diff --git a/README.md b/README.md index f3c6cc6..8ef580d 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,9 @@ Compile the sketch using Arduino IDE. You need: For RGB strip like WS8212b delete it or comment it with '//', leave it for RGBW SK6812: *#define THIS_IS_RGBW* +For RGBW cold white LED strip version if above declaration is defined, delete it or comment it with '//' for RGBW neutral: +*#define COLD_WHITE* + SPI: for APA102/SK9822/HD107 delete it or comment it with '//', leave it for WS2801: *#define is_WS2801* diff --git a/version for Neopixels (SK6812 WS2812)/HyperSerialEsp8266_Neopixel/HyperSerialEsp8266_Neopixel.ino b/version for Neopixels (SK6812 WS2812)/HyperSerialEsp8266_Neopixel/HyperSerialEsp8266_Neopixel.ino new file mode 100644 index 0000000..af38e3c --- /dev/null +++ b/version for Neopixels (SK6812 WS2812)/HyperSerialEsp8266_Neopixel/HyperSerialEsp8266_Neopixel.ino @@ -0,0 +1,411 @@ +#include +//////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////// CONFIG SECTION STARTS ///////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#define THIS_IS_RGBW // RGBW SK6812, otherwise comment it +#define COLD_WHITE // for RGBW (THIS_IS_RGBW enabled) select COLD version, comment it if NEUTRAL +bool skipFirstLed = false; // if set the first led in the strip will be set to black (for level shifters using sacrifice LED) +int serialSpeed = 2000000; // serial port speed + +//////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////// CONFIG SECTION ENDS ///////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef THIS_IS_RGBW + float whiteLimit = 1.0f; + #ifdef COLD_WHITE + uint8_t rCorrection = 0xA0; // adjust red -> white in 0-0xFF range + uint8_t gCorrection = 0xA0; // adjust green -> white in 0-0xFF range + uint8_t bCorrection = 0xA0; // adjust blue -> white in 0-0xFF range + #else + uint8_t rCorrection = 0xB0; // adjust red -> white in 0-0xFF range + uint8_t gCorrection = 0xB0; // adjust green -> white in 0-0xFF range + uint8_t bCorrection = 0x70; // adjust blue -> white in 0-0xFF range + #endif +#endif + +int pixelCount = 0; // This is dynamic, don't change it + +#ifdef THIS_IS_RGBW + #define LED_TYPE NeoGrbwFeature +#else + #define LED_TYPE NeoGrbFeature +#endif + +NeoPixelBus *strip = NULL; + +void Init(int count) +{ + if (strip != NULL) + delete strip; + + pixelCount = count; + strip = new NeoPixelBus(pixelCount); + strip->Begin(); +} + +enum class AwaProtocol +{ + HEADER_A, + HEADER_w, + HEADER_a, + HEADER_HI, + HEADER_LO, + HEADER_CRC, + VERSION2_GAIN, + VERSION2_RED, + VERSION2_GREEN, + VERSION2_BLUE, + RED, + GREEN, + BLUE, + FLETCHER1, + FLETCHER2 +}; + +// static data buffer for the loop +#define MAX_BUFFER 2048 +uint8_t buffer[MAX_BUFFER]; +AwaProtocol state = AwaProtocol::HEADER_A; +bool version2 = false; +uint8_t incoming_gain = 0; +uint8_t incoming_red = 0; +uint8_t incoming_green = 0; +uint8_t incoming_blue = 0; +uint8_t CRC = 0; +uint16_t count = 0; +uint16_t currentPixel = 0; +uint16_t fletcher1 = 0; +uint16_t fletcher2 = 0; + +#ifdef THIS_IS_RGBW + RgbwColor inputColor; + uint8_t wChannel[256]; + uint8_t rChannel[256]; + uint8_t gChannel[256]; + uint8_t bChannel[256]; +#else + RgbColor inputColor; +#endif + +// stats +unsigned long stat_start = 0; +uint16_t stat_good = 0; +uint16_t stat_frames = 0; +uint16_t stat_final_good = 0; +uint16_t stat_final_frames = 0; +bool wantShow = false; + +inline void ShowMe() +{ + if (wantShow == true && strip != NULL && strip->CanShow()) + { + stat_good++; + wantShow = false; + strip->Show(); + } +} + +void readSerialData() +{ + unsigned long curTime = millis(); + uint16_t bufferPointer = 0; + uint16_t internalIndex = min(Serial.available(), MAX_BUFFER); + + if (internalIndex > 0) + internalIndex = Serial.readBytes(buffer, internalIndex); + + // stats + if (internalIndex > 0 && curTime - stat_start > 1000) + { + if (stat_frames > 0 && stat_frames >= stat_good) + { + stat_final_good = stat_good; + stat_final_frames = stat_frames; + } + + stat_start = curTime; + stat_good = 0; + stat_frames = 0; + } + else if (curTime - stat_start > 5000) + { + stat_start = curTime; + stat_good = 0; + stat_frames = 0; + + Serial.write("HyperSerialEsp8266 version 6.\r\nStatistics for the last full 1 second cycle.\r\n"); + Serial.write("Frames per second: "); + Serial.print(stat_final_frames); + Serial.write("\r\nGood frames: "); + Serial.print(stat_final_good); + Serial.write("\r\nBad frames: "); + Serial.print(stat_final_frames - stat_final_good); + Serial.write("\r\n-------------------------\r\n"); + } + + if (state == AwaProtocol::HEADER_A) + ShowMe(); + + while (bufferPointer < internalIndex) + { + byte input = buffer[bufferPointer++]; + switch (state) + { + case AwaProtocol::HEADER_A: + version2 = false; + if (input == 'A') + state = AwaProtocol::HEADER_w; + break; + + case AwaProtocol::HEADER_w: + if (input == 'w') + state = AwaProtocol::HEADER_a; + else + state = AwaProtocol::HEADER_A; + break; + + case AwaProtocol::HEADER_a: + if (input == 'a') + state = AwaProtocol::HEADER_HI; + else if (input == 'A') + { + state = AwaProtocol::HEADER_HI; + version2 = true; + } + else + state = AwaProtocol::HEADER_A; + break; + + case AwaProtocol::HEADER_HI: + stat_frames++; + currentPixel = 0; + count = input * 0x100; + CRC = input; + fletcher1 = 0; + fletcher2 = 0; + state = AwaProtocol::HEADER_LO; + break; + + case AwaProtocol::HEADER_LO: + count += input; + CRC = CRC ^ input ^ 0x55; + state = AwaProtocol::HEADER_CRC; + break; + + case AwaProtocol::HEADER_CRC: + if (CRC == input) + { + if (count + 1 != pixelCount) + Init(count + 1); + + state = AwaProtocol::RED; + } + else + state = AwaProtocol::HEADER_A; + break; + + case AwaProtocol::RED: + inputColor.R = input; + fletcher1 = (fletcher1 + (uint16_t)input) % 255; + fletcher2 = (fletcher2 + fletcher1) % 255; + + state = AwaProtocol::GREEN; + break; + + case AwaProtocol::GREEN: + inputColor.G = input; + fletcher1 = (fletcher1 + (uint16_t)input) % 255; + fletcher2 = (fletcher2 + fletcher1) % 255; + + state = AwaProtocol::BLUE; + break; + + case AwaProtocol::BLUE: + inputColor.B = input; + + #ifdef THIS_IS_RGBW + inputColor.W = min(rChannel[inputColor.R], + min(gChannel[inputColor.G], + bChannel[inputColor.B])); + inputColor.R -= rChannel[inputColor.W]; + inputColor.G -= gChannel[inputColor.W]; + inputColor.B -= bChannel[inputColor.W]; + inputColor.W = wChannel[inputColor.W]; + #endif + + fletcher1 = (fletcher1 + (uint16_t)input) % 255; + fletcher2 = (fletcher2 + fletcher1) % 255; + + if (currentPixel == 0 && skipFirstLed) + { + #ifdef THIS_IS_RGBW + strip->SetPixelColor(currentPixel++, RgbwColor(0, 0, 0, 0)); + #else + strip->SetPixelColor(currentPixel++, RgbColor(0, 0, 0)); + #endif + } + else + setStripPixel(currentPixel++, inputColor); + + if (count-- > 0) + state = AwaProtocol::RED; + else + { + if (version2) + state = AwaProtocol::VERSION2_GAIN; + else + state = AwaProtocol::FLETCHER1; + } + + break; + + case AwaProtocol::VERSION2_GAIN: + incoming_gain = input; + fletcher1 = (fletcher1 + (uint16_t)input) % 255; + fletcher2 = (fletcher2 + fletcher1) % 255; + + state = AwaProtocol::VERSION2_RED; + break; + + case AwaProtocol::VERSION2_RED: + incoming_red = input; + fletcher1 = (fletcher1 + (uint16_t)input) % 255; + fletcher2 = (fletcher2 + fletcher1) % 255; + + state = AwaProtocol::VERSION2_GREEN; + break; + + case AwaProtocol::VERSION2_GREEN: + incoming_green = input; + fletcher1 = (fletcher1 + (uint16_t)input) % 255; + fletcher2 = (fletcher2 + fletcher1) % 255; + + state = AwaProtocol::VERSION2_BLUE; + break; + + case AwaProtocol::VERSION2_BLUE: + incoming_blue = input; + fletcher1 = (fletcher1 + (uint16_t)input) % 255; + fletcher2 = (fletcher2 + fletcher1) % 255; + + state = AwaProtocol::FLETCHER1; + break; + + case AwaProtocol::FLETCHER1: + if (input != fletcher1) + state = AwaProtocol::HEADER_A; + else + state = AwaProtocol::FLETCHER2; + break; + + case AwaProtocol::FLETCHER2: + if (input == fletcher2) + { + wantShow = true; + ShowMe(); + + + if (version2) + { + #ifdef THIS_IS_RGBW + float final_limit = (incoming_gain != 255) ? incoming_gain / 255.0f : 1.0f; + if (rCorrection != incoming_red || gCorrection != incoming_green || bCorrection != incoming_blue || whiteLimit != final_limit) + { + rCorrection = incoming_red; + gCorrection = incoming_green; + bCorrection = incoming_blue; + whiteLimit = final_limit; + prepareCalibration(); + } + #endif + } + } + + state = AwaProtocol::HEADER_A; + break; + } + } +} + +#ifdef THIS_IS_RGBW + inline void setStripPixel(uint16_t pix, RgbwColor &inputColor) + { + if (pix < pixelCount) + { + strip->SetPixelColor(pix, inputColor); + } + } +#else + inline void setStripPixel(uint16_t pix, RgbColor &inputColor) + { + if (pix < pixelCount) + { + strip->SetPixelColor(pix, inputColor); + } + } +#endif + +void setup() +{ + // Init serial port + Serial.begin(serialSpeed); + Serial.setTimeout(50); + Serial.setRxBufferSize(2048); + + // Display config + Serial.write("\r\nWelcome!\r\nAwa driver 6.\r\n"); + + // first LED info + if (skipFirstLed) + Serial.write("First LED: disabled\r\n"); + else + Serial.write("First LED: enabled\r\n"); + + // RGBW claibration info + #ifdef THIS_IS_RGBW + #ifdef COLD_WHITE + Serial.write("Default color mode: RGBW cold\r\n"); + #else + Serial.write("Default color mode: RGBW neutral\r\n"); + #endif + prepareCalibration(); + #else + Serial.write("Color mode: RGB\r\n"); + #endif +} + +void prepareCalibration() +{ + #ifdef THIS_IS_RGBW + // prepare LUT calibration table, cold white is much better than "neutral" white + for (uint32_t i = 0; i < 256; i++) + { + // color calibration + float red = rCorrection * i; // adjust red + float green = gCorrection * i; // adjust green + float blue = bCorrection * i; // adjust blue + + wChannel[i] = (uint8_t)round(min(whiteLimit * i, 255.0f)); + rChannel[i] = (uint8_t)round(min(red / 0xFF, 255.0f)); + gChannel[i] = (uint8_t)round(min(green / 0xFF, 255.0f)); + bChannel[i] = (uint8_t)round(min(blue / 0xFF, 255.0f)); + } + + Serial.write("RGBW calibration. White limit(%): "); + Serial.print(whiteLimit * 100.0f); + Serial.write(" %, red: "); + Serial.print(rCorrection); + Serial.write(" , green: "); + Serial.print(gCorrection); + Serial.write(" , blue: "); + Serial.print(bCorrection); + Serial.write("\r\n"); + #endif +} + +void loop() +{ + readSerialData(); +} diff --git a/version for SK6812 cold white/HyperSerialEsp8266_SK6812ColdWhite/HyperSerialEsp8266_SK6812ColdWhite.ino b/version for SK6812 cold white/HyperSerialEsp8266_SK6812ColdWhite/HyperSerialEsp8266_SK6812ColdWhite.ino deleted file mode 100644 index 9a67993..0000000 --- a/version for SK6812 cold white/HyperSerialEsp8266_SK6812ColdWhite/HyperSerialEsp8266_SK6812ColdWhite.ino +++ /dev/null @@ -1,297 +0,0 @@ -#include -//////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////// CONFIG SECTION STARTS ///////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -#define THIS_IS_RGBW // RGBW SK6812, otherwise comment it -bool skipFirstLed = false; // if set the first led in the strip will be set to black (for level shifters) -int serialSpeed = 2000000; // serial port speed - -//////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////// CONFIG SECTION ENDS ///////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -int pixelCount = 0; // This is dynamic, don't change it - -#ifdef THIS_IS_RGBW - #define LED_TYPE NeoGrbwFeature -#else - #define LED_TYPE NeoGrbFeature -#endif - - -NeoPixelBus* strip = NULL; - -void Init(int count) -{ - if (strip != NULL) - delete strip; - - pixelCount = count; - strip = new NeoPixelBus(pixelCount); - strip->Begin(); -} - -enum class AwaProtocol { - HEADER_A, - HEADER_w, - HEADER_a, - HEADER_HI, - HEADER_LO, - HEADER_CRC, - RED, - GREEN, - BLUE, - FLETCHER1, - FLETCHER2 -}; - -// static data buffer for the loop -#define MAX_BUFFER 2048 -uint8_t buffer[MAX_BUFFER]; -AwaProtocol state = AwaProtocol::HEADER_A; -uint8_t CRC = 0; -uint16_t count = 0; -uint16_t currentPixel = 0; -uint16_t fletcher1 = 0; -uint16_t fletcher2 = 0; - -#ifdef THIS_IS_RGBW -RgbwColor inputColor; -uint8_t rChannel[256]; -uint8_t gChannel[256]; -uint8_t bChannel[256]; - -#else -RgbColor inputColor; -#endif - -// stats -unsigned long stat_start = 0; -uint16_t stat_good = 0; -uint16_t stat_frames = 0; -uint16_t stat_final_good = 0; -uint16_t stat_final_frames = 0; -bool wantShow = false; - -inline void ShowMe() -{ - if (wantShow == true && strip != NULL && strip->CanShow()) - { - stat_good++;; - wantShow = false; - strip->Show(); - } -} - -void readSerialData() -{ - unsigned long curTime = millis(); - uint16_t bufferPointer = 0; - uint16_t internalIndex = min(Serial.available(), MAX_BUFFER); - - if (internalIndex > 0) - internalIndex = Serial.readBytes(buffer, internalIndex); - - // stats - if (internalIndex > 0 && curTime - stat_start > 1000) - { - if (stat_frames > 0 && stat_frames >= stat_good ) - { - stat_final_good = stat_good; - stat_final_frames = stat_frames; - } - - stat_start = curTime; - stat_good = 0; - stat_frames = 0; - } - else if (curTime - stat_start > 5000) - { - stat_start = curTime; - stat_good = 0; - stat_frames = 0; - - Serial.write("HyperSerialEsp8266 version 5.\r\nStatistics for the last full 1 second cycle.\r\n"); - Serial.write("Frames per second: "); - Serial.print(stat_final_frames); - Serial.write("\r\nGood frames: "); - Serial.print(stat_final_good); - Serial.write("\r\nBad frames: "); - Serial.print(stat_final_frames - stat_final_good); - Serial.write("\r\n-------------------------\r\n"); - } - - if (state == AwaProtocol::HEADER_A) - ShowMe(); - - while (bufferPointer < internalIndex) - { - byte input = buffer[bufferPointer++]; - switch (state) - { - case AwaProtocol::HEADER_A: - if (input == 'A') state = AwaProtocol::HEADER_w; - break; - - case AwaProtocol::HEADER_w: - if (input == 'w') state = AwaProtocol::HEADER_a; - else state = AwaProtocol::HEADER_A; - break; - - case AwaProtocol::HEADER_a: - if (input == 'a') state = AwaProtocol::HEADER_HI; - else state = AwaProtocol::HEADER_A; - break; - - case AwaProtocol::HEADER_HI: - stat_frames++; - currentPixel = 0; - count = input * 0x100; - CRC = input; - fletcher1 = 0; - fletcher2 = 0; - state = AwaProtocol::HEADER_LO; - break; - - case AwaProtocol::HEADER_LO: - count += input; - CRC = CRC ^ input ^ 0x55; - state = AwaProtocol::HEADER_CRC; - break; - - case AwaProtocol::HEADER_CRC: - if (CRC == input) - { - if (count+1 != pixelCount) Init(count+1); - state = AwaProtocol::RED; - } - else - state = AwaProtocol::HEADER_A; - break; - - case AwaProtocol::RED: - inputColor.R = input; - fletcher1 = (fletcher1 + (uint16_t)input) % 255; - fletcher2 = (fletcher2 + fletcher1) % 255; - - state = AwaProtocol::GREEN; - break; - - case AwaProtocol::GREEN: - inputColor.G = input; - fletcher1 = (fletcher1 + (uint16_t)input) % 255; - fletcher2 = (fletcher2 + fletcher1) % 255; - - state = AwaProtocol::BLUE; - break; - - case AwaProtocol::BLUE: - inputColor.B = input; - - #ifdef THIS_IS_RGBW - inputColor.W = min(rChannel[inputColor.R], - min(gChannel[inputColor.G], - bChannel[inputColor.B])); - inputColor.R -= rChannel[inputColor.W]; - inputColor.G -= gChannel[inputColor.W]; - inputColor.B -= bChannel[inputColor.W]; - #endif - - fletcher1 = (fletcher1 + (uint16_t)input) % 255; - fletcher2 = (fletcher2 + fletcher1) % 255; - - if (currentPixel == 0 && skipFirstLed) - { - #ifdef THIS_IS_RGBW - strip->SetPixelColor(currentPixel++, RgbwColor(0, 0, 0, 0)); - #else - strip->SetPixelColor(currentPixel++, RgbColor(0, 0, 0)); - #endif - } - else - setStripPixel(currentPixel++, inputColor); - - if (count-- > 0) state = AwaProtocol::RED; - else state = AwaProtocol::FLETCHER1; - break; - - case AwaProtocol::FLETCHER1: - if (input != fletcher1) state = AwaProtocol::HEADER_A; - else state = AwaProtocol::FLETCHER2; - break; - - case AwaProtocol::FLETCHER2: - if (input == fletcher2) - { - wantShow = true; - ShowMe(); - } - state = AwaProtocol::HEADER_A; - break; - } - } -} - -#ifdef THIS_IS_RGBW -inline void setStripPixel(uint16_t pix, RgbwColor& inputColor) -{ - if (pix < pixelCount) - { - strip->SetPixelColor(pix, inputColor); - } -} -#else -inline void setStripPixel(uint16_t pix, RgbColor& inputColor) -{ - if (pix < pixelCount) - { - strip->SetPixelColor(pix, inputColor); - } -} -#endif - -void setup() -{ - // Init serial port - Serial.begin(serialSpeed); - Serial.setTimeout(50); - Serial.setRxBufferSize(2048); - - // Display config - Serial.write("\r\nWelcome!\r\nAwa driver 5.\r\n"); - #ifdef THIS_IS_RGBW - Serial.write("Color mode: RGBW cold\r\n"); - #else - Serial.write("Color mode: RGB\r\n"); - #endif - if (skipFirstLed) - Serial.write("First LED: disabled\r\n"); - else - Serial.write("First LED: enabled\r\n"); - - // Prepare calibration for RGBW - #ifdef THIS_IS_RGBW - // prepare LUT calibration table, cold white is much better than "neutral" white - for (uint32_t i = 0; i < 256; i++) - { - // color calibration - uint32_t rCorrection = 0xA0 * (uint32_t)i; // adjust red -> white in 0-0xFF range - uint32_t gCorrection = 0xA0 * (uint32_t)i; // adjust green -> white in 0-0xFF range - uint32_t bCorrection = 0xA0 * (uint32_t)i; // adjust blue -> white in 0-0xFF range - - rCorrection /= 0xFF; - gCorrection /= 0xFF; - bCorrection /= 0xFF; - - rChannel[i] = (uint8_t)rCorrection; - gChannel[i] = (uint8_t)gCorrection; - bChannel[i] = (uint8_t)bCorrection; - } - #endif -} - -void loop() -{ - readSerialData(); -} diff --git a/version for SK6812 neutral white/HyperSerialEsp8266_SK6812NeutralWhite/HyperSerialEsp8266_SK6812NeutralWhite.ino b/version for SK6812 neutral white/HyperSerialEsp8266_SK6812NeutralWhite/HyperSerialEsp8266_SK6812NeutralWhite.ino deleted file mode 100644 index 40d7ae0..0000000 --- a/version for SK6812 neutral white/HyperSerialEsp8266_SK6812NeutralWhite/HyperSerialEsp8266_SK6812NeutralWhite.ino +++ /dev/null @@ -1,297 +0,0 @@ -#include -//////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////// CONFIG SECTION STARTS ///////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -#define THIS_IS_RGBW // RGBW SK6812, otherwise comment it -bool skipFirstLed = true; // if set the first led in the strip will be set to black (for level shifters) -int serialSpeed = 2000000; // serial port speed - -//////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////// CONFIG SECTION ENDS ///////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -int pixelCount = 0; // This is dynamic, don't change it - -#ifdef THIS_IS_RGBW - #define LED_TYPE NeoGrbwFeature -#else - #define LED_TYPE NeoGrbFeature -#endif - - -NeoPixelBus* strip = NULL; - -void Init(int count) -{ - if (strip != NULL) - delete strip; - - pixelCount = count; - strip = new NeoPixelBus(pixelCount); - strip->Begin(); -} - -enum class AwaProtocol { - HEADER_A, - HEADER_w, - HEADER_a, - HEADER_HI, - HEADER_LO, - HEADER_CRC, - RED, - GREEN, - BLUE, - FLETCHER1, - FLETCHER2 -}; - -// static data buffer for the loop -#define MAX_BUFFER 2048 -uint8_t buffer[MAX_BUFFER]; -AwaProtocol state = AwaProtocol::HEADER_A; -uint8_t CRC = 0; -uint16_t count = 0; -uint16_t currentPixel = 0; -uint16_t fletcher1 = 0; -uint16_t fletcher2 = 0; - -#ifdef THIS_IS_RGBW -RgbwColor inputColor; -uint8_t rChannel[256]; -uint8_t gChannel[256]; -uint8_t bChannel[256]; - -#else -RgbColor inputColor; -#endif - -// stats -unsigned long stat_start = 0; -uint16_t stat_good = 0; -uint16_t stat_frames = 0; -uint16_t stat_final_good = 0; -uint16_t stat_final_frames = 0; -bool wantShow = false; - -inline void ShowMe() -{ - if (wantShow == true && strip != NULL && strip->CanShow()) - { - stat_good++;; - wantShow = false; - strip->Show(); - } -} - -void readSerialData() -{ - unsigned long curTime = millis(); - uint16_t bufferPointer = 0; - uint16_t internalIndex = min(Serial.available(), MAX_BUFFER); - - if (internalIndex > 0) - internalIndex = Serial.readBytes(buffer, internalIndex); - - // stats - if (internalIndex > 0 && curTime - stat_start > 1000) - { - if (stat_frames > 0 && stat_frames >= stat_good ) - { - stat_final_good = stat_good; - stat_final_frames = stat_frames; - } - - stat_start = curTime; - stat_good = 0; - stat_frames = 0; - } - else if (curTime - stat_start > 5000) - { - stat_start = curTime; - stat_good = 0; - stat_frames = 0; - - Serial.write("HyperSerialEsp8266 version 5.\r\nStatistics for the last full 1 second cycle.\r\n"); - Serial.write("Frames per second: "); - Serial.print(stat_final_frames); - Serial.write("\r\nGood frames: "); - Serial.print(stat_final_good); - Serial.write("\r\nBad frames: "); - Serial.print(stat_final_frames - stat_final_good); - Serial.write("\r\n-------------------------\r\n"); - } - - if (state == AwaProtocol::HEADER_A) - ShowMe(); - - while (bufferPointer < internalIndex) - { - byte input = buffer[bufferPointer++]; - switch (state) - { - case AwaProtocol::HEADER_A: - if (input == 'A') state = AwaProtocol::HEADER_w; - break; - - case AwaProtocol::HEADER_w: - if (input == 'w') state = AwaProtocol::HEADER_a; - else state = AwaProtocol::HEADER_A; - break; - - case AwaProtocol::HEADER_a: - if (input == 'a') state = AwaProtocol::HEADER_HI; - else state = AwaProtocol::HEADER_A; - break; - - case AwaProtocol::HEADER_HI: - stat_frames++; - currentPixel = 0; - count = input * 0x100; - CRC = input; - fletcher1 = 0; - fletcher2 = 0; - state = AwaProtocol::HEADER_LO; - break; - - case AwaProtocol::HEADER_LO: - count += input; - CRC = CRC ^ input ^ 0x55; - state = AwaProtocol::HEADER_CRC; - break; - - case AwaProtocol::HEADER_CRC: - if (CRC == input) - { - if (count+1 != pixelCount) Init(count+1); - state = AwaProtocol::RED; - } - else - state = AwaProtocol::HEADER_A; - break; - - case AwaProtocol::RED: - inputColor.R = input; - fletcher1 = (fletcher1 + (uint16_t)input) % 255; - fletcher2 = (fletcher2 + fletcher1) % 255; - - state = AwaProtocol::GREEN; - break; - - case AwaProtocol::GREEN: - inputColor.G = input; - fletcher1 = (fletcher1 + (uint16_t)input) % 255; - fletcher2 = (fletcher2 + fletcher1) % 255; - - state = AwaProtocol::BLUE; - break; - - case AwaProtocol::BLUE: - inputColor.B = input; - - #ifdef THIS_IS_RGBW - inputColor.W = min(rChannel[inputColor.R], - min(gChannel[inputColor.G], - bChannel[inputColor.B])); - inputColor.R -= rChannel[inputColor.W]; - inputColor.G -= gChannel[inputColor.W]; - inputColor.B -= bChannel[inputColor.W]; - #endif - - fletcher1 = (fletcher1 + (uint16_t)input) % 255; - fletcher2 = (fletcher2 + fletcher1) % 255; - - if (currentPixel == 0 && skipFirstLed) - { - #ifdef THIS_IS_RGBW - strip->SetPixelColor(currentPixel++, RgbwColor(0, 0, 0, 0)); - #else - strip->SetPixelColor(currentPixel++, RgbColor(0, 0, 0)); - #endif - } - else - setStripPixel(currentPixel++, inputColor); - - if (count-- > 0) state = AwaProtocol::RED; - else state = AwaProtocol::FLETCHER1; - break; - - case AwaProtocol::FLETCHER1: - if (input != fletcher1) state = AwaProtocol::HEADER_A; - else state = AwaProtocol::FLETCHER2; - break; - - case AwaProtocol::FLETCHER2: - if (input == fletcher2) - { - wantShow = true; - ShowMe(); - } - state = AwaProtocol::HEADER_A; - break; - } - } -} - -#ifdef THIS_IS_RGBW -inline void setStripPixel(uint16_t pix, RgbwColor& inputColor) -{ - if (pix < pixelCount) - { - strip->SetPixelColor(pix, inputColor); - } -} -#else -inline void setStripPixel(uint16_t pix, RgbColor& inputColor) -{ - if (pix < pixelCount) - { - strip->SetPixelColor(pix, inputColor); - } -} -#endif - -void setup() -{ - // Init serial port - Serial.begin(serialSpeed); - Serial.setTimeout(50); - Serial.setRxBufferSize(2048); - - // Display config - Serial.write("\r\nWelcome!\r\nAwa driver 5.\r\n"); - #ifdef THIS_IS_RGBW - Serial.write("Color mode: RGBW neutral\r\n"); - #else - Serial.write("Color mode: RGB\r\n"); - #endif - if (skipFirstLed) - Serial.write("First LED: disabled\r\n"); - else - Serial.write("First LED: enabled\r\n"); - - // Prepare calibration for RGBW - #ifdef THIS_IS_RGBW - // prepare LUT calibration table, neutral white is in fact yellow - for (uint32_t i = 0; i < 256; i++) - { - // color calibration - uint32_t rCorrection = 0xB0 * (uint32_t)i; // adjust red -> white in 0-0xFF range - uint32_t gCorrection = 0xB0 * (uint32_t)i; // adjust green -> white in 0-0xFF range - uint32_t bCorrection = 0x70 * (uint32_t)i; // adjust blue -> white in 0-0xFF range - - rCorrection /= 0xFF; - gCorrection /= 0xFF; - bCorrection /= 0xFF; - - rChannel[i] = (uint8_t)rCorrection; - gChannel[i] = (uint8_t)gCorrection; - bChannel[i] = (uint8_t)bCorrection; - } - #endif -} - -void loop() -{ - readSerialData(); -}