我目前有一台HC-06蓝牙设备连接到我的Arduino Mega 2560,以便接收从Android设备发送的字符串。使用串行0上的HC-06,我收到的数据没有错误,使用以下代码:
String inString = "";
int index = 0;
boolean stringComplete = false;
void setup(){
Serial.begin(9600);
pinMode(pwmPin, OUTPUT);
}
void loop(){
if(stringComplete){
ParseSerialData(); //Parse the received data
inString = ""; //Reset inString to empty
stringComplete = false; //Reset the system for further input of data
}
}
void serialEvent(){
while(Serial.available() && stringComplete == false){
char inChar = Serial.read();
inData[index] = inChar; //Store it in char array
index++;
if (inChar == '\n'){ //Check for termination character
index = 0; //Reset the index
stringComplete = true; //Set completion of read to true
}else{
inString += inChar; //Also store as string
}
}
}
当我尝试将“Serial”替换为“Serial1”并将“serialEvent()”替换为“serialEvent1()”并将蓝牙设备移至TX1和RX1时,此程序将不再有效。
我读过有些人在使用AVR-GCC 4.4.x时有类似的问题并通过降级到4.3.x来解决问题,但我有4.3.2(在Windows 8.1上,Arduino IDE 1.0出现了同样的问题.3,1.0.5-r2和1.5.6-r2)。
我将以下打印语句(使用Serial 0打印到我的PC上的显示器上)添加到BT设备仍在Serial 1上的代码:
String inString = "";
int index = 0;
boolean stringComplete = false;
void setup(){
Serial1.begin(9600);
Serial.begin(9600);
pinMode(pwmPin, OUTPUT);
Serial.println("Setting up...");
}
void loop(){
if(stringComplete){
ParseSerialData();
inString = "";
stringComplete = false;
}
}
void serialEvent1(){
Serial.println("In serialEvent1...");
while(Serial1.available() && stringComplete == false){
Serial.println("Char in...");
char inChar = Serial1.read();
Serial.println("WTF");
Serial.println(inChar);
Serial.println("WTF2");
inData[index] = inChar;
index++;
if (inChar == '\n'){
Serial.println("Termination char read...");
index = 0;
stringComplete = true;
}else{
inString += inChar;
}
}
}
这样做,我在监视器上得到:
Setting up...
In serialEvent1...
Char in...
WTF
WTF2
inChar通常打印为空,但在一次测试中打印为“@”字符。发送的字符串是Android设备中的“s,1 \ n”。
基于打印输出,串行事件由串行数据的可用性触发,但Serial1.available()仅在第一次迭代时保持为真,未读入's'(也不执行任何其他字符)当使用Serial时,永远不会读入终止字符(换行符char),以便我可以开始解析。
我还尝试了各种波特率,但行为没有区别。基于读取Arduino文档,串行端口1应该像串行端口0一样工作,我没有错过在代码的任何部分替换Serial for Serial1。
有没有人知道什么可能导致在Serial1上进行通信的错误,就像在Serial0上完美运行一样?
如果我没有包含任何相关信息,请告诉我。
提前致谢!
编辑:
我还找到了一个相关的SO question,它使用类似于我的代码(与Serial0完美配合,基于Arduino documentation)使用预期的终止字符解决(差别在于他的代码在主循环中实现了串行读取,而我的代码在serialEvent中实现。出于某种原因,我们似乎都遇到了Serial1数据在下一次迭代开始时没有显示可用的问题。由于某种原因,我没有再次调用serialEvent1。我仍然不明白为什么第一个/唯一一个字符读不是。起初我认为在再次进入串行事件之前,流已经被刷新了,但是仍然没有考虑读取不正确的第一个字符。
另外,我添加了以下Serial1 print语句在Arduino设置中多次运行,Android设备每次都会收到它而没有错误,因此发送数据工作正常:
Serial1.print("b,1\n");
甚至
Serial1.print("A long test message. A long test message.\n");
编辑2:
我现在非常接近回答我自己的问题,进一步测试/调试。我实际上认为答案可能最终与硬件相关而不是软件。我想知道问题是从HC-06发送到端口1的数据,还是端口1的读取功能。我基本上有串口0读取数据,然后串行发送到端口1,会读取该数据,并通过蓝牙将反馈发送到Android设备。串口1读取来自端口0的精细数据,因此问题是从HC-06专门读取数据。它可能只是一个电压等级问题,因此答案可能不属于stackoverflow。我将保留未回答的问题,直到我明确找到根本原因(允许我可能需要一些HC-06或串行端口1的定义语句才能正确读取数据,尽管我猜测的是电压级别转换可能会解决问题。我不知道为什么Serial0和Serial1之间会有这样的差异。)
答案 0 :(得分:6)
我解决了启用Rx1引脚的上拉电阻的问题:
Serial1.begin(9600);
pinMode(19, INPUT);
digitalWrite(19, HIGH);
因此,对于逻辑高电平,arduino的5V将3V“覆盖”,而逻辑低电平则由蓝牙的TX下拉零。
答案 1 :(得分:0)
检查示波器上的串行数据线后,我能够找到解决问题的方法。通过 EDIT 2 (蓝牙TX - > RX0,TX0 - > RX1,TX1 - >蓝牙RX)中描述的设置,我检查了 发送的信号 由蓝牙设备和Arduino的串口0。
蓝牙设备的信号低至400 mV,高电压为3.68V,而Arduino的端口0在0V时为低电平,在5V时为高电平。我知道蓝牙设备是3.3V级别的设备,但是Arduino应该读取高于3V的任何东西,所以这应该不是问题(显然它不在串行0上)。
无论如何,我用我购买的备份替换了HC-06蓝牙设备,使用我在帖子中发布的Serial1的代码一切正常。这款蓝牙设备的传输速率约为160 mV,高电压为3.3V。
似乎我的问题根植于预期的硬件(电压电平),并且由于某种原因,Serial1对数字电平的变化比Serial0更敏感。我想我的问题是为什么它更适合StackExchange或类似的地方。如果您有任何进一步的信息或更深入的答案,请告诉我。
答案 2 :(得分:0)
只需对Alison的此解决方案表示感谢。通过使用INPUT_PULLUP功能将硬件Serial3引脚拉为高电平,我做了一些不同的操作:
Serial3.begin(19200);
pinMode(15, INPUT_PULLUP); //Serial3 Rx pin
这很有效,以前我的两个arduino mega 256之间的串行通信主要是偶然的正确传输损坏了。现在主要是正确的传输。以前,接收有效串行值所花费的时间最多为2.5秒(由于必须反复重试以获取有效Tx)。现在,获得有效的Tx
所花费的时间为 20ms 。 (我使用大约35厘米长的双绞单芯线)。
很棒-再次感谢。