44 * library (http://fastled.io) for driving led strips.
55 *
66 * http://github.com/dmadison/Adalight-FastLED
7- * Last Updated: 2017-03-27
7+ * Last Updated: 2017-04-08
88 */
99
1010// --- General Settings
@@ -52,10 +52,14 @@ uint8_t * ledsRaw = (uint8_t *)leds;
5252static const uint8_t magic[] = {
5353 ' A' ,' d' ,' a' };
5454#define MAGICSIZE sizeof (magic)
55- #define HEADERSIZE (MAGICSIZE + 3 )
55+
56+ // Check values are header byte # - 1, as they are indexed from 0
57+ #define HICHECK (MAGICSIZE)
58+ #define LOCHECK (MAGICSIZE + 1 )
59+ #define CHECKSUM (MAGICSIZE + 2 )
5660
5761#define MODE_HEADER 0
58- #define MODE_DATA 2
62+ #define MODE_DATA 1
5963
6064void setup (){
6165 #ifdef GROUND_PIN
@@ -76,26 +80,16 @@ void setup(){
7680}
7781
7882void adalight (){
79- // Dirty trick: the circular buffer for serial data is 256 bytes,
80- // and the "in" and "out" indices are unsigned 8-bit types -- this
81- // much simplifies the cases where in/out need to "wrap around" the
82- // beginning/end of the buffer. Otherwise there'd be a ton of bit-
83- // masking and/or conditional code every time one of these indices
84- // needs to change, slowing things down tremendously.
85-
8683 uint8_t
87- buffer[256 ],
88- indexIn = 0 ,
89- indexOut = 0 ,
90- mode = MODE_HEADER,
91- hi, lo, chk, i;
84+ mode = MODE_HEADER,
85+ headPos,
86+ hi, lo, chk;
9287 int16_t
9388 c;
9489 uint16_t
95- bytesBuffered = 0 ;
96- uint32_t
97- bytesRemaining,
9890 outPos;
91+ uint32_t
92+ bytesRemaining;
9993 unsigned long
10094 lastByteTime,
10195 lastAckTime,
@@ -113,84 +107,83 @@ void adalight(){
113107 // Implementation is a simple finite-state machine.
114108 // Regardless of mode, check for serial input each time:
115109 t = millis ();
116- if ((bytesBuffered < 256 ) && ((c = Serial.read ()) >= 0 )) {
117- buffer[indexIn++] = c;
118- bytesBuffered++;
110+
111+ if ((c = Serial.read ()) >= 0 ){
119112 lastByteTime = lastAckTime = t; // Reset timeout counters
120- }
121- else {
122- // No data received. If this persists, send an ACK packet
123- // to host once every second to alert it to our presence.
124- if ((t - lastAckTime) > 1000 ) {
125- Serial.print (" Ada\n " ); // Send ACK string to host
126- lastAckTime = t; // Reset counter
127- }
128- // If no data received for an extended time, turn off all LEDs.
129- if ((t - lastByteTime) > SerialTimeout) {
130- memset (leds, 0 , Num_Leds * sizeof (struct CRGB )); // filling Led array by zeroes
131- FastLED.show ();
132- lastByteTime = t; // Reset counter
133- }
134- }
135-
136- switch (mode) {
137-
138- case MODE_HEADER:
139-
140- // In header-seeking mode. Is there enough data to check?
141- if (bytesBuffered >= HEADERSIZE) {
142- // Indeed. Check for a 'magic word' match.
143- for (i=0 ; (i<MAGICSIZE) && (buffer[indexOut++] == magic[i++]););
144- if (i == MAGICSIZE) {
145- // Magic word matches. Now how about the checksum?
146- hi = buffer[indexOut++];
147- lo = buffer[indexOut++];
148- chk = buffer[indexOut++];
149- if (chk == (hi ^ lo ^ 0x55 )) {
150- // Checksum looks valid. Get 16-bit LED count, add 1
151- // (# LEDs is always > 0) and multiply by 3 for R,G,B.
152- bytesRemaining = 3L * (256L * (long )hi + (long )lo + 1L );
153- bytesBuffered -= 3 ;
154- outPos = 0 ;
155- memset (leds, 0 , Num_Leds * sizeof (struct CRGB ));
156- mode = MODE_DATA; // Proceed to latch wait mode
157- }
158- else {
159- // Checksum didn't match; search resumes after magic word.
160- indexOut -= 3 ; // Rewind
113+
114+ switch (mode) {
115+
116+ case MODE_HEADER:
117+
118+ if (headPos < MAGICSIZE){
119+ if (c == magic[headPos]) headPos++;
120+ else headPos = 0 ;
121+ }
122+ else {
123+ switch (headPos){
124+ case HICHECK:
125+ hi = c;
126+ headPos++;
127+ break ;
128+ case LOCHECK:
129+ lo = c;
130+ headPos++;
131+ break ;
132+ case CHECKSUM:
133+ chk = c;
134+ if (chk == (hi ^ lo ^ 0x55 )) {
135+ // Checksum looks valid. Get 16-bit LED count, add 1
136+ // (# LEDs is always > 0) and multiply by 3 for R,G,B.
137+ bytesRemaining = 3L * (256L * (long )hi + (long )lo + 1L );
138+ outPos = 0 ;
139+ memset (leds, 0 , Num_Leds * sizeof (struct CRGB ));
140+ mode = MODE_DATA; // Proceed to latch wait mode
141+ }
142+ headPos = 0 ; // Reset header position regardless of checksum result
143+ break ;
161144 }
162- } // else no header match. Resume at first mismatched byte.
163- bytesBuffered -= i;
164- }
165- break ;
166-
167- case MODE_DATA:
145+ }
146+ break ;
147+
148+ case MODE_DATA:
168149
169- if (bytesRemaining > 0 ) {
170- if (bytesBuffered > 0 ) {
150+ if (bytesRemaining > 0 ) {
171151 if (outPos < sizeof (leds)){
172152 #ifdef CALIBRATE
173153 if (outPos < 3 )
174- ledsRaw[outPos++] = buffer[indexOut] ;
154+ ledsRaw[outPos++] = c ;
175155 else {
176156 ledsRaw[outPos] = ledsRaw[outPos%3 ]; // Sets RGB data to first LED color
177157 outPos++;
178158 }
179159 #else
180- ledsRaw[outPos++] = buffer[indexOut] ; // Issue next byte
160+ ledsRaw[outPos++] = c ; // Issue next byte
181161 #endif
182162 }
183- indexOut++;
184- bytesBuffered--;
185163 bytesRemaining--;
186164 }
165+ if (bytesRemaining == 0 ) {
166+ // End of data -- issue latch:
167+ mode = MODE_HEADER; // Begin next header search
168+ FastLED.show ();
169+ }
170+ break ;
171+ } // end switch
172+ } // end serial if
173+ else {
174+ // No data received. If this persists, send an ACK packet
175+ // to host once every second to alert it to our presence.
176+ if ((t - lastAckTime) > 1000 ) {
177+ Serial.print (" Ada\n " ); // Send ACK string to host
178+ lastAckTime = t; // Reset counter
187179 }
188- else {
189- // End of data -- issue latch:
190- mode = MODE_HEADER ; // Begin next header search
180+ // If no data received for an extended time, turn off all LEDs.
181+ if ((t - lastByteTime) > SerialTimeout) {
182+ memset (leds, 0 , Num_Leds * sizeof ( struct CRGB )) ; // filling Led array by zeroes
191183 FastLED.show ();
184+ lastByteTime = t; // Reset counter
192185 }
193- } // end switch
186+ } // end else
194187 } // end for(;;)
195188}
196189
0 commit comments