2014-02-06 145 views
2

我目前正试图设计一个控制器,将通过蓝牙通信到Android手机(Galaxy Nexus)。我面临一些挑战。另外,我没有太多实际的编程经验。通过蓝牙串行发送数据从arduino

在控制器的核心在于一个Arduino微控制器谁扫描的8个数字销和六个销类似物(10个比特)的状态,并通过串行发送数据,一个HC-05蓝牙芯片。 然后,android手机应该读取通过蓝牙发送的串行信息,并将数据包传输到另一部手机 - 由于我对互联网的工作原理知之甚少,因此需要一段时间才能实现 - 或者分析并解释它以便采取进一步行动被采取

我要求的是洞察到最好的方式去做这件事。现在最好是什么意思? 我们希望它是实时的,所以当我按下一个按钮或底部组合时,android手机会采取足够快的动作,让人不会感觉到延迟。

然后,我希望能够在手机中的串行缓冲器到相应的按钮或模拟引脚读取信息相关联。如果有错误或者以避免它们落入同步

这里是我到目前为止所。我还没有测试过这个代码,部分原因是我仍然在学习如何编程这个项目的android部分,部分原因是我想要一些反馈,看看我是否很愚蠢,或者这实际上是一种有效的方式去做这个:

//Initialization 
/* 

This Program has three functions: 
1) Scan 8 digital pins and compile their state in a single byte (8 bits) 
2) Scans 6 Analogue inputs corresponding to the joysticks and triggers 
3) Send this info as packets through seril --> Bluetooth 

*/ 
#include <SoftwareSerial.h>// import the serial software library 

#define A = 2 
#define B = 3 
#define X = 4 
#define Y = 5 
#define LB = 6 
#define RB = 7 
#define LJ = 8 
#define RJ = 9 
#define RX = 10 
#define TX = 11 
//Pin 12 and 13 are unused for now 
SoftwareSerial Bluetooth(RX,TX); //Setup software serial using the defined constants 
// declare other variables 
byte state = B00000000 

void setup() { 
    //Setup code here, to run once: 
    //Setup all digital pin inputs 
    pinMode(A,INPUT); 
    pinMode(B,INPUT); 
    pinMode(X,INPUT); 
    pinMode(Y,INPUT); 
    pinMode(LB,INPUT); 
    pinMode(RB,INPUT); 
    pinMode(LJ,INPUT); 
    pinMode(RJ,INPUT); 
    //Setup all analogue pin inputs 
    //setup serial bus and send validation message 
    Bluetooth.begin(9600); 
    Bluetooth.println("The controller has successfuly connected to the phone") 
} 

void loop() { 
    //Main code here, to run repeatedly: 
    //Loop to sum digital inputs in a byte, left shift the byte every time by 1 and add that if the pin is high 
    for(byte pin = 2, b = B00000001; pin < 10; pin++, b = b << 1){ if (digitalRead(pin)== HIGH) state += b; } 
    //Send digital state byte to serial 
    Bluetooth.write(state); 
    //Loop to read analgue pin 0 to 5 and send it to serial 
    for(int pin = 0, testByte = 0x8000; pin < 6 ; pin++, testByte = testByte >> 1) { Bluetooth.write(analogRead(pin)+testByte); } 
} 

//Adding some validation would be wise. How would I go about doing that? 
// Could add a binary value of 1000_0000_0000_0000, 0100_0000_0000_0000, 0010_0000_0000_0000 ... so on and then use a simple AND statement at the other end to veryfy what analogue reading the info came from 
// so say the value for analgue is 1023 and came from analgue pin 1 I would have 0100_0011_1111_1111 now using an bitwise && I could check it against 0100_0000_0000_0000 if the result is 0100_0000_0000_0000 then I know this is the analogu reading from pin 1 
//could easily implement a test loop with a shiting bit on the android side 

对我来说这样做是没有意义的吗?最后,如果我没有弄错,所有数据都以字节(8位数据包)发送,那么Bluetooth.write(analogRead(pin)+testByte)实际上会发送两个字节,还是会截断int数据?它将如何被分解,我怎样才能在android端恢复它?

你将如何去实现这个?任何见解或建议的话?

回答

2

这是伟大的,你正在学习这个!几点建议:

您的代码会更容易阅读,理解和维护,如果你的空间就出来了一点,特别是通过加入新行...

void loop() { 
    //Main code here, to run repeatedly: 
    //Loop to sum digital inputs in a byte, 
    //left shift the byte every time by 1 and add that if the pin is high 
    for(byte pin = 2, b = B00000001; pin < 10; pin++, b = b << 1) { 
    if (digitalRead(pin)== HIGH) 
     state += b; 
    } 
    //Send digital state byte to serial 
    Bluetooth.write(state); 
    //Loop to read analgue pin 0 to 5 and send it to serial 
    for(int pin = 0, testByte = 0x8000; pin < 6 ; pin++, testByte = testByte >> 1) { 
    Bluetooth.write(analogRead(pin)+testByte); 
    } 
} 

此外,您还可以使用Shift运营商值除了一个。所以不要保留你添加的换档面具,而只需使用一个简单的变量。比较经典的方式做你在第一个德路表现会是什么这样的:

#define PIN_OFFSET 2 
    for (int i=0; i < 8; i++) { 
    if (digitalRead(i+PIN_OFFSET)== HIGH) 
     state += (1 << i); 
    } 

第二个循环也同样可以做到:

for(int pin = 0; pin < 6; pin++) { 
    short testByte = 0x8000 >> pin; 
    short result = analogRead(pin) + testByte; 
    Bluetooth.write(result >> 8); 
    Bluetooth.write(result & 0xFF); 
    } 

注意,Bluetooth.write()调用发送一个字节,所以这个代码首先发送最重要的字节,然后是最小的。

最后,你可能想在被循环开始到零的状态变量() - 否则,一旦一个位被设置它永远不会被清除。

您可能想要考虑发送给手机的内容。这将是二进制数据,这很难处理 - 你怎么知道开始和结束,并且往往一个价值将被误解为一个控制角色,让你陷入了一段艰难时期。考虑将其更改为格式化的,可读的字符串,并在最后换行。

我希望有帮助。

+0

感谢您的提示和鼓励@bobwki!我会牢记这一点。好吧,所以你建议我发送更多的“格式化的人类可重复字符串”。这个计算是否会足够快以实现实时?这实际上是我唯一的问题,也是为什么我试图真正有效地处理我发送和收到的大量数据的原因。 – Ethienne

+0

不确定效率问题 - 另一种方法是对结果进行编码,使其至少为可打印字符,以避免控制代码问题。另外,请注意,您不能假设蓝牙能够像发送它们一样快地接收字符。它会缓冲字符并尽可能发送它们。根据接口的工作方式(我没有看过),它可能会丢弃它不能发送的字符,或者它会做某种“流量控制” - 这两种方法可能对你想要的没有好处做。 – bobwki

0

这可能对您有好处,可以为您的android手机选择现成的蓝牙终端应用程序。在Google play上,很少的应用程序是: 1)https://play.google.com/store/apps/details?id=arduino.bluetooth.terminal&hl=en 2)https://play.google.com/store/apps/details?id=com.sena.bterm&hl=en (并且在Google Play上还有更多功能可用)。这将帮助您专注于控制器端开发。

+0

感谢您的建议。我已经下载了一个终端来测试我的blutooth模块是否工作。也就是说,终端应用程序毫无意义,因为他们所做的只是显示通过终端发送的数据。如果我想处理这些数据,我需要修改他们的代码或从头开始编写应用程序。在这两种情况下,我需要学习Android的部分内容。我完全没事!这个项目的全部目的是给我一个很好的借口来做出必要的努力来学习一些东西。 =) – Ethienne

1

这个Arduino结束的速度足够快,可以做你想做的事情,而且你不需要担心在你谈论的时候,从微处理器发送到手机的最小化字节数如此少量的数据。我不清楚你发送给手机的是什么;你想为每个按钮所以当按钮被按下它会发出像不同的值:

按钮被按下,按钮号码(两个字节)

如果它是一个模拟值:

模拟值读,模拟量MSB,模拟量LSB(假设模拟值大于八位

我不知道你正在使用的Arduino的代码,但我怀疑的是,这条线:

蓝牙。写(模拟读(引脚)+ testByte)

会发送一个字节,这是模拟值,无论testByte是什么。

你能发布一个链接到这个API的文档吗?

所有这一切都将延迟到手机端。请不要在半价试图在Arduino端保存一两个字节! (我正在做一个项目,使用Cortex M3通过蓝牙模块向Android手机发送数据,并且我们发送了几K个数据。根据这个经验,我知道两个字节和二十个字节之间的差异并不重要的延迟。)

+0

好的,谢谢,很高兴知道我不必担心速度那么!然后,如果我之前发送了“按下按钮”,则不需要测试字节。 API可以在arduino网站上找到。 http://www.arduino.cc/en/Reference/HomePage#.UxLULfldVjQ – Ethienne

相关问题