diff --git a/README.md b/README.md index 716cda074..cbf0eb4e7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **5.9.1b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. +Current version is **5.9.1c** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index dffc8a805..c8ecde0f0 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,6 +1,9 @@ -/* 5.9.1b +/* 5.9.1c + * Add support for WS2812 RGBW ledstrips to be enabled in user_config.h with define USE_WS2812_CTYPE (#1156) + * + * 5.9.1b * Remove spaces in JSON messages - * Add support for INA219 Voltage and Current sensor to be enabled in user_config.h + * Add support for INA219 Voltage and Current sensor to be enabled in user_config.h with define USE_INA219 * * 5.9.1a * Fix PWM watchdog timeout if Dimmer is set to 100 or Color set to 0xFF (#1146) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 70aed3b2a..281beef8d 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x05090102 // 5.9.1b +#define VERSION 0x05090103 // 5.9.1c // Location specific includes #include "sonoff.h" // Enumaration used in user_config.h diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 7e7764d96..20bc22435 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -179,7 +179,7 @@ #define USE_IR_RECEIVE // Support for IR receiver (+4k code) #define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+5k code, +1k mem) - Disable by // - #define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB) + #define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB, 2 - RGBW, 3 - GRBW) // #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow /*********************************************************************************************\ diff --git a/sonoff/xdrv_snfled.ino b/sonoff/xdrv_snfled.ino index 2731892a4..a57074dfd 100644 --- a/sonoff/xdrv_snfled.ino +++ b/sonoff/xdrv_snfled.ino @@ -29,7 +29,7 @@ * 5 PWM5 RGBCW yes (H801, Arilux) * 9 reserved no * 10 reserved yes - * 11 +WS2812 RGB no + * 11 +WS2812 RGB(W) no (One WS2812 RGB or RGBW ledstrip) * 12 AiLight RGBW no * 13 Sonoff B1 RGBCW yes * @@ -174,6 +174,8 @@ void LightInit(void) { uint8_t max_scheme = LS_MAX -1; + light_subtype = light_type &7; + if (light_type < LT_PWM6) { // PWM for (byte i = 0; i < light_type; i++) { Settings.pwm_value[i] = 0; // Disable direct PWM control @@ -198,6 +200,9 @@ void LightInit(void) } #ifdef USE_WS2812 // ************************************************************************ else if (LT_WS2812 == light_type) { +#if (USE_WS2812_CTYPE > 1) + light_subtype++; // from RGB to RGBW +#endif Ws2812Init(); max_scheme = LS_MAX +7; } @@ -214,7 +219,6 @@ void LightInit(void) LightMy92x1Init(); } - light_subtype = light_type &7; if (light_subtype < LST_RGB) { max_scheme = LS_POWER; } @@ -539,7 +543,7 @@ void LightAnimate() } #ifdef USE_WS2812 // ************************************************************************ if (LT_WS2812 == light_type) { - Ws2812SetColor(0, cur_col[0], cur_col[1], cur_col[2]); + Ws2812SetColor(0, cur_col[0], cur_col[1], cur_col[2], cur_col[3]); } #endif // USE_ES2812 ************************************************************************ if (light_type > LT_WS2812) { @@ -800,7 +804,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le else if ((CMND_LED == command_code) && (LT_WS2812 == light_type) && (index > 0) && (index <= Settings.light_pixels)) { if (data_len > 0) { if (LightColorEntry(dataBuf, data_len)) { - Ws2812SetColor(index, light_entry_color[0], light_entry_color[1], light_entry_color[2]); + Ws2812SetColor(index, light_entry_color[0], light_entry_color[1], light_entry_color[2], light_entry_color[3]); } } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Ws2812GetColor(index, scolor)); diff --git a/sonoff/xdrv_ws2812.ino b/sonoff/xdrv_ws2812.ino index 5cac3011e..6e3edffbb 100644 --- a/sonoff/xdrv_ws2812.ino +++ b/sonoff/xdrv_ws2812.ino @@ -19,7 +19,7 @@ #ifdef USE_WS2812 /*********************************************************************************************\ - * WS2812 Leds using NeopixelBus library + * WS2812 RGB / RGBW Leds using NeopixelBus library \*********************************************************************************************/ #include @@ -27,13 +27,21 @@ #ifdef USE_WS2812_DMA #if (USE_WS2812_CTYPE == 1) NeoPixelBus *strip = NULL; -#else // USE_WS2812_CTYPE +#elif (USE_WS2812_CTYPE == 2) + NeoPixelBus *strip = NULL; +#elif (USE_WS2812_CTYPE == 3) + NeoPixelBus *strip = NULL; +#else // USE_WS2812_CTYPE NeoPixelBus *strip = NULL; #endif // USE_WS2812_CTYPE -#else // USE_WS2812_DMA +#else // USE_WS2812_DMA #if (USE_WS2812_CTYPE == 1) NeoPixelBus *strip = NULL; -#else // USE_WS2812_CTYPE +#elif (USE_WS2812_CTYPE == 2) + NeoPixelBus *strip = NULL; +#elif (USE_WS2812_CTYPE == 3) + NeoPixelBus *strip = NULL; +#else // USE_WS2812_CTYPE NeoPixelBus *strip = NULL; #endif // USE_WS2812_CTYPE #endif // USE_WS2812_DMA @@ -82,12 +90,22 @@ uint8_t ws_show_next = 1; void Ws2812StripShow() { +#if (USE_WS2812_CTYPE > 1) + RgbwColor c; +#else RgbColor c; +#endif if (Settings.light_correction) { for (uint16_t i = 0; i < Settings.light_pixels; i++) { c = strip->GetPixelColor(i); - strip->SetPixelColor(i, RgbColor(ledTable[c.R], ledTable[c.G], ledTable[c.B])); + c.R = ledTable[c.R]; + c.G = ledTable[c.G]; + c.B = ledTable[c.B]; +#if (USE_WS2812_CTYPE > 1) + c.W = ledTable[c.W]; +#endif + strip->SetPixelColor(i, c); } } strip->Show(); @@ -104,18 +122,22 @@ int mod(int a, int b) #define cmin(a,b) ((a)<(b)?(a):(b)) -void Ws2812UpdatePixelColor(int position, struct RgbColor hand_color, uint8_t hand) +void Ws2812UpdatePixelColor(int position, struct WsColor hand_color, uint8_t hand) { +#if (USE_WS2812_CTYPE > 1) + RgbwColor color; +#else RgbColor color; +#endif uint16_t mod_position = mod(position, (int)Settings.light_pixels); color = strip->GetPixelColor(mod_position); float dimmer = 100 / (float)Settings.light_dimmer; uint8_t offset = 1 << hand; - color.R = cmin(color.R + ((hand_color.R / dimmer) / offset), 255); - color.G = cmin(color.G + ((hand_color.G / dimmer) / offset), 255); - color.B = cmin(color.B + ((hand_color.B / dimmer) / offset), 255); + color.R = cmin(color.R + ((hand_color.red / dimmer) / offset), 255); + color.G = cmin(color.G + ((hand_color.green / dimmer) / offset), 255); + color.B = cmin(color.B + ((hand_color.blue / dimmer) / offset), 255); strip->SetPixelColor(mod_position, color); } @@ -124,7 +146,7 @@ void Ws2812UpdateHand(int position, uint8_t index) if (Settings.flag.ws_clock_reverse) { position = Settings.light_pixels -position; } - RgbColor hand_color = RgbColor(Settings.ws_color[index][WS_RED], Settings.ws_color[index][WS_GREEN], Settings.ws_color[index][WS_BLUE]); + WsColor hand_color = { Settings.ws_color[index][WS_RED], Settings.ws_color[index][WS_GREEN], Settings.ws_color[index][WS_BLUE] }; Ws2812UpdatePixelColor(position, hand_color, 0); for (uint8_t h = 1; h <= ((Settings.ws_width[index] -1) / 2); h++) { @@ -139,7 +161,6 @@ void Ws2812Clock() int clksize = 600 / (int)Settings.light_pixels; Ws2812UpdateHand((RtcTime.second * 10) / clksize, WS_SECOND); Ws2812UpdateHand((RtcTime.minute * 10) / clksize, WS_MINUTE); -// Ws2812UpdateHand((RtcTime.hour % 12) * (50 / clksize), WS_HOUR); Ws2812UpdateHand(((RtcTime.hour % 12) * (50 / clksize)) + ((RtcTime.minute * 10) / (12 * clksize)), WS_HOUR); Ws2812StripShow(); @@ -177,7 +198,12 @@ void Ws2812Gradient(uint8_t schemenr) * Display a gradient of colors for the current color scheme. * Repeat is the number of repetitions of the gradient (pick a multiple of 2 for smooth looping of the gradient). */ +#if (USE_WS2812_CTYPE > 1) + RgbwColor c; + c.W = 0; +#else RgbColor c; +#endif ColorScheme scheme = kSchemes[schemenr]; if (scheme.count < 2) { @@ -222,7 +248,12 @@ void Ws2812Bars(uint8_t schemenr) * Display solid bars of color for the current color scheme. * Width is the width of each bar in pixels/lights. */ +#if (USE_WS2812_CTYPE > 1) + RgbwColor c; + c.W = 0; +#else RgbColor c; +#endif uint16_t i; ColorScheme scheme = kSchemes[schemenr]; @@ -268,12 +299,20 @@ void Ws2812Init() #ifdef USE_WS2812_DMA #if (USE_WS2812_CTYPE == 1) strip = new NeoPixelBus(WS2812_MAX_LEDS); // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use. +#elif (USE_WS2812_CTYPE == 2) + strip = new NeoPixelBus(WS2812_MAX_LEDS); // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use. +#elif (USE_WS2812_CTYPE == 3) + strip = new NeoPixelBus(WS2812_MAX_LEDS); // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use. #else // USE_WS2812_CTYPE strip = new NeoPixelBus(WS2812_MAX_LEDS); // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use. #endif // USE_WS2812_CTYPE #else // USE_WS2812_DMA #if (USE_WS2812_CTYPE == 1) strip = new NeoPixelBus(WS2812_MAX_LEDS, pin[GPIO_WS2812]); +#elif (USE_WS2812_CTYPE == 2) + strip = new NeoPixelBus(WS2812_MAX_LEDS, pin[GPIO_WS2812]); +#elif (USE_WS2812_CTYPE == 3) + strip = new NeoPixelBus(WS2812_MAX_LEDS, pin[GPIO_WS2812]); #else // USE_WS2812_CTYPE strip = new NeoPixelBus(WS2812_MAX_LEDS, pin[GPIO_WS2812]); #endif // USE_WS2812_CTYPE @@ -289,9 +328,15 @@ void Ws2812Clear() ws_show_next = 1; } -void Ws2812SetColor(uint16_t led, uint8_t red, uint8_t green, uint8_t blue) +void Ws2812SetColor(uint16_t led, uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { +#if (USE_WS2812_CTYPE > 1) + RgbwColor lcolor; + lcolor.W = white; +#else RgbColor lcolor; +#endif + lcolor.R = red; lcolor.G = green; lcolor.B = blue; @@ -309,14 +354,19 @@ void Ws2812SetColor(uint16_t led, uint8_t red, uint8_t green, uint8_t blue) char* Ws2812GetColor(uint16_t led, char* scolor) { - uint8_t sl_ledcolor[3]; + uint8_t sl_ledcolor[4]; + #if (USE_WS2812_CTYPE > 1) + RgbwColor lcolor = strip->GetPixelColor(led -1); + sl_ledcolor[3] = lcolor.W; + #else RgbColor lcolor = strip->GetPixelColor(led -1); + #endif sl_ledcolor[0] = lcolor.R; sl_ledcolor[1] = lcolor.G; sl_ledcolor[2] = lcolor.B; scolor[0] = '\0'; - for (byte i = 0; i < 3; i++) { + for (byte i = 0; i < light_subtype; i++) { if (Settings.flag.decimal_text) { snprintf_P(scolor, 25, PSTR("%s%s%d"), scolor, (i > 0) ? "," : "", sl_ledcolor[i]); } else {