arduino连续不稳定的行为缺少字符,偶尔整个传输

时间:2014-07-20 18:39:12

标签: serial-port arduino arduino-uno

我对UNO上的硬件序列有问题,在很多情况下它似乎丢弃一个字符(通常是收到的第一个字符),并且在某些情况下它错过了整个传输。这只发生在Arduino从串口监视器中输入的计算机接收数据时。当我发送字符串时,我可以看到RX指示灯闪烁,但arduino完全忽略了它。

我发送的数据是三个逗号分隔的8位无符号整数

#include <Adafruit_NeoPixel.h>
//#include <OneSheeld.h>

#define PIN 6
#define LEDS 5

Adafruit_NeoPixel strip = Adafruit_NeoPixel(LEDS, PIN, NEO_GRB + NEO_KHZ800);
int leds = LEDS-1;
byte red;
byte green;
byte blue;
int i;
// pins for the LEDs:
//const int red = 3;
//const int green = 5;
//const int blue = 6;

void setup() {
  // initialize serial:
  Serial.begin(9600);
  strip.begin();
  strip.setPixelColor(0,12,12,12);
     strip.show(); // Initialize all pixels to 'off'
     Serial.print("number of LEDS in strip:");
     Serial.println(LEDS);
     i=0;
  // make the pins outputs:
//  pinMode(redPin, OUTPUT); 
//  pinMode(greenPin, OUTPUT); 
//  pinMode(bluePin, OUTPUT); 

}

void loop() {
  red = 0;
  green=0;
  blue= 0;

 // i=0;
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
      red = Serial.parseInt(); 
    // do it again:
      green = Serial.parseInt(); 
    // do it again:
       blue = Serial.parseInt();
       delay(1);

    // look for the newline. That's the end of your
    // sentence:
    if (Serial.read() == '\n') {
      // constrain the values to 0 - 255 and invert
      // if you're using a common-cathode LED, just use "constrain(color, 0, 255);"
//      red = constrain(red, 0, 255);
//      green = constrain(green, 0, 255);
//      blue = constrain(blue, 0, 255);     
         Serial.print("LED being served = ");
         Serial.println(i);


      // fade the red, green, and blue legs of the LED: 

//      analogWrite(redPin, red);
//      analogWrite(greenPin, green);
//      analogWrite(bluePin, blue);
      strip.setPixelColor(i,red,green,blue);
      strip.show();

      // print the three numbers in one string as hexadecimal:
      Serial.print("R=");
      Serial.println(red);
      Serial.print("G=");
      Serial.println(green);
      Serial.print("B=");
      Serial.println(blue);

     if(i==leds)
     i=0;
     else
     i=i+1;
    }
  }
}

以下是输入以下字符串时串行监视器的一些示例输出 string:&lt; 25,25,25&gt;

输出:

number of LEDS in strip:5
LED being served = 0
R=25
G=25
B=25
LED being served = 1   <<< this transmission got lost the first time it was sent
R=25
G=25
B=25
LED being served = 2
R=25
G=25
B=25
LED being served = 3
R=5
G=25
B=25
LED being served = 4 <<< This transmission got lost the first 4 times it was sent
R=5
G=25
B=25
LED being served = 0
R=25
G=25
B=25
LED being served = 1
R=25
G=25
B=25
LED being served = 2
R=25
G=25
B=25
LED being served = 3
R=25
G=25
B=25
LED being served = 4
R=5
G=25
B=25
LED being served = 0
R=25
G=25
B=25
LED being served = 1
R=5
G=25
B=25
LED being served = 2
R=25
G=25
B=25
LED being served = 3
R=25
G=25
B=25
LED being served = 4
R=25
G=25
B=25

由于

1 个答案:

答案 0 :(得分:1)

您的问题很可能是时间问题:

while (Serial.available() > 0) {
  red = Serial.parseInt(); 
  green = Serial.parseInt(); 
  blue = Serial.parseInt();

请注意,第一次进入while循环时,您只是从串行线接收到了第一个字节。第二个字节甚至可能还没有在线上。如果您已将“25,25,25”发送给Arduino并且它只有第一个字符,red = Serial.parseInt()将返回2并将其指定为红色。 green = Serial.parseInt()将获得5,而blue = Serial.parseInt()将获得25.然后你在串行缓冲区中遇到“25”,这可能会在下一次循环()循环中导致更多问题。< / p>

parseInt()上的文档说它会等待一秒钟的有效整数字节,但它没有说明一旦它有一个它会做什么,它是否会等待1 / Hz秒到看看是否还有更多。如果确实如此,那么你必须看看潜在的硬件原因......

您必须记住,串行不是可靠的协议。在将每个字节传送到应用程序之前检查每个字节的奇偶校验,如果奇偶校验失败,则可能根本不会传送它。

之前我和Arduino有过这样的问题。所需要的只是一些杂散RF,面包板上的噪音或任何其他电气问题,当你去读取串行线时,0变为1,反之亦然。鉴于损失发生在你系列的第一个字节上,我强烈怀疑你看到了这种情况的症状。如果你的串行引脚上的电压累积很慢,当你去读它时,你要看到的第一件事是1.我当前的项目通过将顶部位设置为0和1来识别高字节和低字节。有时候,我会得到一个前缀为0的三倍字节或一个前缀为1的三倍,我只是把这些样本丢掉了。

您的UNO是否坐在电气绝缘的表面上?如果你正在使用面包板,你相信它多少钱?你确定你的连接线和它们之间几乎无限大的阻力接近零电阻吗?你有一条糟糕的USB线处理你的串行频道吗?如果是这样,附近的强RF信号可能会导致您的问题。