From a766fb4910580e94de50d53df30c5f863ab41dc7 Mon Sep 17 00:00:00 2001 From: David Madison Date: Mon, 27 Mar 2017 19:20:55 -0400 Subject: [PATCH] Rewrote Adalight code to no longer use 256 byte buffer The buffer was only being used to store the header information before processing, otherwise data was retrieved immediately. Buffer and support variables were causing more problems than anything else. --- .../LEDstream_FastLED/LEDstream_FastLED.ino | 150 +++++++++--------- 1 file changed, 71 insertions(+), 79 deletions(-) diff --git a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino index 0fecce1..a675e32 100644 --- a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino +++ b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino @@ -52,7 +52,11 @@ uint8_t * ledsRaw = (uint8_t *)leds; static const uint8_t magic[] = { 'A','d','a'}; #define MAGICSIZE sizeof(magic) -#define HEADERSIZE (MAGICSIZE + 3) + +// Check values are header byte # - 1, as they are indexed from 0 +#define HICHECK (MAGICSIZE) +#define LOCHECK (MAGICSIZE + 1) +#define CHECKSUM (MAGICSIZE + 2) #define MODE_HEADER 0 #define MODE_DATA 2 @@ -76,23 +80,12 @@ void setup(){ } void adalight(){ - // Dirty trick: the circular buffer for serial data is 256 bytes, - // and the "in" and "out" indices are unsigned 8-bit types -- this - // much simplifies the cases where in/out need to "wrap around" the - // beginning/end of the buffer. Otherwise there'd be a ton of bit- - // masking and/or conditional code every time one of these indices - // needs to change, slowing things down tremendously. - uint8_t - buffer[256], - indexIn = 0, - indexOut = 0, - mode = MODE_HEADER, - hi, lo, chk, i; + mode = MODE_HEADER, + headPos, + hi, lo, chk; int16_t c; - uint16_t - bytesBuffered = 0; uint32_t bytesRemaining, outPos; @@ -113,11 +106,69 @@ void adalight(){ // Implementation is a simple finite-state machine. // Regardless of mode, check for serial input each time: t = millis(); - if((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) { - buffer[indexIn++] = c; - bytesBuffered++; + + if((c = Serial.read()) >= 0){ lastByteTime = lastAckTime = t; // Reset timeout counters - } + + switch(mode) { + + case MODE_HEADER: + + if(headPos < MAGICSIZE){ + if(c == magic[headPos]) headPos++; + else headPos = 0; + } + else{ + switch(headPos){ + case HICHECK: + hi = c; + headPos++; + break; + case LOCHECK: + lo = c; + headPos++; + break; + case CHECKSUM: + chk = c; + if(chk == (hi ^ lo ^ 0x55)) { + // Checksum looks valid. Get 16-bit LED count, add 1 + // (# LEDs is always > 0) and multiply by 3 for R,G,B. + bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L); + outPos = 0; + memset(leds, 0, Num_Leds * sizeof(struct CRGB)); + mode = MODE_DATA; // Proceed to latch wait mode + } + headPos = 0; // Reset header position regardless of checksum result + break; + } + } + break; + + case MODE_DATA: + + if(bytesRemaining > 0) { + if (outPos < sizeof(leds)){ + #ifdef CALIBRATE + if(outPos < 3) + ledsRaw[outPos++] = c; + else{ + ledsRaw[outPos] = ledsRaw[outPos%3]; // Sets RGB data to first LED color + outPos++; + } + #else + ledsRaw[outPos++] = c; // Issue next byte + #endif + } + bytesRemaining--; + } + else { + // End of data -- issue latch: + mode = MODE_HEADER; // Begin next header search + FastLED.show(); + } + break; + } // end switch + } // end serial if else { // No data received. If this persists, send an ACK packet // to host once every second to alert it to our presence. @@ -131,66 +182,7 @@ void adalight(){ FastLED.show(); lastByteTime = t; // Reset counter } - } - - switch(mode) { - - case MODE_HEADER: - - // In header-seeking mode. Is there enough data to check? - if(bytesBuffered >= HEADERSIZE) { - // Indeed. Check for a 'magic word' match. - for(i=0; (i 0) and multiply by 3 for R,G,B. - bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L); - bytesBuffered -= 3; - outPos = 0; - memset(leds, 0, Num_Leds * sizeof(struct CRGB)); - mode = MODE_DATA; // Proceed to latch wait mode - } - else { - // Checksum didn't match; search resumes after magic word. - indexOut -= 3; // Rewind - } - } // else no header match. Resume at first mismatched byte. - bytesBuffered -= i; - } - break; - - case MODE_DATA: - - if(bytesRemaining > 0) { - if(bytesBuffered > 0) { - if (outPos < sizeof(leds)){ - #ifdef CALIBRATE - if(outPos < 3) - ledsRaw[outPos++] = buffer[indexOut++]; - else{ - ledsRaw[outPos] = ledsRaw[outPos%3]; // Sets RGB data to first LED color - outPos++; - indexOut++; - } - #else - ledsRaw[outPos++] = buffer[indexOut++]; // Issue next byte - #endif - } - bytesBuffered--; - bytesRemaining--; - } - } - else { - // End of data -- issue latch: - mode = MODE_HEADER; // Begin next header search - FastLED.show(); - } - } // end switch + } // end else } // end for(;;) }