Switching patterns by button presses
neopolygnath opened this issue · comments
Hello, found the WS2812FX library recently as I'm working on a lighting project that would require me to switch between complex segment patterns by pushing two buttons. I'm not a programmer and unsure if WS2812FX is even adaptable for my scenario. My issue:
I have two to patterns with two modes that I want to modify by button presses. I'm not a programmer myself (sadly) but I try to describe what I want to achieve and maybe someone here can help me with an example or give some hints:
Pressing the first button is intended to switch between the main patterns 1 and 2. Patterns 3 and 4 are color inverted versions of the two main patterns. So pressing the second button is intended to switch between patterns 1 and 3 and 2 and 4 (depending upon the previously selected pattern). To my understanding I would have to stop, swap and then re-initialize the activated pattern by "ws2812fx.start();". Is it even technically possible with the library (or could another library be more helpful here)? My patterns look like the following:
Pattern 1:
ws2812fx.init();
//ws2812fx.setBrightness(200);
// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx.setSegment(0, 0, 9, FX_MODE_FIRE_FLICKER, 0xFF0000, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(1, 10, 19, FX_MODE_BLINK, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(2, 20, 29, FX_MODE_FIRE_FLICKER, 0x00FF00, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(3, 30, 39, FX_MODE_BLINK, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(4, 40, 49, FX_MODE_FIRE_FLICKER, 0x0000FF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.start();
}
Pattern 2:
ws2812fx.init();
//ws2812fx.setBrightness(200);
// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx.setSegment(0, 0, 9, FX_MODE_BLINK, 0xFF0000, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(1, 10, 19, FX_MODE_FIRE_FLICKER, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(2, 20, 29, FX_MODE_BLINK, 0x00FF00, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(3, 30, 39, FX_MODE_FIRE_FLICKER, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(4, 40, 49, FX_MODE_BLINK, 0x0000FF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.start();
}
Pattern 3:
ws2812fx.init();
//ws2812fx.setBrightness(200);
// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx.setSegment(0, 0, 9, FX_MODE_FIRE_FLICKER, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(1, 10, 19, FX_MODE_BLINK, 0xFF0000, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(2, 20, 29, FX_MODE_FIRE_FLICKER, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(3, 30, 39, FX_MODE_BLINK, 0x00FF00, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(4, 40, 49, FX_MODE_FIRE_FLICKER, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.start();
}
Pattern 4:
ws2812fx.init();
//ws2812fx.setBrightness(200);
// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx.setSegment(0, 0, 9, FX_MODE_BLINK, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(1, 10, 19, FX_MODE_FIRE_FLICKER, 0xFF0000, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(2, 20, 29, FX_MODE_BLINK, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(3, 30, 39, FX_MODE_FIRE_FLICKER, 0x00FF00, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.setSegment(4, 40, 49, FX_MODE_BLINK, 0xFFFFFF, 1000, false); // segment 0 is leds 0 - 9
ws2812fx.start();
}
Seems like you're using button1 to change the effect of each segment, and button2 to change the color of each segment. You don't need to reconfigure each segment whenever a button is pressed. You can just use setSegment() to initialize the segments, then use setMode() and setColor() to update the segments in response to a button press. This is what I came up with:
#include <WS2812FX.h>
#define LED_PIN D2 // digital pin used to drive the LED strip
#define LED_COUNT 50 // number of LEDs on the strip
#define BUTTON1_PIN D0 // digital pin for button 1
#define BUTTON2_PIN D1 // digital pin for button 2
boolean button1 = HIGH; // initial state of the buttons
boolean button2 = HIGH;
boolean modeState = false; // initial state of the effect mode
boolean colorState = false; // initial state of the color palette
WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
delay(500);
pinMode(BUTTON1_PIN, INPUT_PULLUP); // config buttons as inputs with pullup resistors
pinMode(BUTTON2_PIN, INPUT_PULLUP);
ws2812fx.init();
ws2812fx.setBrightness(128);
// parameters: index, start, stop, mode, color, speed, reverse
ws2812fx.setSegment(0, 0, 9, FX_MODE_FIRE_FLICKER, RED, 1000, false);
ws2812fx.setSegment(1, 10, 19, FX_MODE_BLINK, WHITE, 1000, false);
ws2812fx.setSegment(2, 20, 29, FX_MODE_FIRE_FLICKER, GREEN, 1000, false);
ws2812fx.setSegment(3, 30, 39, FX_MODE_BLINK, WHITE, 1000, false);
ws2812fx.setSegment(4, 40, 49, FX_MODE_FIRE_FLICKER, BLUE, 1000, false);
ws2812fx.start();
}
void loop() {
ws2812fx.service();
// Check button 1 (controls the effect mode)
boolean newState = digitalRead(BUTTON1_PIN);
if((newState == LOW) && (button1 == HIGH)) { // button 1 toggled high to low
if(modeState) {
ws2812fx.setMode(0, FX_MODE_FIRE_FLICKER);
ws2812fx.setMode(1, FX_MODE_BLINK);
ws2812fx.setMode(2, FX_MODE_FIRE_FLICKER);
ws2812fx.setMode(3, FX_MODE_BLINK);
ws2812fx.setMode(4, FX_MODE_FIRE_FLICKER);
} else {
ws2812fx.setMode(0, FX_MODE_BLINK);
ws2812fx.setMode(1, FX_MODE_FIRE_FLICKER);
ws2812fx.setMode(2, FX_MODE_BLINK);
ws2812fx.setMode(3, FX_MODE_FIRE_FLICKER);
ws2812fx.setMode(4, FX_MODE_BLINK);
}
modeState = !modeState;
}
button1 = newState;
// Check button 2 (controls the color scheme)
newState = digitalRead(BUTTON2_PIN);
if((newState == LOW) && (button2 == HIGH)) { // button 2 toggled high to low
if(colorState) {
ws2812fx.setColor(0, RED);
ws2812fx.setColor(1, WHITE);
ws2812fx.setColor(2, GREEN);
ws2812fx.setColor(3, WHITE);
ws2812fx.setColor(4, BLUE);
} else {
ws2812fx.setColor(0, WHITE);
ws2812fx.setColor(1, RED);
ws2812fx.setColor(2, WHITE);
ws2812fx.setColor(3, GREEN);
ws2812fx.setColor(4, WHITE);
}
colorState = !colorState;
}
button2 = newState;
}
Wow, that was fast (and it's working like a charm). Many thanks for your input and your example :-) It depicts capabilities of this library I had not even thought possible. Especially the solution to decouple the segment description from the rest and your way to set the modes and colors - that's just elegant - I raise my virtual hat to your programming skills. Thank you and best wishes