From a766fb4910580e94de50d53df30c5f863ab41dc7 Mon Sep 17 00:00:00 2001 From: David Madison Date: Mon, 27 Mar 2017 19:20:55 -0400 Subject: [PATCH 1/5] 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(;;) } From eba7bdb73ec08257158ffadaeb90b314abac42ba Mon Sep 17 00:00:00 2001 From: David Madison Date: Mon, 27 Mar 2017 19:26:36 -0400 Subject: [PATCH 2/5] Changed MODE_DATA definition Just because. --- Arduino/LEDstream_FastLED/LEDstream_FastLED.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino index a675e32..10e83fc 100644 --- a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino +++ b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino @@ -59,7 +59,7 @@ static const uint8_t magic[] = { #define CHECKSUM (MAGICSIZE + 2) #define MODE_HEADER 0 -#define MODE_DATA 2 +#define MODE_DATA 1 void setup(){ #ifdef GROUND_PIN From 84fef87d35ddff7c37a88911d75ccf7e31a0165a Mon Sep 17 00:00:00 2001 From: David Madison Date: Mon, 27 Mar 2017 19:37:49 -0400 Subject: [PATCH 3/5] Check if data can latch immediately Prior to this change, code would wait for an additional byte before latching. --- Arduino/LEDstream_FastLED/LEDstream_FastLED.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino index 10e83fc..9ff07a6 100644 --- a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino +++ b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino @@ -161,7 +161,7 @@ void adalight(){ } bytesRemaining--; } - else { + if(bytesRemaining == 0) { // End of data -- issue latch: mode = MODE_HEADER; // Begin next header search FastLED.show(); From b13d9f67c72c1fad5678dc6f424650276994457a Mon Sep 17 00:00:00 2001 From: David Madison Date: Mon, 27 Mar 2017 22:59:53 -0400 Subject: [PATCH 4/5] Changed 'outPos' to 16 bit --- Arduino/LEDstream_FastLED/LEDstream_FastLED.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino index 9ff07a6..033509e 100644 --- a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino +++ b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino @@ -86,9 +86,10 @@ void adalight(){ hi, lo, chk; int16_t c; - uint32_t - bytesRemaining, + uint16_t outPos; + uint32_t + bytesRemaining; unsigned long lastByteTime, lastAckTime, From 8688131d6cb0d4d23bcc54d71276fafa6e533bca Mon Sep 17 00:00:00 2001 From: David Madison Date: Sat, 8 Apr 2017 09:57:42 -0400 Subject: [PATCH 5/5] Updated date --- Arduino/LEDstream_FastLED/LEDstream_FastLED.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino index 288e30e..8a3b850 100644 --- a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino +++ b/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino @@ -4,7 +4,7 @@ * library (http://fastled.io) for driving led strips. * * http://github.com/dmadison/Adalight-FastLED - * Last Updated: 2017-03-27 + * Last Updated: 2017-04-08 */ // --- General Settings @@ -152,7 +152,6 @@ void adalight(){ #ifdef CALIBRATE if(outPos < 3) ledsRaw[outPos++] = c; - else{ ledsRaw[outPos] = ledsRaw[outPos%3]; // Sets RGB data to first LED color outPos++;