From 151f9e8c43405d4e1b4ed1bb6f6828630dac7b3a Mon Sep 17 00:00:00 2001 From: Fisch Date: Tue, 1 Dec 2020 22:51:24 +0100 Subject: [PATCH] first working sk6812 RGB output with color copy --- platformio.ini | 17 ++ src/FastLED_RGBW.h | 65 ++++++ .../LEDstream_FastLED.ino => src/main.cpp | 203 +++++++++++------- 3 files changed, 204 insertions(+), 81 deletions(-) create mode 100644 platformio.ini create mode 100644 src/FastLED_RGBW.h rename Arduino/LEDstream_FastLED/LEDstream_FastLED.ino => src/main.cpp (55%) diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..d96ff70 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,17 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:d1_mini] +platform = espressif8266 +board = d1_mini +framework = arduino + +lib_deps = + fastled/FastLED \ No newline at end of file diff --git a/src/FastLED_RGBW.h b/src/FastLED_RGBW.h new file mode 100644 index 0000000..4f03274 --- /dev/null +++ b/src/FastLED_RGBW.h @@ -0,0 +1,65 @@ +/* FastLED_RGBW + * + * Hack to enable SK6812 RGBW strips to work with FastLED. + * + * Original code by Jim Bumgardner (http://krazydad.com). + * Modified by David Madison (http://partsnotincluded.com). + * +*/ + +#include +/*#ifndef fastled_h + #include +#endif +*/ + +#ifndef FastLED_RGBW_h +#define FastLED_RGBW_h + +struct CRGBW { + union { + struct { + union { + uint8_t g; + uint8_t green; + }; + union { + uint8_t r; + uint8_t red; + }; + union { + uint8_t b; + uint8_t blue; + }; + union { + uint8_t w; + uint8_t white; + }; + }; + uint8_t raw[4]; + }; + + CRGBW(){} + + CRGBW(uint8_t rd, uint8_t grn, uint8_t blu, uint8_t wht){ + r = rd; + g = grn; + b = blu; + w = wht; + } + + inline void operator = (const CRGB c) __attribute__((always_inline)){ + this->r = c.r; + this->g = c.g; + this->b = c.b; + this->white = 0; + } +}; + +inline uint16_t getRGBWsize(uint16_t nleds){ + uint16_t nbytes = nleds * 4; + if(nbytes % 3 > 0) return nbytes / 3 + 1; + else return nbytes / 3; +} + +#endif diff --git a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino b/src/main.cpp similarity index 55% rename from Arduino/LEDstream_FastLED/LEDstream_FastLED.ino rename to src/main.cpp index d53f816..a750398 100644 --- a/Arduino/LEDstream_FastLED/LEDstream_FastLED.ino +++ b/src/main.cpp @@ -1,11 +1,9 @@ -/* LEDstream_FastLED - * - * Modified version of Adalight that uses the FastLED - * library (http://fastled.io) for driving led strips. - * - * http://github.com/dmadison/Adalight-FastLED +/* + * Project Adalight FastLED + * @author David Madison + * @link github.com/dmadison/Adalight-FastLED + * @license LGPL - Copyright (c) 2017 David Madison * - * -------------------------------------------------------------------- * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -18,43 +16,69 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . - * -------------------------------------------------------------------- + * */ +#define SK6812RGBW + +#include + + // --- General Settings -static const uint16_t - Num_Leds = 80; // strip length -static const uint8_t - Brightness = 255; // maximum brightness +const uint16_t + Num_Leds = 112; // strip length +const uint8_t + Brightness = 255; // maximum brightness // --- FastLED Setings -#define LED_TYPE WS2812B // led strip type for FastLED -#define COLOR_ORDER GRB // color order for bitbang -#define PIN_DATA 6 // led data output pin -//#define PIN_CLOCK 7 // led data clock pin (uncomment if you're using a 4-wire LED type) +#if defined(SK6812RGBW) + #define LED_TYPE SK6812 // led strip type for FastLED + #define COLOR_ORDER RGB // color order for bitbang +#else + #define LED_TYPE WS2812B // led strip type for FastLED + #define COLOR_ORDER GRB // color order for bitbang +#endif + + +#define PIN_DATA D2 // led data output pin +// #define PIN_CLOCK 7 // led data clock pin (uncomment if you're using a 4-wire LED type) // --- Serial Settings -static const unsigned long - SerialSpeed = 115200; // serial port speed -static const uint16_t - SerialTimeout = 60; // time before LEDs are shut off if no data (in seconds), 0 to disable +const unsigned long + SerialSpeed = 115200; // serial port speed +const uint16_t + SerialTimeout = 60; // time before LEDs are shut off if no data (in seconds), 0 to disable // --- Optional Settings (uncomment to add) -#define SERIAL_FLUSH // Serial buffer cleared on LED latch -//#define CLEAR_ON_START // LEDs are cleared on reset -//#define GROUND_PIN 10 // additional grounding pin (optional) -//#define CALIBRATE // sets all LEDs to the color of the first +#define SERIAL_FLUSH // Serial buffer cleared on LED latch +#define CLEAR_ON_START // LEDs are cleared on reset // --- Debug Settings (uncomment to add) -//#define DEBUG_LED 13 // toggles the Arduino's built-in LED on header match -//#define DEBUG_FPS 8 // enables a pulse on LED latch +#define DEBUG_LED LED_BUILTIN // toggles the Arduino's built-in LED on header match +// #define DEBUG_FPS 8 // enables a pulse on LED latch // -------------------------------------------------------------------- #include -CRGB leds[Num_Leds]; -uint8_t * ledsRaw = (uint8_t *)leds; + +#if defined(SK6812RGBW) + #include "FastLED_RGBW.h" //rgbw +#endif + +// + +// FastLED with RGBW +#if defined(SK6812RGBW) + CRGBW send_leds[Num_Leds]; + CRGB *send_ledsRaw = (CRGB *) &send_leds[0]; + + CRGB leds[Num_Leds]; + uint8_t * ledsRaw = (uint8_t *)leds; +#else + CRGB leds[Num_Leds]; + uint8_t * ledsRaw = (uint8_t *)leds; +#endif // A 'magic word' (along with LED count & checksum) precedes each block // of LED data; this assists the microcontroller in syncing up with the @@ -70,7 +94,7 @@ uint8_t * ledsRaw = (uint8_t *)leds; // XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B, // where 0 = off and 255 = max brightness. -static const uint8_t magic[] = { +const uint8_t magic[] = { 'A','d','a'}; #define MAGICSIZE sizeof(magic) @@ -81,18 +105,23 @@ static const uint8_t magic[] = { enum processModes_t {Header, Data} mode = Header; -static int16_t - c; -static uint16_t - outPos; -static uint32_t - bytesRemaining; -static unsigned long - t, - lastByteTime, - lastAckTime; +int16_t c; // current byte, must support -1 if no data available +uint16_t outPos; // current byte index in the LED array +uint32_t bytesRemaining; // count of bytes yet received, set by checksum +unsigned long t, lastByteTime, lastAckTime; // millisecond timestamps + +void headerMode(); +void dataMode(); +void timeouts(); + +// Macros initialized +#ifdef SERIAL_FLUSH + #undef SERIAL_FLUSH + #define SERIAL_FLUSH while(Serial.available() > 0) { Serial.read(); } +#else + #define SERIAL_FLUSH +#endif -// Debug macros initialized #ifdef DEBUG_LED #define ON 1 #define OFF 0 @@ -109,11 +138,6 @@ static unsigned long #endif void setup(){ - #ifdef GROUND_PIN - pinMode(GROUND_PIN, OUTPUT); - digitalWrite(GROUND_PIN, LOW); - #endif - #ifdef DEBUG_LED pinMode(DEBUG_LED, OUTPUT); digitalWrite(DEBUG_LED, LOW); @@ -123,10 +147,18 @@ void setup(){ pinMode(DEBUG_FPS, OUTPUT); #endif - #ifdef PIN_CLOCK + #if defined(PIN_CLOCK) && defined(PIN_DATA) FastLED.addLeds(leds, Num_Leds); + #elif defined(PIN_DATA) + #if defined(SK6812RGBW) + //FastLED with RGBW + FastLED.addLeds(send_ledsRaw, getRGBWsize(Num_Leds)); + #else + FastLED.addLeds(leds, Num_Leds); + #endif + #else - FastLED.addLeds(leds, Num_Leds); + #error "No LED output pins defined. Check your settings at the top." #endif FastLED.setBrightness(Brightness); @@ -141,11 +173,7 @@ void setup(){ lastByteTime = lastAckTime = millis(); // Set initial counters } -void loop(){ - adalight(); -} - -void adalight(){ +void loop(){ t = millis(); // Save current time // If there is new serial data @@ -193,11 +221,19 @@ void headerMode(){ 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. - D_LED(ON); - bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L); - outPos = 0; - memset(leds, 0, Num_Leds * sizeof(struct CRGB)); - mode = Data; // Proceed to latch wait mode + #if defined(SK6812RGBW) + D_LED(ON); + bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L); + outPos = 0; + memset(leds, 0, Num_Leds * sizeof(struct CRGB)); + mode = Data; // Proceed to latch wait mode + #else + D_LED(ON); + bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L); + outPos = 0; + memset(leds, 0, Num_Leds * sizeof(struct CRGB)); + mode = Data; // Proceed to latch wait mode + #endif } headPos = 0; // Reset header position regardless of checksum result break; @@ -208,35 +244,34 @@ void headerMode(){ void dataMode(){ // If LED data is not full if (outPos < sizeof(leds)){ - dataSet(); + + #if defined(SK6812RGBW) + ledsRaw[outPos++] = c; // Issue next byte + #else + ledsRaw[outPos++] = c; // Issue next byte + #endif } bytesRemaining--; if(bytesRemaining == 0) { // End of data -- issue latch: mode = Header; // Begin next header search + + #if defined(SK6812RGBW) + //Copy data over + for(int i = 0; i < Num_Leds; i++){ + //send_leds[i] = CRGBW(0, 0, 0, 50); + send_leds[i] = CRGBW(leds[i].r, leds[i].g, leds[i].b, 0); + } + #endif + FastLED.show(); D_FPS; D_LED(OFF); - #ifdef SERIAL_FLUSH - serialFlush(); - #endif + SERIAL_FLUSH; } } -void dataSet(){ - #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 -} - void timeouts(){ // No data received. If this persists, send an ACK packet // to host once every second to alert it to our presence. @@ -246,16 +281,22 @@ void timeouts(){ // If no data received for an extended time, turn off all LEDs. if(SerialTimeout != 0 && (t - lastByteTime) >= (uint32_t) SerialTimeout * 1000) { - memset(leds, 0, Num_Leds * sizeof(struct CRGB)); //filling Led array by zeroes + #if defined(SK6812RGBW) + memset(leds, 0, Num_Leds * sizeof(struct CRGB)); //filling Led array by zeroes + #else + memset(leds, 0, Num_Leds * sizeof(struct CRGB)); //filling Led array by zeroes + #endif + + #if defined(SK6812RGBW) + //All Black + for(int i = 0; i < Num_Leds; i++){ + send_leds[i] = CRGBW(0, 0, 0, 0); + } + #endif + FastLED.show(); mode = Header; lastByteTime = t; // Reset counter } } } - -void serialFlush(){ - while(Serial.available() > 0) { - Serial.read(); - } -}