2014-04-04 38 views
1

我有一个arduino正在接收串行输入,并将打开LED。代码如下。在Arduino串行数据上截断的最后一块数据

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

我在串行监视器120 120 120 81上看到我发送了480字节的数据。有谁能指出这个错误吗?

#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(); 
    } 
    } 
} 

回答

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,但您可以在setup()函数中使用Serial.setTimeout(5000);来提高此值。

尽管使用阻塞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

+0

我的想法,但它是如何进行工作做好第一个块只会被最后一个块损坏。当你说有时间问题时,你也是对的。当我删除了Fastled.show()时,它读得非常好。我认为问题来自show函数,但我不明白它是如何正确读取3个块,但损坏了第4个。 (如果我发送4) –

+0

我让你的代码工作,并且有一小部分需要修正,如果(colors [colors_index]!= -1)不会工作,因为它是一个字节数组。它必须被赋予int所以如果有人碰到这个,他们知道。谢谢 –