diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 1b8115d28..2e31ff08d 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -477,6 +477,7 @@ #define D_CMND_FADE "Fade" #define D_CMND_PALETTE "Palette" #define D_CMND_PIXELS "Pixels" +#define D_CMND_STEPPIXELS "StepPixels" #define D_CMND_RGBWWTABLE "RGBWWTable" #define D_CMND_ROTATION "Rotation" #define D_CMND_SCHEME "Scheme" diff --git a/tasmota/settings.h b/tasmota/settings.h index 0cde278e9..99a226cba 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -739,8 +739,9 @@ typedef struct { uint16_t shd_warmup_brightness; // F5C uint8_t shd_warmup_time; // F5E uint8_t tcp_config; // F5F + uint8_t light_step_pixels; // F60 - uint8_t free_f60[60]; // F60 - Decrement if adding new Setting variables just above and below + uint8_t free_f59[59]; // F61 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below diff --git a/tasmota/xlgt_01_ws2812.ino b/tasmota/xlgt_01_ws2812.ino index a7e7c9927..e0030dcb8 100644 --- a/tasmota/xlgt_01_ws2812.ino +++ b/tasmota/xlgt_01_ws2812.ino @@ -37,13 +37,13 @@ #define XLGT_01 1 -const uint8_t WS2812_SCHEMES = 8; // Number of WS2812 schemes +const uint8_t WS2812_SCHEMES = 9; // Number of WS2812 schemes const char kWs2812Commands[] PROGMEM = "|" // No prefix - D_CMND_LED "|" D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_WIDTH ; + D_CMND_LED "|" D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_WIDTH "|" D_CMND_STEPPIXELS ; void (* const Ws2812Command[])(void) PROGMEM = { - &CmndLed, &CmndPixels, &CmndRotation, &CmndWidth }; + &CmndLed, &CmndPixels, &CmndRotation, &CmndWidth, &CmndStepPixels }; #include @@ -166,6 +166,7 @@ WsColor kHanukkah[2] = { 0,0,255, 255,255,255 }; WsColor kwanzaa[3] = { 255,0,0, 0,0,0, 0,255,0 }; WsColor kRainbow[7] = { 255,0,0, 255,128,0, 255,255,0, 0,255,0, 0,0,255, 128,0,255, 255,0,255 }; WsColor kFire[3] = { 255,0,0, 255,102,0, 255,192,0 }; +WsColor kStairs[2] = { 0,0,0, 255,255,255 }; ColorScheme kSchemes[WS2812_SCHEMES -1] = { // Skip clock scheme kIncandescent, 2, kRgb, 3, @@ -173,7 +174,8 @@ ColorScheme kSchemes[WS2812_SCHEMES -1] = { // Skip clock scheme kHanukkah, 2, kwanzaa, 3, kRainbow, 7, - kFire, 3 }; + kFire, 3, + kStairs, 2 }; uint8_t kWidth[5] = { 1, // Small @@ -399,6 +401,96 @@ void Ws2812Bars(uint32_t schemenr) Ws2812StripShow(); } +void Ws2812Steps(uint32_t schemenr) +{ +#if (USE_WS2812_CTYPE > NEO_3LED) + RgbwColor c; + c.W = 0; +#else + RgbColor c; +#endif + + ColorScheme scheme = kSchemes[schemenr]; + // apply main color if current sheme == kStairs + if(scheme.colors == kStairs){ + scheme.colors[1].red = Settings->light_color[0]; + scheme.colors[1].green = Settings->light_color[1]; + scheme.colors[1].blue = Settings->light_color[2]; + } + uint8_t scheme_count=scheme.count; + + if(Settings->light_fade){ + scheme_count=Settings->ws_width[WS_HOUR];//Width4 + } + + WsColor mcolor[scheme_count]; + uint8_t color_start=0; + uint8_t color_end=1; + + if(Settings->light_rotation & 0x01){ + color_start=1; + color_end=0; + } + + if(Settings->light_fade){ + // generate gradient (width = Width4) + for(uint32_t i=1; i < scheme_count - 1; i++){ + mcolor[i].red = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].red, scheme.colors[color_end].red); + mcolor[i].green = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].green, scheme.colors[color_end].green); + mcolor[i].blue = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].blue, scheme.colors[color_end].blue); + } + } else { + memcpy(mcolor, scheme.colors, sizeof(mcolor)); + } + // repair first & last color in gradient; apply scheme rotation if fade==0 + mcolor[0].red=scheme.colors[color_start].red; + mcolor[0].green=scheme.colors[color_start].green; + mcolor[0].blue=scheme.colors[color_start].blue; + mcolor[scheme_count-1].red=scheme.colors[color_end].red; + mcolor[scheme_count-1].green=scheme.colors[color_end].green; + mcolor[scheme_count-1].blue=scheme.colors[color_end].blue; + + + // Adjust to dimmer value + float dimmer = 100 / (float)Settings->light_dimmer; + for (uint32_t i = 0; i < scheme_count; i++) { + float fmyRed = (float)mcolor[i].red / dimmer; + float fmyGrn = (float)mcolor[i].green / dimmer; + float fmyBlu = (float)mcolor[i].blue / dimmer; + mcolor[i].red = (uint8_t)fmyRed; + mcolor[i].green = (uint8_t)fmyGrn; + mcolor[i].blue = (uint8_t)fmyBlu; + } + + uint32_t speed = Settings->light_speed; + int32_t current_position = Light.strip_timer_counter / speed; + + //all pixels are shown already | rotation change will not change current state + if(current_position > Settings->light_pixels / Settings->light_step_pixels + scheme_count ) { + return; + } + + int32_t colorIndex; + int32_t step_nr; + + for (uint32_t i = 0; i < Settings->light_pixels; i++) { + step_nr = i / Settings->light_step_pixels; + colorIndex = current_position - step_nr; + if(colorIndex < 0) colorIndex = 0; + if(colorIndex > scheme_count - 1) colorIndex = scheme_count - 1; + c.R = mcolor[colorIndex].red; + c.G = mcolor[colorIndex].green; + c.B = mcolor[colorIndex].blue; + // Adjust the scheme rotation + if(Settings->light_rotation & 0x02){ + strip->SetPixelColor(Settings->light_pixels - i - 1, c); + } else { + strip->SetPixelColor(i, c); + } + } + Ws2812StripShow(); +} + void Ws2812Clear(void) { strip->ClearTo(0); @@ -496,10 +588,14 @@ void Ws2812ShowScheme(void) } break; default: - if (1 == Settings->light_fade) { - Ws2812Gradient(scheme -1); - } else { - Ws2812Bars(scheme -1); + if(Settings->light_step_pixels > 0){ + Ws2812Steps(scheme -1); + } else { + if (1 == Settings->light_fade) { + Ws2812Gradient(scheme -1); + } else { + Ws2812Bars(scheme -1); + } } Ws2812.show_next = 1; break; @@ -568,6 +664,17 @@ void CmndPixels(void) ResponseCmndNumber(Settings->light_pixels); } +void CmndStepPixels(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= WS2812_MAX_LEDS)) { + Settings->light_step_pixels = XdrvMailbox.payload; + Ws2812Clear(); + Light.update = true; + } + ResponseCmndNumber(Settings->light_step_pixels); +} + + void CmndRotation(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < Settings->light_pixels)) {