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.
This commit is contained in:
parent
672f401a4d
commit
a766fb4910
|
@ -52,7 +52,11 @@ uint8_t * ledsRaw = (uint8_t *)leds;
|
||||||
static const uint8_t magic[] = {
|
static const uint8_t magic[] = {
|
||||||
'A','d','a'};
|
'A','d','a'};
|
||||||
#define MAGICSIZE sizeof(magic)
|
#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_HEADER 0
|
||||||
#define MODE_DATA 2
|
#define MODE_DATA 2
|
||||||
|
@ -76,23 +80,12 @@ void setup(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void adalight(){
|
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
|
uint8_t
|
||||||
buffer[256],
|
|
||||||
indexIn = 0,
|
|
||||||
indexOut = 0,
|
|
||||||
mode = MODE_HEADER,
|
mode = MODE_HEADER,
|
||||||
hi, lo, chk, i;
|
headPos,
|
||||||
|
hi, lo, chk;
|
||||||
int16_t
|
int16_t
|
||||||
c;
|
c;
|
||||||
uint16_t
|
|
||||||
bytesBuffered = 0;
|
|
||||||
uint32_t
|
uint32_t
|
||||||
bytesRemaining,
|
bytesRemaining,
|
||||||
outPos;
|
outPos;
|
||||||
|
@ -113,11 +106,69 @@ void adalight(){
|
||||||
// Implementation is a simple finite-state machine.
|
// Implementation is a simple finite-state machine.
|
||||||
// Regardless of mode, check for serial input each time:
|
// Regardless of mode, check for serial input each time:
|
||||||
t = millis();
|
t = millis();
|
||||||
if((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) {
|
|
||||||
buffer[indexIn++] = c;
|
if((c = Serial.read()) >= 0){
|
||||||
bytesBuffered++;
|
|
||||||
lastByteTime = lastAckTime = t; // Reset timeout counters
|
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 {
|
else {
|
||||||
// No data received. If this persists, send an ACK packet
|
// No data received. If this persists, send an ACK packet
|
||||||
// to host once every second to alert it to our presence.
|
// to host once every second to alert it to our presence.
|
||||||
|
@ -131,66 +182,7 @@ void adalight(){
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
lastByteTime = t; // Reset counter
|
lastByteTime = t; // Reset counter
|
||||||
}
|
}
|
||||||
}
|
} // end else
|
||||||
|
|
||||||
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<MAGICSIZE) && (buffer[indexOut++] == magic[i++]););
|
|
||||||
if(i == MAGICSIZE) {
|
|
||||||
// Magic word matches. Now how about the checksum?
|
|
||||||
hi = buffer[indexOut++];
|
|
||||||
lo = buffer[indexOut++];
|
|
||||||
chk = buffer[indexOut++];
|
|
||||||
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);
|
|
||||||
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 for(;;)
|
} // end for(;;)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue