diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index 03df3d6..b2dfae5 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -114,60 +114,57 @@ WS2812FX * strip = NULL; #if USE_WS2812FX_DMA == 0 // Uses GPIO3/RXD0/RX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods #if !defined(LED_TYPE_WS2811) - NeoEsp8266Dma800KbpsMethod * dma = NULL ; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) + NeoPixelBus * dma = NULL ; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) #else - NeoEsp8266Dma400KbpsMethod * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) + NeoPixelBus * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) #endif #endif #if USE_WS2812FX_DMA == 1 // Uses UART1: GPIO1/TXD0/TX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods #if !defined(LED_TYPE_WS2811) - NeoEsp8266Uart0800KbpsMethod * dma = NULL; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) + NeoPixelBus * dma = NULL; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) #else - NeoEsp8266Uart0400KbpsMethod * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) + NeoPixelBus * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) #endif #endif #if USE_WS2812FX_DMA == 2 // Uses UART2: GPIO2/TXD1/D4, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods #if !defined(LED_TYPE_WS2811) - NeoEsp8266Uart1800KbpsMethod * dma = NULL; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) + NeoPixelBus * dma = NULL; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) #else - NeoEsp8266Uart1400KbpsMethod * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) + NeoPixelBus * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) #endif #endif void initDMA(uint16_t stripSize = NUMLEDS){ if (dma != NULL) { delete(dma); } - uint8_t ledcolors = 3; - if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) { - ledcolors = 4; - } #if USE_WS2812FX_DMA == 0 // Uses GPIO3/RXD0/RX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods #if !defined(LED_TYPE_WS2811) - dma = new NeoEsp8266Dma800KbpsMethod(stripSize, ledcolors); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) + dma = new NeoPixelBus(stripSize); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) #else - dma = new NeoEsp8266Dma400KbpsMethod(stripSize, ledcolors); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) + dma = new NeoPixelBus(stripSize); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) #endif #endif #if USE_WS2812FX_DMA == 1 // Uses UART1: GPIO1/TXD0/TX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods #if !defined(LED_TYPE_WS2811) - dma = new NeoEsp8266Uart0800KbpsMethod(stripSize, ledcolors); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) + dma = new NeoPixelBus(stripSize); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) #else - dma = new NeoEsp8266Uart0400KbpsMethod(stripSize, ledcolors); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) + dma = new NeoPixelBus(stripSize); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) #endif #endif #if USE_WS2812FX_DMA == 2 // Uses UART2: GPIO2/TXD1/D4, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods #if !defined(LED_TYPE_WS2811) - dma = new NeoEsp8266Uart1800KbpsMethod(stripSize, ledcolors); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) + dma = new NeoPixelBus(stripSize); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) #else - dma = new NeoEsp8266Uart1400KbpsMethod(stripSize, ledcolors); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) + dma = new NeoPixelBus(stripSize); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) #endif #endif - dma->Initialize(); + dma->Begin(); } void DMA_Show(void) { - if(dma->IsReadyToUpdate()) { - memcpy(dma->getPixels(), strip->getPixels(), dma->getPixelsSize()); - dma->Update(false); + if(dma->CanShow()) { + memcpy(dma->Pixels(), strip->getPixels(), dma->PixelsSize()); + dma->Dirty(); + dma->Show(); } } #endif @@ -312,12 +309,11 @@ void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, char RGBOrd initDMA(stripSize); strip->setCustomShow(DMA_Show); #endif - strip->setBrightness(brightness); //parameters: index, start, stop, mode, color, speed, options strip->setSegment(0, 0, stripSize - 1, ws2812fx_mode, hex_colors, convertSpeed(ws2812fx_speed), fxoptions); #if defined(CUSTOM_WS2812FX_ANIMATIONS) strip->setCustomMode(0, F("Fire 2012"), myCustomEffect0); -//strip->setCustomMode(1, F("CustEffect"), myCustomEffect1); + strip->setCustomMode(1, F("Gradient"), myCustomEffect1); gReverseDirection = (WS2812FXStripSettings.fxoptions & 128); #endif #if defined(ENABLE_E131) @@ -674,8 +670,6 @@ void setup() { if (mdns_result) { MDNS.addService("http", "tcp", 80); } - - prevmode = mode; #if defined(ENABLE_BUTTON_GY33) tcs.setConfig(MCU_LED_06, MCU_WHITE_ON); @@ -684,9 +678,9 @@ void setup() { #endif #if defined(ENABLE_REMOTE) irrecv.enableIRIn(); // Start the receiver - snprintf(last_state, sizeof(last_state), "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, ws2812fx_mode, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white, back_color.red, back_color.green, back_color.blue, back_color.white, xtra_color.red, xtra_color.green, xtra_color.blue,xtra_color.white); - last_state[sizeof(last_state)]= 0x00; #endif + snprintf(last_state, sizeof(last_state), "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, ws2812fx_mode, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white, back_color.red, back_color.green, back_color.blue, back_color.white, xtra_color.red, xtra_color.green, xtra_color.blue,xtra_color.white); + last_state[sizeof(last_state)]= 0x00; DBG_OUTPUT_PORT.println("finished Main Setup!"); initStrip(); @@ -751,35 +745,43 @@ void loop() { if(!strip->isRunning()) strip->start(); } - if ((mode == OFF) || (mode == TV) || (mode == E131)) { + if (((mode == OFF) && (brightness_actual == 0)) || (mode == TV) || (mode == E131)) { if(strip->isRunning()) { - strip->strip_off(); // Workaround: to be shure, + strip->strip_off(); // Workaround: to be shure, delay(10); // that strip is really off. Sometimes strip->stop isn't enought - strip->stop(); // should clear memory + strip->stop(); // should clear memory } else { if (prevmode != mode) { // Start temporarily to clear strip strip->start(); - strip->strip_off(); // Workaround: to be shure, + strip->strip_off(); // Workaround: to be shure, delay(10); // that strip is really off. Sometimes strip->stop isn't enought - strip->stop(); // should clear memory + strip->stop(); // should clear memory } } } - if (( mode == AUTO) || (mode == HOLD)) { // strip->service() is only needed for modes with WS2812FX functionality - strip->service(); + if (( mode == AUTO) || (mode == HOLD) || ((mode == OFF) && (brightness !=0))) { + strip->service(); // strip->service() is only needed for modes with WS2812FX functionality } - if ((prevmode == AUTO) && (mode != AUTO)) { handleAutoStop(); } // stop auto mode + if ((prevmode == AUTO) && (mode != AUTO)) { + handleAutoStop(); // stop auto mode + } if (mode == OFF) { - #if defined(ENABLE_MQTT) - if (prevmode != mode) { snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =off", ""); } - #endif + if (prevmode != mode) { + #if defined(ENABLE_MQTT) + snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =off", ""); + #endif + if (fadeEffect) { + brightness_fade = 0; + } + } } if (mode == AUTO) { if (prevmode != mode) { + brightness_fade = brightness; handleAutoStart(); #if defined(ENABLE_MQTT) snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =auto", ""); @@ -789,19 +791,25 @@ void loop() { #if defined(ENABLE_TV) if (mode == TV) { - handleTV(); + if (prevmode != mode) { + brightness_fade = brightness; #if defined(ENABLE_MQTT) - if (prevmode != mode) { snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =tv", ""); } + snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =tv", ""); #endif + } + handleTV(); } #endif #if defined(ENABLE_E131) if (mode == E131) { - handleE131(); + if (prevmode != mode) { + brightness_fade = brightness; #if defined(ENABLE_MQTT) - if (prevmode != mode) { snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =e131", ""); } + snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =e131", ""); #endif + } + handleE131(); } #endif @@ -816,16 +824,18 @@ void loop() { } if (mode == SET_ALL) { - mode = HOLD; - if ((prevmode == OFF) || (prevmode == AUTO) || (prevmode == TV) || (prevmode == E131)) { setModeByStateString(last_state); } + mode = prevmode; + if ((prevmode == OFF) || (prevmode == AUTO) || (prevmode == TV) || (prevmode == E131)) { + setModeByStateString(last_state); + } #if defined(ENABLE_MQTT) snprintf(mqtt_buf, sizeof(mqtt_buf), "OK /%i", ws2812fx_mode); #endif strip->setMode(ws2812fx_mode); + if (fade_cnt==0) { fade_cnt=1; } + if (!fadeEffect) { fade_cnt=255; } + brightness_fade = brightness; convertColors(); - strip->setColors(0, hex_colors); - strip->setSpeed(convertSpeed(ws2812fx_speed)); - strip->setBrightness(brightness); prevmode = SET_ALL; strip->trigger(); } @@ -836,40 +846,95 @@ void loop() { snprintf(mqtt_buf, sizeof(mqtt_buf), "OK /%i", ws2812fx_mode); #endif strip->setMode(ws2812fx_mode); + brightness_fade = brightness; prevmode = SET_MODE; strip->trigger(); } if (mode == SET_COLOR) { + if (fade_cnt==0) { fade_cnt=1; } + if (!fadeEffect) { fade_cnt=255; } convertColors(); - strip->setColors(0, hex_colors); mode = prevmode; prevmode = SET_COLOR; - //DBG_OUTPUT_PORT.printf("mode: %d\r\n", mode); - if (mode == HOLD) strip->trigger(); } + // Async color transition + if ((fade_cnt > 0) && (fade_cnt < 254)) { + if ((fadeEffect) && (colorFadeDelay <= millis())) { + hex_colors_actual[0] = fade(hex_colors[0], hex_colors_mem[0], fade_cnt); + hex_colors_actual[1] = fade(hex_colors[1], hex_colors_mem[1], fade_cnt); + hex_colors_actual[2] = fade(hex_colors[2], hex_colors_mem[2], fade_cnt); + fade_cnt++; + colorFadeDelay = millis() + FADE_COLOR_DELAY; + strip->setColors(0, hex_colors_actual); + if ((mode == HOLD) && ((ws2812fx_mode != 1) && (ws2812fx_mode != 2) && (ws2812fx_mode != 8) && (ws2812fx_mode != 9) &&(ws2812fx_mode != 10) && (ws2812fx_mode != 15))) strip->trigger(); + } + } + if (fade_cnt >= 254) { + strip->setColors(0, hex_colors); + if (mode == HOLD) strip->trigger(); + fade_cnt = 0; + } + if (mode == SET_SPEED) { #if defined(ENABLE_MQTT) snprintf(mqtt_buf, sizeof(mqtt_buf), "OK ?%i", ws2812fx_speed); #endif - strip->setSpeed(convertSpeed(ws2812fx_speed)); mode = prevmode; prevmode = SET_SPEED; - if (mode == HOLD) strip->trigger(); } + // Async speed transition + if (ws2812fx_speed_actual != ws2812fx_speed) { + if (fadeEffect) { + if (speedFadeDelay <= millis()) { + if (ws2812fx_speed_actual < ws2812fx_speed) { + ws2812fx_speed_actual++; + } + if (ws2812fx_speed_actual > ws2812fx_speed) { + ws2812fx_speed_actual--; + } + speedFadeDelay = millis() + FADE_DELAY; + strip->setSpeed(convertSpeed(ws2812fx_speed_actual)); + if ((mode == HOLD) && ((ws2812fx_mode != 1) && (ws2812fx_mode != 2) && (ws2812fx_mode != 8) && (ws2812fx_mode != 9) &&(ws2812fx_mode != 10) && (ws2812fx_mode != 15))) strip->trigger(); + } + } else { + ws2812fx_speed_actual = ws2812fx_speed; + strip->setSpeed(ws2812fx_speed); + if (mode == HOLD) strip->trigger(); + } + } + if (mode == SET_BRIGHTNESS) { #if defined(ENABLE_MQTT) snprintf(mqtt_buf, sizeof(mqtt_buf), "OK %%%i", brightness); #endif - strip->setBrightness(brightness); + brightness_fade = brightness; mode = prevmode; prevmode = SET_BRIGHTNESS; - //DBG_OUTPUT_PORT.printf("mode: %d\r\n", mode); - if (mode == HOLD) strip->trigger(); } - - if (prevmode != mode) { - if ((prevmode != AUTO) && (prevmode != INIT_STRIP)) { // do not save if AUTO Mode was set + // Async brightness transition + if (brightness_actual != brightness_fade) { + if (fadeEffect) { + if(brightnessFadeDelay <= millis()) { + if (brightness_actual < brightness_fade) { + brightness_actual++; + } + if (brightness_actual > brightness_fade) { + brightness_actual--; + } + brightnessFadeDelay = millis() + FADE_DELAY; + strip->setBrightness(brightness_actual); + if ((mode == HOLD) && ((ws2812fx_mode != 1) && (ws2812fx_mode != 2) && (ws2812fx_mode != 8) && (ws2812fx_mode != 9) &&(ws2812fx_mode != 10) && (ws2812fx_mode != 15))) strip->trigger(); + } + } else { + brightness_actual = brightness; + strip->setBrightness(brightness_actual); + if (mode == HOLD) strip->trigger(); + } + } + + if (prevmode != mode) { + if (prevmode != INIT_STRIP) { // do not save if INIT_STRIP mode was set #if defined(ENABLE_STATE_SAVE) if(!settings_save_state.active()) settings_save_state.once(3, tickerSaveState); #endif diff --git a/Arduino/McLighting/definitions.h b/Arduino/McLighting/definitions.h index 91cb4ed..a136002 100644 --- a/Arduino/McLighting/definitions.h +++ b/Arduino/McLighting/definitions.h @@ -21,7 +21,7 @@ char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just #define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT must be active #define MQTT_HOME_ASSISTANT_SUPPORT // If defined, use AMQTT and select Tools -> IwIP Variant -> Higher Bandwidth #define ENABLE_BUTTON 14 // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control, the value defines the input pin (14 / D5) for switching the LED strip on / off, connect this PIN to ground to trigger button. -//#define ENABLE_BUTTON_GY33 12 // If defined, enable button handling code for GY-33 color sensor to scan color. The value defines the input pin (12 / D6) for read color data with RGB sensor, connect this PIN to ground to trigger button. +#define ENABLE_BUTTON_GY33 12 // If defined, enable button handling code for GY-33 color sensor to scan color. The value defines the input pin (12 / D6) for read color data with RGB sensor, connect this PIN to ground to trigger button. #if defined(ENABLE_BUTTON_GY33) #define GAMMA 2.5 // Gamma correction for GY-33 sensor #endif @@ -35,6 +35,15 @@ char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just #define ENABLE_TV // Enable TV Animation #define USE_HTML_MIN_GZ // uncomment for using index.htm & edit.htm from PROGMEM instead of SPIFFs +#define FADE_COLOR_DELAY 5 // Delay for color transition +#define FADE_DELAY 10 // Delay for brightness and speed transition + +bool fadeEffect = true; // Experimental: Enable transitions of color, brightness and speed. It does not work properly for all effects. +uint8_t fade_cnt = 0; +unsigned long colorFadeDelay = 0; +unsigned long brightnessFadeDelay = 0; +unsigned long speedFadeDelay = 0; + #if defined(ENABLE_E131) #define MULTICAST false #define START_UNIVERSE 1 // First DMX Universe to listen for @@ -82,7 +91,7 @@ char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just #endif // parameters for automatically cycling favorite patterns -uint32_t autoParams[][6] = { // main_color, back_color, xtra_color, speed, mode, duration (seconds) +uint32_t autoParams[][6] = { // main_color, back_color, xtra_color, speed, mode, duration (milliseconds) {0x00ff0000, 0x0000ff00, 0x00000000, 200, 1, 5000}, // blink red/geen for 5 seconds {0x0000ff00, 0x000000ff, 0x00000000, 200, 3, 10000}, // wipe green/blue for 10 seconds {0x000000ff, 0x00ff0000, 0x00000000, 60, 14, 10000}, // dual scan blue on red for 10 seconds @@ -133,20 +142,21 @@ uint32_t autoParams[][6] = { // main_color, back_color, xtra_color, speed, mod #define DBG_OUTPUT_PORT Serial // Set debug output port // List of all color modes -#if defined(ENABLE_LEGACY_ANIMATIONS) - enum MODE {OFF, AUTO, TV, E131, CUSTOM, HOLD, SET_ALL, SET_MODE, SET_COLOR, SET_SPEED, SET_BRIGHTNESS, INIT_STRIP, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW}; -#else - enum MODE {OFF, AUTO, TV, E131, CUSTOM, HOLD, SET_ALL, SET_MODE, SET_COLOR, SET_SPEED, SET_BRIGHTNESS, INIT_STRIP}; -#endif +enum MODE {OFF, AUTO, TV, E131, CUSTOM, HOLD, SET_ALL, SET_MODE, SET_COLOR, SET_SPEED, SET_BRIGHTNESS, INIT_STRIP}; MODE mode = SET_ALL; // Standard mode that is active when software starts -MODE prevmode = mode; +MODE prevmode = INIT_STRIP; -uint8_t ws2812fx_speed = 196; // Global variable for storing the delay between color changes --> smaller == faster -uint8_t brightness = 196; // Global variable for storing the brightness (255 == 100%) -uint8_t ws2812fx_mode = 0; // Global variable for storing the WS2812FX modes +uint8_t ws2812fx_speed = 196; // Global variable for storing the speed for effects --> smaller == slower +uint8_t ws2812fx_speed_actual = 196; // Global variable for storing the speed for effects while fading --> smaller == slower +uint8_t brightness = 196; // Global variable for storing the brightness (255 == 100%) +uint8_t brightness_actual = 0; // Global variable for storing the brightness while fadeing (255 == 100%) +uint8_t brightness_fade = 0; // Global variable for storing the brightness before change +uint8_t ws2812fx_mode = 0; // Global variable for storing the WS2812FX modes -uint32_t hex_colors[3] = {}; // Color array for setting WS2812FX -struct ledstate // Data structure to store a state of a single led +uint32_t hex_colors[3] = {}; // Color array for setting colors of WS2812FX +uint32_t hex_colors_actual[3] = {}; // Color array for actual colors of WS2812FX while fading +uint32_t hex_colors_mem[3] = {}; // Color array of colors of WS2812FX before fading +struct ledstate // Data structure to store a state of a single led { uint8_t red; uint8_t green; @@ -162,7 +172,7 @@ LEDState xtra_color = { 0, 0, 0, 0 }; // Store the "3rd color" of the strip u bool updateConfig = false; // For WiFiManger custom config and config char last_state[67]; // Keeps the state representation before auto or off mode -bool updateState = false; +bool updateState = false; // Button handling diff --git a/Arduino/McLighting/mode_custom_ws2812fx_animations.h b/Arduino/McLighting/mode_custom_ws2812fx_animations.h index a294fef..e025591 100644 --- a/Arduino/McLighting/mode_custom_ws2812fx_animations.h +++ b/Arduino/McLighting/mode_custom_ws2812fx_animations.h @@ -86,7 +86,26 @@ void Fire2012() { } } +void Gradient() { + for( uint16_t j = 0; j < WS2812FXStripSettings.stripSize; j++) { + uint16_t pixelnumber; + uint32_t color; + if( gReverseDirection ) { + pixelnumber = (WS2812FXStripSettings.stripSize - 1) - j; + } else { + pixelnumber = j; + } + color = fade(hex_colors_actual[1], hex_colors_actual[0], (j*255)/(WS2812FXStripSettings.stripSize - 1)); + strip->setPixelColor(pixelnumber, ((color >> 16) & 0xFF), ((color >> 8) & 0xFF), ((color >> 0) & 0xFF), ((color >> 24) & 0xFF)); + } +} + uint16_t myCustomEffect0() { Fire2012(); return (strip->getSpeed() / WS2812FXStripSettings.stripSize); } + +uint16_t myCustomEffect1() { + Gradient(); + return (strip->getSpeed() / WS2812FXStripSettings.stripSize); +} diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index 9e10a97..1e6f0e8 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -52,13 +52,20 @@ void handleE131(){ // Call convertColors whenever main_color, back_color or xtra_color changes. void convertColors() { + if ((fadeEffect) && (fade_cnt > 1) && (fade_cnt < 254)) { + memcpy(hex_colors_mem, hex_colors_actual, sizeof(hex_colors_actual)); + DBG_OUTPUT_PORT.println("Color transistion aborted. Restarting...!"); + fade_cnt = 1; + } else { + memcpy(hex_colors_mem, hex_colors, sizeof(hex_colors)); + } hex_colors[0] = (uint32_t)(main_color.white << 24) | (main_color.red << 16) | (main_color.green << 8) | main_color.blue; hex_colors[1] = (uint32_t)(back_color.white << 24) | (back_color.red << 16) | (back_color.green << 8) | back_color.blue; hex_colors[2] = (uint32_t)(xtra_color.white << 24) | (xtra_color.red << 16) | (xtra_color.green << 8) | xtra_color.blue; + memcpy(hex_colors_actual, hex_colors, sizeof(hex_colors)); } void getArgs() { - if (mode == SET_ALL || mode == SET_COLOR) { if (server.arg("rgb") != "") { uint32_t rgb = (uint32_t) strtoul(server.arg("rgb").c_str(), NULL, 16); @@ -132,7 +139,6 @@ void getArgs() { xtra_color.green = constrain(xtra_color.green, 0, 255); xtra_color.blue = constrain(xtra_color.blue, 0, 255); xtra_color.white = constrain(xtra_color.white, 0, 255); - convertColors(); } if (mode == SET_ALL || mode == SET_SPEED || mode == TV) { if ((server.arg("s") != "") && (server.arg("s").toInt() >= 0) && (server.arg("s").toInt() <= 255)) { @@ -461,12 +467,13 @@ bool setModeByStateString(String saved_state_string) { xtra_color.blue = str_blue.toInt(); str_white = getValue(saved_state_string, '|', 16); xtra_color.white = str_white.toInt(); - convertColors(); DBG_OUTPUT_PORT.print("Set to state: "); DBG_OUTPUT_PORT.println(listStatusJSON()); + //prevmode=mode; + //mode = SET_ALL; return true; } else { - DBG_OUTPUT_PORT.println("Saved conf not found!"); + DBG_OUTPUT_PORT.println("Saved state not found!"); return false; } return false; @@ -717,9 +724,10 @@ void autoTick() { strip->setColors(0, setcolors); strip->setSpeed(convertSpeed((uint8_t)autoParams[autoCount][3])); strip->setMode((uint8_t)autoParams[autoCount][4]); + strip->trigger(); autoTicker.once_ms((uint32_t)autoParams[autoCount][5], autoTick); DBG_OUTPUT_PORT.print("autoTick "); - DBG_OUTPUT_PORT.printf("autoTick[%d]: {0x%06x, %d, %d, %d}\r\n", autoCount, autoParams[autoCount][0], (uint8_t)autoParams[autoCount][1], (uint8_t)autoParams[autoCount][2], (uint32_t)autoParams[autoCount][3], (uint32_t)autoParams[autoCount][4], (uint32_t)autoParams[autoCount][5]); + DBG_OUTPUT_PORT.printf("autoTick[%d]: {0x%08x, 0x%08x, 0x%08x, %d, %d, %d}\r\n", autoCount, autoParams[autoCount][0], autoParams[autoCount][1], autoParams[autoCount][2], autoParams[autoCount][3], autoParams[autoCount][4], autoParams[autoCount][5]); autoCount++; if (autoCount >= (sizeof(autoParams) / sizeof(autoParams[0]))) autoCount = 0; @@ -1506,7 +1514,6 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght #endif #endif - // *************************************************************************** // Button management // *************************************************************************** @@ -1515,7 +1522,6 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght DBG_OUTPUT_PORT.printf("Short button press\r\n"); if (mode == OFF) { setModeByStateString(BTN_MODE_SHORT); - prevmode = mode; mode = SET_ALL; } else { mode = OFF; @@ -1526,7 +1532,6 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght void mediumKeyPress() { DBG_OUTPUT_PORT.printf("Medium button press\r\n"); setModeByStateString(BTN_MODE_MEDIUM); - prevmode = mode; mode = SET_ALL; } @@ -1534,7 +1539,6 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght void longKeyPress() { DBG_OUTPUT_PORT.printf("Long button press\r\n"); setModeByStateString(BTN_MODE_LONG); - prevmode = mode; mode = SET_ALL; } @@ -1579,9 +1583,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght tcs.getData(&r, &g, &b, &col, &conf); DBG_OUTPUT_PORT.printf("Colors: R: [%d] G: [%d] B: [%d] Color: [%d] Conf: [%d]\r\n", (int)r, (int)g, (int)b, (int)col, (int)conf); main_color.red = (pow((r/255.0), GAMMA)*255); main_color.green = (pow((g/255.0), GAMMA)*255); main_color.blue = (pow((b/255.0), GAMMA)*255);main_color.white = 0; - ws2812fx_mode = FX_MODE_STATIC; - prevmode = HOLD; - mode = SET_ALL; + mode = SET_COLOR; } // called when button is kept pressed for less than 2 seconds @@ -1726,7 +1728,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght checkRGBOrder(tmp_rgbOrder); uint8_t temp_pin; checkPin((uint8_t) root["ws_pin"]); - WS2812FXStripSettings.fxoptions = constrain(root["ws_fxopt"].as(), 0, 255) && 0xFE; + WS2812FXStripSettings.fxoptions = constrain(root["ws_fxopt"].as(), 0, 255) & 0xFE; jsonBuffer.clear(); return true; } else { @@ -2122,3 +2124,17 @@ void handleRemote() { } } #endif + +uint32_t scale_wrgb(uint32_t wrgb, uint8_t level) { + uint8_t w = ((wrgb >> 24) & 0xFF) * level / 255; + uint8_t r = ((wrgb >> 16) & 0xFF) * level / 255; + uint8_t g = ((wrgb >> 8) & 0xFF) * level / 255; + uint8_t b = ((wrgb) & 0xFF) * level / 255; + return (w << 24) | (r << 16) | (g << 8) | b; +} + +uint32_t fade(uint32_t newcolor, uint32_t oldcolor, uint8_t level) { + newcolor = scale_wrgb(newcolor, level); + oldcolor = scale_wrgb(oldcolor, 255-level); + return newcolor + oldcolor; +} diff --git a/Arduino/McLighting/version.h b/Arduino/McLighting/version.h index c1cb01b..abbd427 100644 --- a/Arduino/McLighting/version.h +++ b/Arduino/McLighting/version.h @@ -1 +1 @@ -#define SKETCH_VERSION "2.2.6.RU1.rgbw.3c" +#define SKETCH_VERSION "2.2.7.BETA1.rgbw.3c" diff --git a/Arduino/McLighting/version_info.ino b/Arduino/McLighting/version_info.ino index a74007e..6ecfc3b 100644 --- a/Arduino/McLighting/version_info.ino +++ b/Arduino/McLighting/version_info.ino @@ -165,4 +165,11 @@ * adressed issue: #31 * adressed issue: #32 * + * 15 September 2019 + * Version Bump to 2.2.7.BETA1.rgbw.3colors + * adressed issue: #25 (added Custom Animation 'Gradient') + * adressed issue: #30 (Status 'AUTO' is saved now) + * adressed issue: https://github.com/toblum/McLighting/issues/403 (Experimental Support of transitions: set fadeEffect = true in definitions.h) + * corrected use of DMA for Neopixelbus by Makuna (Tests for other strips than SK6812 GRBW were not made) + * */ diff --git a/README.md b/README.md index 4fd2dcf..17d3c82 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # McLighting v2 - The ESP8266 based multi-client lighting gadget -[![Gitter](https://badges.gitter.im/mclighting/Lobby.svg)](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Build Status](https://travis-ci.com/toblum/McLighting.svg?branch=master)](https://travis-ci.com/toblum/McLighting) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![version](https://img.shields.io/badge/version-v2.2.4-blue.svg)](https://github.com/toblum/McLighting/blob/master/Arduino/McLighting/version.h) +[![Gitter](https://badges.gitter.im/mclighting/Lobby.svg)](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Build Status](https://travis-ci.com/toblum/McLighting.svg?branch=master)](https://travis-ci.com/toblum/McLighting) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![version](https://img.shields.io/badge/version-v2.2.7-blue.svg)](https://github.com/toblum/McLighting/blob/master/Arduino/McLighting/version.h) McLighting (the multi-client lighting gadget) is a very cheap internet-controllable lighting solution based on the famous ESP8266 microcontroller and WS2811/2812 led strips. It features among other things a web-interface, a REST-API and a websocket connector. @@ -61,17 +61,20 @@ I hope I didn't miss any sources and mentioned every author. In case I forgot so ## Todos - [ ] Support multiple strips and control them separately or together [Issue](https://github.com/toblum/McLighting/issues/118) -- [ ] Make number of pixels, MQTT and PIN configurable via front end [Issue](https://github.com/toblum/McLighting/issues/93) and [Issue](https://github.com/toblum/McLighting/issues/93) -- [ ] Bundle webpages instead of SPIFFS [Issue](https://github.com/toblum/McLighting/issues/93) - [ ] Remove old / wrong EEPROM settings completely [Issue] - [ ] Customer profile to define segments of (in)active areas on the strip [Issue](https://github.com/toblum/McLighting/issues/37) - [ ] Additional clients - [ ] If no wifi, at least enable button mode. - [ ] Also enable McLighting in Wifi AP mode. -- [ ] IR remote support [issue](https://github.com/toblum/McLightingUI/issues/3) - [ ] Multiple buttons/GPIO Inputs. [Issue](https://github.com/toblum/McLighting/issues/119) - [ ] Music visualizer / Bring back ArtNet [Issue](https://github.com/toblum/McLighting/issues/111) - [ ] Display version and parameters (Number of LEDs, definition settings, ..) in the web UI [Issue](https://github.com/toblum/McLighting/issues/150) +- [x] Save status: Added saving of status 'AUTO'. [Issue] https://github.com/FabLab-Luenen/McLighting/issues/30 +- [x] EXPERIMENTAL: Added transition feature on changing values of color brightness and speed. ATTENTION! Does not work proberly for all WS2812fx effects. +- [x] Added Custom Animation 'Gradient': [Issue] https://github.com/FabLab-Luenen/McLighting/issues/25 +- [x] Make number of pixels, MQTT and PIN configurable via front end [Issue](https://github.com/toblum/McLighting/issues/93) and [Issue](https://github.com/toblum/McLighting/issues/93) +- [x] Bundle webpages instead of SPIFFS [Issue](https://github.com/toblum/McLighting/issues/93) +- [x] IR remote support [issue](https://github.com/toblum/McLightingUI/issues/3) - [x] MQTT support - [x] Save favourite effects? [Issue](https://github.com/toblum/McLighting/issues/35)(https://github.com/toblum/McLighting/issues/101) - [x] OTA update [Issue](https://github.com/toblum/McLighting/issues/92) @@ -95,4 +98,4 @@ I hope I didn't miss any sources and mentioned every author. In case I forgot so You use this project at your own risk. This is not a solution that should be used in productive environments, but this code and guide could give you a quick start for your own experiments. Please keep also in mind that there are currently some security features missing. -*More information will be added as soon as I clean up the code and complete documentation.* +*More information will be added as soon as I clean up the code and complete documentation.* \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 5803450..53a6bb4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,6 +25,8 @@ description = The ESP8266 based multi-client lighting gadget # arduino core 2.4.1 = platformIO 1.7.3 # arduino core 2.4.2 = platformIO 1.8.0 # arduino core 2.5.0 = platformIO 2.0.4 +# arduino core 2.5.1 = platformIO 2.1.1 +# arduino core 2.5.2 = platformIO 2.2.3 # arduino core stage = platformIO feature#stage # ------------------------------------------------------------------------------ arduino_core_2_3_0 = espressif8266@1.5.0 @@ -33,7 +35,7 @@ arduino_core_2_4_1 = espressif8266@1.7.3 arduino_core_2_4_2 = espressif8266@1.8.0 arduino_core_2_5_0 = espressif8266@2.0.4 arduino_core_2_5_1 = espressif8266@2.1.1 -arduino_core_2_5_2 = espressif8266@2.2.0 +arduino_core_2_5_2 = espressif8266@2.2.3 arduino_core_stage = https://github.com/platformio/platform-espressif8266.git#feature/stage framework = arduino