Aply a mask to segments
romses opened this issue · comments
Christopher Kreitz commented
Is there a way, to apply a bitmask to effects, so that masked pixels do not get turned on?
e.g.
Mask: 000011110000
Effect: EEEEEEEEEEEE
Out: 0000EEEE0000
Keith Lord commented
I modified the ws2812fx_overlay example sketch to perform the masking function. It uses the same idea of using a virtual strip (to run the animation) and a physical strip (to drive the LED strip), and the custom show() function does the masking.
#include <WS2812FX.h>
#define LED_PIN 14
#define LED_COUNT 144
WS2812FX ws2812fx_v = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800,1,1);
WS2812FX ws2812fx_p = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800,1,1);
bool mask[LED_COUNT];
void setup() {
// Initialize the virtual strip
ws2812fx_v.init();
ws2812fx_v.setBrightness(64);
ws2812fx_v.setSegment(0, 0, LED_COUNT-1, FX_MODE_RAINBOW_CYCLE, BLACK, 1000);
ws2812fx_v.start();
// Config custom show() function for the virtual strip
ws2812fx_v.setCustomShow(myCustomShow);
/* Initialize the LED mask */
for(int i=0; i<LED_COUNT; i++) {
if(i & 1) {
mask[i] = true; // mask even LEDs
} else {
mask[i] = false; // unmask odd LEDs
}
}
// Initialize the physical strip last
ws2812fx_p.init();
}
void loop() {
// Run effects only on the virtual strip
ws2812fx_v.service();
}
// The custom show() function masks the virtual strip data
// and copies it to the physical strip
void myCustomShow(void) {
// get pointers to all the pixel data arrays
uint8_t *pixels_v = ws2812fx_v.getPixels();
uint8_t *pixels_p = ws2812fx_p.getPixels();
// copy the masked virtual LED data to the physical strip
for (uint16_t i=0; i < LED_COUNT; i++) {
uint16_t pindex = i * 3; // index into the pixel arrays
if(mask[i]) {
memmove(&pixels_p[pindex], &pixels_v[pindex], 3); // copy 3 bytes
} else {
memset(&pixels_p[pindex], 0, 3); // set 3 bytes to zero (BLACK)
}
}
// Call the physical strip's show() function.
ws2812fx_p.Adafruit_NeoPixel::show();
}