1

我对 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;
    }
  }
}

这是输入以下字符串时串行监视器的一些示例输出:<25,25,25>

输出:

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

谢谢

4

1 回答 1

2

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

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

请注意,当您第一次进入此 while 循环时,您只是刚刚从串行线路接收到第一个字节。第二个字节甚至可能还没有在线上。如果您向 Arduino 发送了“25,25,25”并且它只有第一个字符,red = Serial.parseInt()则返回 2 并将其分配给红色。green = Serial.parseInt()将得到 5,blue = Serial.parseInt()将得到 25。然后你的串行缓冲区中被“,25”卡住了,这可能会在下一次通过 loop() 时导致更多问题。

parseInt() 上的文档说它会等待一秒钟以获得一个有效的整数字节,但它没有说明一旦它有一个它会做什么,它是否会等待 1/Hz 秒以查看是否有更多来或不来。如果是这样,那么您必须查看潜在的硬件原因......

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

我以前在 Arduino 上遇到过这样的问题。所需要的只是一些杂散射频、面包板上的噪声或任何数量的其他电气问题,当您读取串行线时,0 变为 1,反之亦然。鉴于一系列中的第一个字节发生了丢失,我强烈怀疑您看到了这种症状。如果您的串行引脚上的电压积累缓慢,那么当您阅读它时,您首先会看到一个 1。我当前的项目通过将最高位交替设置为 0 和 1 来识别高字节和低字节. 有时,我会得到三个以 0 为前缀的字节或三个以 1 为前缀的字节,然后我就丢弃这些样本。

您的 UNO 是否坐在电绝缘表面上?如果您使用的是面包板,您对它的信任程度如何?您确定连接线的电阻接近于零并且它们之间的电阻接近于无限吗?您是否有一条糟糕的 USB 电缆来处理您的串行通道?如果是这样,附近的强射频信号可能会导致您的问题。

于 2014-07-23T01:25:02.047 回答