2014-04-04 41 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所以如果有人碰到這個,他們知道。謝謝 –