Arduino Mega通过Serial 0但不是Serial 1-3接收正确的数据

时间:2014-04-16 23:57:47

标签: android bluetooth serial-port arduino

我目前有一台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之间会有这样的差异。)

3 个答案:

答案 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厘米长的双绞单芯线)。

很棒-再次感谢。