最后一块数据在arduino串行数据上被截断

时间:2014-04-04 08:27:27

标签: arduino serial-communication

我有一个arduino接受串行输入并打开LED指示灯。代码如下。

我有一个奇怪的问题,当我发送120x字节的倍数时,例如240,480,最后的120个字节永远不会被完全读取。

如果我发送480字节的数据,我在串行监视器120 120 120 81上看到。谁能指出错误?

#include "FastLED.h"
#define DATA_PIN 6
#define NUM_LEDS 40

byte colors[120];

CRGB leds[NUM_LEDS];

void setup(){
  FastLED.addLeds<NEOPIXEL, DATA_PIN, RGB>(leds, NUM_LEDS);
  Serial.begin(115200);
}

void loop(){
  if (Serial.available()){
    int i =0;
    char incomingByte;

    while(1) {  
      incomingByte = Serial.readBytes((char *)colors,120);
      break;
    }
    Serial.print(incomingByte);
    for(i=0;i<NUM_LEDS ;i++){
      leds[i].green = colors[i];
      leds[i].red = colors[i+1];
      leds[i].blue = colors[i+2];
    }
    if(incomingByte==0x78){
      FastLED.show();
    }
  }
}

1 个答案:

答案 0 :(得分:0)

你的代码以不同的方式存在缺陷。

首先,请删除无用的while(1) {…; break;},它只是增加了开销,并且不会为您的算法添加任何内容。

否则,您的代码运行不正常,因为,我想,在某些时候,串行通信中发生了导致读取超时的延迟。我们来看看源代码。

首先,您使用readBytes()功能。它所做的就是:

size_t Stream::readBytes(char *buffer, size_t length)
{
  size_t count = 0;
  while (count < length) {
    int c = timedRead();
    if (c < 0) break;
    *buffer++ = (char)c;
    count++;
  }
  return count;
}

即。它在阻塞读取函数上迭代length次。但如果函数的返回值小于零,则返回小于length个字节。因此,为了获得低于length而发生的事情,让我们来看看timedRead()

int Stream::timedRead()
{
  int c;
  _startMillis = millis();
  do {
    c = read();
    if (c >= 0) return c;
  } while(millis() - _startMillis < _timeout);
  return -1; // -1 indicates timeout
}

这里发生的是,如果读取成功,则返回读取值,否则它将循环直到超时,并返回-1,它将立即结束readBytes。超时的默认值为1000ms,但您可以在Serial.setTimeout(5000);函数中使用setup()来提高该值。

虽然使用阻止readBytes()功能无法获得任何收益。因此,您最好编写循环,以便读取值,并在读取所有值后触发事件:

#define NB_COLORS 120

void loop() {
    static byte colors[NB_COLORS];
    static int colors_index=0;
    if (colors_index < NB_COLORS) {
        // let's read only one byte
        colors[colors_index] = Serial.read();
        // if a byte has been read, increment the index
        if (colors[colors_index] != -1)
            ++colors_index;
    } else {
        // reset the index to start over
        colors_index = 0;
        // should'nt you iterate 3 by 3, i.e. having i=i+3 instead of i++ ?
        for(i=0;i<NUM_LEDS ;i++){
          leds[i].green = colors[i];
          leds[i].red = colors[i+1];
          leds[i].blue = colors[i+2];
        }
        FastLED.show();
    } 
}

HTH