Merge pull request #13595 from kruzer/stairs-pixels

Add simple stairs effects to ws2812 driver
This commit is contained in:
Theo Arends 2021-11-18 09:13:13 +01:00 committed by GitHub
commit dbec7712ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 118 additions and 9 deletions

View File

@ -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"

View File

@ -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

View File

@ -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 <NeoPixelBus.h>
@ -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)) {