diff --git a/wled00/WS2812FX.cpp b/wled00/WS2812FX.cpp new file mode 100644 index 00000000..dbb8cd1f --- /dev/null +++ b/wled00/WS2812FX.cpp @@ -0,0 +1,1221 @@ +/* + WS2812FX.cpp - Library for WS2812 LED effects. + Harm Aldick - 2016 + www.aldick.org + FEATURES + * A lot of blinken modes and counting + * WS2812FX can be used as drop-in replacement for Adafruit Neopixel Library + NOTES + * Uses the Adafruit Neopixel library. Get it here: + https://github.com/adafruit/Adafruit_NeoPixel + LICENSE + The MIT License (MIT) + Copyright (c) 2016 Harm Aldick + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + CHANGELOG + 2016-05-28 Initial beta release + 2016-06-03 Code cleanup, minor improvements, new modes + 2016-06-04 2 new fx, fixed setColor (now also resets _mode_color) +*/ + +#include "Arduino.h" +#include "WS2812FX.h" + +#define CALL_MODE(n) (this->*_mode[n])(); + +void WS2812FX::init() { + Adafruit_NeoPixel::begin(); + WS2812FX::setBrightness(_brightness); + Adafruit_NeoPixel::show(); +} + +void WS2812FX::service() { + if(_running) { + unsigned long now = millis(); + + if(now - _mode_last_call_time > _mode_delay) { + CALL_MODE(_mode_index); + _counter_mode_call++; + _mode_last_call_time = now; + } + } +} + +void WS2812FX::start() { + _counter_mode_call = 0; + _counter_mode_step = 0; + _mode_last_call_time = 0; + _running = true; +} + +void WS2812FX::stop() { + _running = false; + strip_off(); +} + +void WS2812FX::setMode(uint8_t m) { + _counter_mode_call = 0; + _counter_mode_step = 0; + _mode_last_call_time = 0; + _mode_index = constrain(m, 0, MODE_COUNT-1); + _mode_color = _color; + Adafruit_NeoPixel::setBrightness(_brightness); + strip_off(); +} + +void WS2812FX::setSpeed(uint8_t s) { + _counter_mode_call = 0; + _counter_mode_step = 0; + _mode_last_call_time = 0; + _speed = constrain(s, SPEED_MIN, SPEED_MAX); + strip_off(); +} + +void WS2812FX::increaseSpeed(uint8_t s) { + s = constrain(_speed + s, SPEED_MIN, SPEED_MAX); + setSpeed(s); +} + +void WS2812FX::decreaseSpeed(uint8_t s) { + s = constrain(_speed - s, SPEED_MIN, SPEED_MAX); + setSpeed(s); +} + +void WS2812FX::setColor(uint8_t r, uint8_t g, uint8_t b) { + setColor(((uint32_t)r << 16) | ((uint32_t)g << 8) | b); +} + +void WS2812FX::setColor(uint32_t c) { + _color = c; + _mode_color = _color; + Adafruit_NeoPixel::setBrightness(_brightness); +} + +void WS2812FX::setBrightness(uint8_t b) { + _brightness = constrain(b, BRIGHTNESS_MIN, BRIGHTNESS_MAX); + Adafruit_NeoPixel::setBrightness(_brightness); + Adafruit_NeoPixel::show(); +} + +void WS2812FX::increaseBrightness(uint8_t s) { + s = constrain(_brightness + s, BRIGHTNESS_MIN, BRIGHTNESS_MAX); + setBrightness(s); +} + +void WS2812FX::decreaseBrightness(uint8_t s) { + s = constrain(_brightness - s, BRIGHTNESS_MIN, BRIGHTNESS_MAX); + setBrightness(s); +} + +boolean WS2812FX::isRunning() { + return _running; +} + +uint8_t WS2812FX::getMode(void) { + return _mode_index; +} + +uint8_t WS2812FX::getSpeed(void) { + return _speed; +} + +uint8_t WS2812FX::getBrightness(void) { + return _brightness; +} + +uint8_t WS2812FX::getModeCount(void) { + return MODE_COUNT; +} + +uint32_t WS2812FX::getColor(void) { + return _color; +} + +const char* WS2812FX::getModeName(uint8_t m) { + if(m < MODE_COUNT) { + return _name[m]; + } else { + return ""; + } +} + +/* ##################################################### +# +# Color and Blinken Functions +# +##################################################### */ + +/* + * Turns everything off. Doh. + */ +void WS2812FX::strip_off() { + Adafruit_NeoPixel::clear(); + Adafruit_NeoPixel::show(); +} + + +/* + * Put a value 0 to 255 in to get a color value. + * The colours are a transition r -> g -> b -> back to r + * Inspired by the Adafruit examples. + */ +uint32_t WS2812FX::color_wheel(uint8_t pos) { + pos = 255 - pos; + if(pos < 85) { + return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3); + } else if(pos < 170) { + pos -= 85; + return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3); + } else { + pos -= 170; + return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0); + } +} + + +/* + * Returns a new, random wheel index with a minimum distance of 42 from pos. + */ +uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { + uint8_t r = 0; + uint8_t x = 0; + uint8_t y = 0; + uint8_t d = 0; + + while(d < 42) { + r = random(256); + x = abs(pos - r); + y = 255 - x; + d = min(x, y); + } + + return r; +} + + +/* + * No blinking. Just plain old static light. + */ +void WS2812FX::mode_static(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + Adafruit_NeoPixel::show(); + + _mode_delay = 50; +} + + +/* + * Normal blinking. 50% on/off time. + */ +void WS2812FX::mode_blink(void) { + if(_counter_mode_call % 2 == 1) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + Adafruit_NeoPixel::show(); + } else { + strip_off(); + } + + _mode_delay = 100 + ((1986 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Lights all LEDs after each other up. Then turns them in + * that order off. Repeat. + */ +void WS2812FX::mode_color_wipe(void) { + if(_counter_mode_step < _led_count) { + Adafruit_NeoPixel::setPixelColor(_counter_mode_step, _color); + } else { + Adafruit_NeoPixel::setPixelColor(_counter_mode_step - _led_count, 0); + } + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % (_led_count * 2); + + _mode_delay = 5 + ((50 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Turns all LEDs after each other to a random color. + * Then starts over with another color. + */ +void WS2812FX::mode_color_wipe_random(void) { + if(_counter_mode_step == 0) { + _mode_color = get_random_wheel_index(_mode_color); + } + + Adafruit_NeoPixel::setPixelColor(_counter_mode_step, color_wheel(_mode_color)); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + + _mode_delay = 5 + ((50 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Lights all LEDs in one random color up. Then switches them + * to the next random color. + */ +void WS2812FX::mode_random_color(void) { + _mode_color = get_random_wheel_index(_mode_color); + + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(_mode_color)); + } + + Adafruit_NeoPixel::show(); + _mode_delay = 100 + ((5000 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Lights every LED in a random color. Changes one random LED after the other + * to another random color. + */ +void WS2812FX::mode_single_dynamic(void) { + if(_counter_mode_call == 0) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(random(256))); + } + } + + Adafruit_NeoPixel::setPixelColor(random(_led_count), color_wheel(random(256))); + Adafruit_NeoPixel::show(); + _mode_delay = 10 + ((5000 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Lights every LED in a random color. Changes all LED at the same time + * to new random colors. + */ +void WS2812FX::mode_multi_dynamic(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(random(256))); + } + Adafruit_NeoPixel::show(); + _mode_delay = 100 + ((5000 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Does the "standby-breathing" of well known i-Devices. Fixed Speed. + * Use mode "fade" if you like to have something similar with a different speed. + */ +void WS2812FX::mode_breath(void) { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // step + uint16_t breath_delay_steps[] = { 7, 9, 13, 15, 16, 17, 18, 930, 19, 18, 15, 13, 9, 7, 4, 5, 10 }; // magic numbers for breathing LED + uint8_t breath_brightness_steps[] = { 150, 125, 100, 75, 50, 25, 16, 15, 16, 25, 50, 75, 100, 125, 150, 220, 255 }; // even more magic numbers! + + if(_counter_mode_call == 0) { + _mode_color = breath_brightness_steps[0] + 1; + } + + uint8_t breath_brightness = _mode_color; // we use _mode_color to store the brightness + + if(_counter_mode_step < 8) { + breath_brightness--; + } else { + breath_brightness++; + } + + // update index of current delay when target brightness is reached, start over after the last step + if(breath_brightness == breath_brightness_steps[_counter_mode_step]) { + _counter_mode_step = (_counter_mode_step + 1) % (sizeof(breath_brightness_steps)/sizeof(uint8_t)); + } + + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); // set all LEDs to selected color + } + int b = map(breath_brightness, 0, 255, 0, _brightness); // keep brightness below brightness set by user + Adafruit_NeoPixel::setBrightness(b); // set new brightness to leds + Adafruit_NeoPixel::show(); + + _mode_color = breath_brightness; // we use _mode_color to store the brightness + _mode_delay = breath_delay_steps[_counter_mode_step]; +} + + +/* + * Fades the LEDs on and (almost) off again. + */ +void WS2812FX::mode_fade(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + + int b = _counter_mode_step - 127; + b = 255 - (abs(b) * 2); + b = map(b, 0, 255, min(25, _brightness), _brightness); + Adafruit_NeoPixel::setBrightness(b); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % 256; + _mode_delay = 5 + ((15 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Runs a single pixel back and forth. + */ +void WS2812FX::mode_scan(void) { + if(_counter_mode_step > (_led_count*2) - 2) { + _counter_mode_step = 0; + } + _counter_mode_step++; + + int i = _counter_mode_step - (_led_count - 1); + i = abs(i); + + Adafruit_NeoPixel::clear(); + Adafruit_NeoPixel::setPixelColor(abs(i), _color); + Adafruit_NeoPixel::show(); + + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Runs two pixel back and forth in opposite directions. + */ +void WS2812FX::mode_dual_scan(void) { + if(_counter_mode_step > (_led_count*2) - 2) { + _counter_mode_step = 0; + } + _counter_mode_step++; + + int i = _counter_mode_step - (_led_count - 1); + i = abs(i); + + Adafruit_NeoPixel::clear(); + Adafruit_NeoPixel::setPixelColor(i, _color); + Adafruit_NeoPixel::setPixelColor(_led_count - (i+1), _color); + Adafruit_NeoPixel::show(); + + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Cycles all LEDs at once through a rainbow. + */ +void WS2812FX::mode_rainbow(void) { + uint32_t color = color_wheel(_counter_mode_step); + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color); + } + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % 256; + + _mode_delay = 1 + ((50 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Cycles a rainbow over the entire string of LEDs. + */ +void WS2812FX::mode_rainbow_cycle(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(((i * 256 / _led_count) + _counter_mode_step) % 256)); + } + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % 256; + + _mode_delay = 1 + ((50 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Theatre-style crawling lights. + * Inspired by the Adafruit examples. + */ +void WS2812FX::mode_theater_chase(void) { + uint8_t j = _counter_mode_call % 6; + if(j % 2 == 0) { + for(uint16_t i=0; i < _led_count; i=i+3) { + Adafruit_NeoPixel::setPixelColor(i+(j/2), _color); + } + Adafruit_NeoPixel::show(); + _mode_delay = 50 + ((500 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); + } else { + for(uint16_t i=0; i < _led_count; i=i+3) { + Adafruit_NeoPixel::setPixelColor(i+(j/2), 0); + } + _mode_delay = 1; + } +} + + +/* + * Theatre-style crawling lights with rainbow effect. + * Inspired by the Adafruit examples. + */ +void WS2812FX::mode_theater_chase_rainbow(void) { + uint8_t j = _counter_mode_call % 6; + if(j % 2 == 0) { + for(uint16_t i=0; i < _led_count; i=i+3) { + Adafruit_NeoPixel::setPixelColor(i+(j/2), color_wheel((i+_counter_mode_step) % 256)); + } + Adafruit_NeoPixel::show(); + _mode_delay = 50 + ((500 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); + } else { + for(uint16_t i=0; i < _led_count; i=i+3) { + Adafruit_NeoPixel::setPixelColor(i+(j/2), 0); + } + _mode_delay = 1; + } + _counter_mode_step = (_counter_mode_step + 1) % 256; +} + + +/* + * Running lights effect with smooth sine transition. + */ +void WS2812FX::mode_running_lights(void) { + uint8_t r = ((_color >> 16) & 0xFF); + uint8_t g = ((_color >> 8) & 0xFF); + uint8_t b = (_color & 0xFF); + + for(uint16_t i=0; i < _led_count; i++) { + int s = (sin(i+_counter_mode_call) * 127) + 128; + Adafruit_NeoPixel::setPixelColor(i, (((uint32_t)(r * s)) / 255), (((uint32_t)(g * s)) / 255), (((uint32_t)(b * s)) / 255)); + } + + Adafruit_NeoPixel::show(); + + _mode_delay = 35 + ((350 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Blink several LEDs on, reset, repeat. + * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ + */ +void WS2812FX::mode_twinkle(void) { + if(_counter_mode_step == 0) { + strip_off(); + uint16_t min_leds = max(1, _led_count/5); // make sure, at least one LED is on + uint16_t max_leds = max(1, _led_count/2); // make sure, at least one LED is on + _counter_mode_step = random(min_leds, max_leds); + } + + Adafruit_NeoPixel::setPixelColor(random(_led_count), _mode_color); + Adafruit_NeoPixel::show(); + + _counter_mode_step--; + _mode_delay = 50 + ((1986 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Blink several LEDs in random colors on, reset, repeat. + * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ + */ +void WS2812FX::mode_twinkle_random(void) { + _mode_color = color_wheel(random(256)); + mode_twinkle(); +} + + +/* + * Blink several LEDs on, fading out. + */ +void WS2812FX::mode_twinkle_fade(void) { + + for(uint16_t i=0; i < _led_count; i++) { + uint32_t px_rgb = Adafruit_NeoPixel::getPixelColor(i); + + byte px_r = (px_rgb & 0x00FF0000) >> 16; + byte px_g = (px_rgb & 0x0000FF00) >> 8; + byte px_b = (px_rgb & 0x000000FF) >> 0; + + // fade out (divide by 2) + px_r = px_r >> 1; + px_g = px_g >> 1; + px_b = px_b >> 1; + + Adafruit_NeoPixel::setPixelColor(i, px_r, px_g, px_b); + } + + if(random(3) == 0) { + Adafruit_NeoPixel::setPixelColor(random(_led_count), _mode_color); + } + + Adafruit_NeoPixel::show(); + + _mode_delay = 100 + ((100 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Blink several LEDs in random colors on, fading out. + */ +void WS2812FX::mode_twinkle_fade_random(void) { + _mode_color = color_wheel(random(256)); + mode_twinkle_fade(); +} + + +/* + * Blinks one LED at a time. + * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ + */ +void WS2812FX::mode_sparkle(void) { + Adafruit_NeoPixel::clear(); + Adafruit_NeoPixel::setPixelColor(random(_led_count),_color); + Adafruit_NeoPixel::show(); + _mode_delay = 10 + ((200 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * Lights all LEDs in the _color. Flashes single white pixels randomly. + * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ + */ +void WS2812FX::mode_flash_sparkle(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + + if(random(10) == 7) { + Adafruit_NeoPixel::setPixelColor(random(_led_count), 255, 255, 255); + _mode_delay = 20; + } else { + _mode_delay = 20 + ((200 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); + } + + Adafruit_NeoPixel::show(); +} + + +/* + * Like flash sparkle. With more flash. + * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ + */ +void WS2812FX::mode_hyper_sparkle(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + + if(random(10) < 4) { + for(uint16_t i=0; i < max(1, _led_count/3); i++) { + Adafruit_NeoPixel::setPixelColor(random(_led_count), 255, 255, 255); + } + _mode_delay = 20; + } else { + _mode_delay = 15 + ((120 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); + } + + Adafruit_NeoPixel::show(); +} + + +/* + * Classic Strobe effect. + */ +void WS2812FX::mode_strobe(void) { + if(_counter_mode_call % 2 == 0) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + _mode_delay = 20; + } else { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, 0); + } + _mode_delay = 50 + ((1986 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); + } + Adafruit_NeoPixel::show(); +} + + +/* + * Strobe effect with different strobe count and pause, controled by _speed. + */ +void WS2812FX::mode_multi_strobe(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, 0); + } + + if(_counter_mode_step < (2 * ((_speed / 10) + 1))) { + if(_counter_mode_step % 2 == 0) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + _mode_delay = 20; + } else { + _mode_delay = 50; + } + + } else { + _mode_delay = 100 + ((9 - (_speed % 10)) * 125); + } + + Adafruit_NeoPixel::show(); + _counter_mode_step = (_counter_mode_step + 1) % ((2 * ((_speed / 10) + 1)) + 1); +} + + +/* + * Classic Strobe effect. Cycling through the rainbow. + */ +void WS2812FX::mode_strobe_rainbow(void) { + if(_counter_mode_call % 2 == 0) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(_counter_mode_call % 256)); + } + _mode_delay = 20; + } else { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, 0); + } + _mode_delay = 50 + ((1986 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); + } + Adafruit_NeoPixel::show(); +} + + +/* + * Classic Blink effect. Cycling through the rainbow. + */ +void WS2812FX::mode_blink_rainbow(void) { + if(_counter_mode_call % 2 == 1) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(_counter_mode_call % 256)); + } + Adafruit_NeoPixel::show(); + } else { + strip_off(); + } + + _mode_delay = 100 + ((1986 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + + +/* + * _color running on white. + */ +void WS2812FX::mode_chase_white(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, 255, 255, 255); + } + + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + Adafruit_NeoPixel::setPixelColor(n, _color); + Adafruit_NeoPixel::setPixelColor(m, _color); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * White running on _color. + */ +void WS2812FX::mode_chase_color(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + Adafruit_NeoPixel::setPixelColor(n, 255, 255, 255); + Adafruit_NeoPixel::setPixelColor(m, 255, 255, 255); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * White running followed by random color. + */ +void WS2812FX::mode_chase_random(void) { + if(_counter_mode_step == 0) { + Adafruit_NeoPixel::setPixelColor(_led_count-1, color_wheel(_mode_color)); + _mode_color = get_random_wheel_index(_mode_color); + } + + for(uint16_t i=0; i < _counter_mode_step; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(_mode_color)); + } + + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + Adafruit_NeoPixel::setPixelColor(n, 255, 255, 255); + Adafruit_NeoPixel::setPixelColor(m, 255, 255, 255); + + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * White running on rainbow. + */ +void WS2812FX::mode_chase_rainbow(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(((i * 256 / _led_count) + (_counter_mode_call % 256)) % 256)); + } + + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + Adafruit_NeoPixel::setPixelColor(n, 255, 255, 255); + Adafruit_NeoPixel::setPixelColor(m, 255, 255, 255); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * White flashes running on _color. + */ +void WS2812FX::mode_chase_flash(void) { + const static uint8_t flash_count = 4; + uint8_t flash_step = _counter_mode_call % ((flash_count * 2) + 1); + + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + + if(flash_step < (flash_count * 2)) { + if(flash_step % 2 == 0) { + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + Adafruit_NeoPixel::setPixelColor(n, 255, 255, 255); + Adafruit_NeoPixel::setPixelColor(m, 255, 255, 255); + _mode_delay = 20; + } else { + _mode_delay = 30; + } + } else { + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); + } + + Adafruit_NeoPixel::show(); +} + + +/* + * White flashes running, followed by random color. + */ +void WS2812FX::mode_chase_flash_random(void) { + const static uint8_t flash_count = 4; + uint8_t flash_step = _counter_mode_call % ((flash_count * 2) + 1); + + for(uint16_t i=0; i < _counter_mode_step; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(_mode_color)); + } + + if(flash_step < (flash_count * 2)) { + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + if(flash_step % 2 == 0) { + Adafruit_NeoPixel::setPixelColor(n, 255, 255, 255); + Adafruit_NeoPixel::setPixelColor(m, 255, 255, 255); + _mode_delay = 20; + } else { + Adafruit_NeoPixel::setPixelColor(n, color_wheel(_mode_color)); + Adafruit_NeoPixel::setPixelColor(m, 0, 0, 0); + _mode_delay = 30; + } + } else { + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 1 + ((10 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); + + if(_counter_mode_step == 0) { + _mode_color = get_random_wheel_index(_mode_color); + } + } + + Adafruit_NeoPixel::show(); +} + + +/* + * Rainbow running on white. + */ +void WS2812FX::mode_chase_rainbow_white(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, 255, 255, 255); + } + + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + Adafruit_NeoPixel::setPixelColor(n, color_wheel(((n * 256 / _led_count) + (_counter_mode_call % 256)) % 256)); + Adafruit_NeoPixel::setPixelColor(m, color_wheel(((m * 256 / _led_count) + (_counter_mode_call % 256)) % 256)); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Black running on _color. + */ +void WS2812FX::mode_chase_blackout(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, _color); + } + + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + Adafruit_NeoPixel::setPixelColor(n, 0, 0, 0); + Adafruit_NeoPixel::setPixelColor(m, 0, 0, 0); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Black running on rainbow. + */ +void WS2812FX::mode_chase_blackout_rainbow(void) { + for(uint16_t i=0; i < _led_count; i++) { + Adafruit_NeoPixel::setPixelColor(i, color_wheel(((i * 256 / _led_count) + (_counter_mode_call % 256)) % 256)); + } + + uint16_t n = _counter_mode_step; + uint16_t m = (_counter_mode_step + 1) % _led_count; + Adafruit_NeoPixel::setPixelColor(n, 0, 0, 0); + Adafruit_NeoPixel::setPixelColor(m, 0, 0, 0); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Random color intruduced alternating from start and end of strip. + */ +void WS2812FX::mode_color_sweep_random(void) { + if(_counter_mode_step == 0 || _counter_mode_step == _led_count) { + _mode_color = get_random_wheel_index(_mode_color); + } + + if(_counter_mode_step < _led_count) { + Adafruit_NeoPixel::setPixelColor(_counter_mode_step, color_wheel(_mode_color)); + } else { + Adafruit_NeoPixel::setPixelColor((_led_count * 2) - _counter_mode_step - 1, color_wheel(_mode_color)); + } + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % (_led_count * 2); + _mode_delay = 5 + ((50 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Alternating color/white pixels running. + */ +void WS2812FX::mode_running_color(void) { + for(uint16_t i=0; i < _led_count; i++) { + if((i + _counter_mode_step) % 4 < 2) { + Adafruit_NeoPixel::setPixelColor(i, _mode_color); + } else { + Adafruit_NeoPixel::setPixelColor(i, 255, 255, 255); + } + } + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % 4; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Alternating red/blue pixels running. + */ +void WS2812FX::mode_running_red_blue(void) { + for(uint16_t i=0; i < _led_count; i++) { + if((i + _counter_mode_step) % 4 < 2) { + Adafruit_NeoPixel::setPixelColor(i, 255, 0, 0); + } else { + Adafruit_NeoPixel::setPixelColor(i, 0, 0, 255); + } + } + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % 4; + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Random colored pixels running. + */ +void WS2812FX::mode_running_random(void) { + for(uint16_t i=_led_count-1; i > 0; i--) { + Adafruit_NeoPixel::setPixelColor(i, Adafruit_NeoPixel::getPixelColor(i-1)); + } + + if(_counter_mode_step == 0) { + _mode_color = get_random_wheel_index(_mode_color); + Adafruit_NeoPixel::setPixelColor(0, color_wheel(_mode_color)); + } + + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % 2; + + _mode_delay = 10 + ((30 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * K.I.T.T. + */ +void WS2812FX::mode_larson_scanner(void) { + + for(uint16_t i=0; i < _led_count; i++) { + uint32_t px_rgb = Adafruit_NeoPixel::getPixelColor(i); + + byte px_r = (px_rgb & 0x00FF0000) >> 16; + byte px_g = (px_rgb & 0x0000FF00) >> 8; + byte px_b = (px_rgb & 0x000000FF) >> 0; + + // fade out (divide by 2) + px_r = px_r >> 1; + px_g = px_g >> 1; + px_b = px_b >> 1; + + Adafruit_NeoPixel::setPixelColor(i, px_r, px_g, px_b); + } + + uint16_t pos = 0; + + if(_counter_mode_step < _led_count) { + pos = _counter_mode_step; + } else { + pos = (_led_count * 2) - _counter_mode_step - 2; + } + + Adafruit_NeoPixel::setPixelColor(pos, _color); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % ((_led_count * 2) - 2); + _mode_delay = 10 + ((10 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Fireing comets from one end. + */ +void WS2812FX::mode_comet(void) { + + for(uint16_t i=0; i < _led_count; i++) { + uint32_t px_rgb = Adafruit_NeoPixel::getPixelColor(i); + + byte px_r = (px_rgb & 0x00FF0000) >> 16; + byte px_g = (px_rgb & 0x0000FF00) >> 8; + byte px_b = (px_rgb & 0x000000FF) >> 0; + + // fade out (divide by 2) + px_r = px_r >> 1; + px_g = px_g >> 1; + px_b = px_b >> 1; + + Adafruit_NeoPixel::setPixelColor(i, px_r, px_g, px_b); + } + + Adafruit_NeoPixel::setPixelColor(_counter_mode_step, _color); + Adafruit_NeoPixel::show(); + + _counter_mode_step = (_counter_mode_step + 1) % _led_count; + _mode_delay = 10 + ((10 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); +} + + +/* + * Firework sparks. + */ +void WS2812FX::mode_fireworks(void) { + uint32_t px_rgb = 0; + byte px_r = 0; + byte px_g = 0; + byte px_b = 0; + + for(uint16_t i=0; i < _led_count; i++) { + px_rgb = Adafruit_NeoPixel::getPixelColor(i); + + px_r = (px_rgb & 0x00FF0000) >> 16; + px_g = (px_rgb & 0x0000FF00) >> 8; + px_b = (px_rgb & 0x000000FF) >> 0; + + // fade out (divide by 2) + px_r = px_r >> 1; + px_g = px_g >> 1; + px_b = px_b >> 1; + + Adafruit_NeoPixel::setPixelColor(i, px_r, px_g, px_b); + } + + // first LED has only one neighbour + px_r = (((Adafruit_NeoPixel::getPixelColor(1) & 0x00FF0000) >> 16) >> 1) + ((Adafruit_NeoPixel::getPixelColor(0) & 0x00FF0000) >> 16); + px_g = (((Adafruit_NeoPixel::getPixelColor(1) & 0x0000FF00) >> 8) >> 1) + ((Adafruit_NeoPixel::getPixelColor(0) & 0x0000FF00) >> 8); + px_b = (((Adafruit_NeoPixel::getPixelColor(1) & 0x000000FF) >> 0) >> 1) + ((Adafruit_NeoPixel::getPixelColor(0) & 0x000000FF) >> 0); + Adafruit_NeoPixel::setPixelColor(0, px_r, px_g, px_b); + + // set brightness(i) = ((brightness(i-1)/2 + brightness(i+1)) / 2) + brightness(i) + for(uint16_t i=1; i < _led_count-1; i++) { + px_r = (( + (((Adafruit_NeoPixel::getPixelColor(i-1) & 0x00FF0000) >> 16) >> 1) + + (((Adafruit_NeoPixel::getPixelColor(i+1) & 0x00FF0000) >> 16) >> 0) ) >> 1) + + (((Adafruit_NeoPixel::getPixelColor(i ) & 0x00FF0000) >> 16) >> 0); + + px_g = (( + (((Adafruit_NeoPixel::getPixelColor(i-1) & 0x0000FF00) >> 8) >> 1) + + (((Adafruit_NeoPixel::getPixelColor(i+1) & 0x0000FF00) >> 8) >> 0) ) >> 1) + + (((Adafruit_NeoPixel::getPixelColor(i ) & 0x0000FF00) >> 8) >> 0); + + px_b = (( + (((Adafruit_NeoPixel::getPixelColor(i-1) & 0x000000FF) >> 0) >> 1) + + (((Adafruit_NeoPixel::getPixelColor(i+1) & 0x000000FF) >> 0) >> 0) ) >> 1) + + (((Adafruit_NeoPixel::getPixelColor(i ) & 0x000000FF) >> 0) >> 0); + + Adafruit_NeoPixel::setPixelColor(i, px_r, px_g, px_b); + } + + // last LED has only one neighbour + px_r = (((Adafruit_NeoPixel::getPixelColor(_led_count-2) & 0x00FF0000) >> 16) >> 2) + ((Adafruit_NeoPixel::getPixelColor(_led_count-1) & 0x00FF0000) >> 16); + px_g = (((Adafruit_NeoPixel::getPixelColor(_led_count-2) & 0x0000FF00) >> 8) >> 2) + ((Adafruit_NeoPixel::getPixelColor(_led_count-1) & 0x0000FF00) >> 8); + px_b = (((Adafruit_NeoPixel::getPixelColor(_led_count-2) & 0x000000FF) >> 0) >> 2) + ((Adafruit_NeoPixel::getPixelColor(_led_count-1) & 0x000000FF) >> 0); + Adafruit_NeoPixel::setPixelColor(_led_count-1, px_r, px_g, px_b); + + for(uint16_t i=0; i> 16; + byte p_g = (_color & 0x0000FF00) >> 8; + byte p_b = (_color & 0x000000FF) >> 0; + byte flicker_val = max(p_r,max(p_g, p_b))/rev_intensity; + for(uint16_t i=0; i < _led_count; i++) + { + int flicker = random(0,flicker_val); + int r1 = p_r-flicker; + int g1 = p_g-flicker; + int b1 = p_b-flicker; + if(g1<0) g1=0; + if(r1<0) r1=0; + if(b1<0) b1=0; + Adafruit_NeoPixel::setPixelColor(i,r1,g1, b1); + } + Adafruit_NeoPixel::show(); + _mode_delay = 10 + ((500 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX); +} + +/* + * Access to individual control + */ +void WS2812FX::mode_individual_control(void) +{ + //does nothing + _mode_delay = 50; +} + +/* + * Only works in individual mode + */ +void WS2812FX::setIndividual(int i) +{ + if (i >= 0 && i < _led_count) + Adafruit_NeoPixel::setPixelColor(i, _color); + Adafruit_NeoPixel::show(); +} + +void WS2812FX::setRange(int i, int i2) +{ + for (int x = i; x < i2; x++) + { + if (x >= 0 && x < _led_count) + Adafruit_NeoPixel::setPixelColor(x, _color); + } + Adafruit_NeoPixel::show(); +} + diff --git a/wled00/WS2812FX.h b/wled00/WS2812FX.h new file mode 100644 index 00000000..f46c324e --- /dev/null +++ b/wled00/WS2812FX.h @@ -0,0 +1,338 @@ +/* + WS2812FX.h - Library for WS2812 LED effects. + + Harm Aldick - 2016 + www.aldick.org + FEATURES + * A lot of blinken modes and counting + * WS2812FX can be used as drop-in replacement for Adafruit Neopixel Library + NOTES + * Uses the Adafruit Neopixel library. Get it here: + https://github.com/adafruit/Adafruit_NeoPixel + LICENSE + The MIT License (MIT) + Copyright (c) 2016 Harm Aldick + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + CHANGELOG + 2016-05-28 Initial beta release + 2016-06-03 Code cleanup, minor improvements, new modes + 2016-06-04 2 new fx, fixed setColor (now also resets _mode_color) +*/ + +#ifndef WS2812FX_h +#define WS2812FX_h + +#include "Arduino.h" +#include + +#define DEFAULT_BRIGHTNESS 50 +#define DEFAULT_MODE 0 +#define DEFAULT_SPEED 150 +#define DEFAULT_COLOR 0xFF0000 + +#define SPEED_MIN 0 +#define SPEED_MAX 255 + +#define BRIGHTNESS_MIN 0 +#define BRIGHTNESS_MAX 255 + +#define MODE_COUNT 48 + +#define FX_MODE_STATIC 0 +#define FX_MODE_BLINK 1 +#define FX_MODE_BREATH 2 +#define FX_MODE_COLOR_WIPE 3 +#define FX_MODE_COLOR_WIPE_RANDOM 4 +#define FX_MODE_RANDOM_COLOR 5 +#define FX_MODE_SINGLE_DYNAMIC 6 +#define FX_MODE_MULTI_DYNAMIC 7 +#define FX_MODE_RAINBOW 8 +#define FX_MODE_RAINBOW_CYCLE 9 +#define FX_MODE_SCAN 10 +#define FX_MODE_DUAL_SCAN 11 +#define FX_MODE_FADE 12 +#define FX_MODE_THEATER_CHASE 13 +#define FX_MODE_THEATER_CHASE_RAINBOW 14 +#define FX_MODE_RUNNING_LIGHTS 15 +#define FX_MODE_TWINKLE 16 +#define FX_MODE_TWINKLE_RANDOM 17 +#define FX_MODE_TWINKLE_FADE 18 +#define FX_MODE_TWINKLE_FADE_RANDOM 19 +#define FX_MODE_SPARKLE 20 +#define FX_MODE_FLASH_SPARKLE 21 +#define FX_MODE_HYPER_SPARKLE 22 +#define FX_MODE_STROBE 23 +#define FX_MODE_STROBE_RAINBOW 24 +#define FX_MODE_MULTI_STROBE 25 +#define FX_MODE_BLINK_RAINBOW 26 +#define FX_MODE_CHASE_WHITE 27 +#define FX_MODE_CHASE_COLOR 28 +#define FX_MODE_CHASE_RANDOM 29 +#define FX_MODE_CHASE_RAINBOW 30 +#define FX_MODE_CHASE_FLASH 31 +#define FX_MODE_CHASE_FLASH_RANDOM 32 +#define FX_MODE_CHASE_RAINBOW_WHITE 33 +#define FX_MODE_CHASE_BLACKOUT 34 +#define FX_MODE_CHASE_BLACKOUT_RAINBOW 35 +#define FX_MODE_COLOR_SWEEP_RANDOM 36 +#define FX_MODE_RUNNING_COLOR 37 +#define FX_MODE_RUNNING_RED_BLUE 38 +#define FX_MODE_RUNNING_RANDOM 39 +#define FX_MODE_LARSON_SCANNER 40 +#define FX_MODE_COMET 41 +#define FX_MODE_FIREWORKS 42 +#define FX_MODE_FIREWORKS_RANDOM 43 +#define FX_MODE_MERRY_CHRISTMAS 44 +#define FX_MODE_FIRE_FLICKER 45 +#define FX_MODE_FIRE_FLICKER_SOFT 46 +#define FX_MODE_INDIVIDUAL_CONTROL 47 + +class WS2812FX : public Adafruit_NeoPixel { + + typedef void (WS2812FX::*mode_ptr)(void); + + public: + + WS2812FX(uint16_t n, uint8_t p, neoPixelType t) : Adafruit_NeoPixel(n, p, t) { + _mode[FX_MODE_STATIC] = &WS2812FX::mode_static; + _mode[FX_MODE_BLINK] = &WS2812FX::mode_blink; + _mode[FX_MODE_BREATH] = &WS2812FX::mode_breath; + _mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe; + _mode[FX_MODE_COLOR_WIPE_RANDOM] = &WS2812FX::mode_color_wipe_random; + _mode[FX_MODE_RANDOM_COLOR] = &WS2812FX::mode_random_color; + _mode[FX_MODE_SINGLE_DYNAMIC] = &WS2812FX::mode_single_dynamic; + _mode[FX_MODE_MULTI_DYNAMIC] = &WS2812FX::mode_multi_dynamic; + _mode[FX_MODE_RAINBOW] = &WS2812FX::mode_rainbow; + _mode[FX_MODE_RAINBOW_CYCLE] = &WS2812FX::mode_rainbow_cycle; + _mode[FX_MODE_SCAN] = &WS2812FX::mode_scan; + _mode[FX_MODE_DUAL_SCAN] = &WS2812FX::mode_dual_scan; + _mode[FX_MODE_FADE] = &WS2812FX::mode_fade; + _mode[FX_MODE_THEATER_CHASE] = &WS2812FX::mode_theater_chase; + _mode[FX_MODE_THEATER_CHASE_RAINBOW] = &WS2812FX::mode_theater_chase_rainbow; + _mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights; + _mode[FX_MODE_TWINKLE] = &WS2812FX::mode_twinkle; + _mode[FX_MODE_TWINKLE_RANDOM] = &WS2812FX::mode_twinkle_random; + _mode[FX_MODE_TWINKLE_FADE] = &WS2812FX::mode_twinkle_fade; + _mode[FX_MODE_TWINKLE_FADE_RANDOM] = &WS2812FX::mode_twinkle_fade_random; + _mode[FX_MODE_SPARKLE] = &WS2812FX::mode_sparkle; + _mode[FX_MODE_FLASH_SPARKLE] = &WS2812FX::mode_flash_sparkle; + _mode[FX_MODE_HYPER_SPARKLE] = &WS2812FX::mode_hyper_sparkle; + _mode[FX_MODE_STROBE] = &WS2812FX::mode_strobe; + _mode[FX_MODE_STROBE_RAINBOW] = &WS2812FX::mode_strobe_rainbow; + _mode[FX_MODE_MULTI_STROBE] = &WS2812FX::mode_multi_strobe; + _mode[FX_MODE_BLINK_RAINBOW] = &WS2812FX::mode_blink_rainbow; + _mode[FX_MODE_CHASE_WHITE] = &WS2812FX::mode_chase_white; + _mode[FX_MODE_CHASE_COLOR] = &WS2812FX::mode_chase_color; + _mode[FX_MODE_CHASE_RANDOM] = &WS2812FX::mode_chase_random; + _mode[FX_MODE_CHASE_RAINBOW] = &WS2812FX::mode_chase_rainbow; + _mode[FX_MODE_CHASE_FLASH] = &WS2812FX::mode_chase_flash; + _mode[FX_MODE_CHASE_FLASH_RANDOM] = &WS2812FX::mode_chase_flash_random; + _mode[FX_MODE_CHASE_RAINBOW_WHITE] = &WS2812FX::mode_chase_rainbow_white; + _mode[FX_MODE_CHASE_BLACKOUT] = &WS2812FX::mode_chase_blackout; + _mode[FX_MODE_CHASE_BLACKOUT_RAINBOW]= &WS2812FX::mode_chase_blackout_rainbow; + _mode[FX_MODE_COLOR_SWEEP_RANDOM] = &WS2812FX::mode_color_sweep_random; + _mode[FX_MODE_RUNNING_COLOR] = &WS2812FX::mode_running_color; + _mode[FX_MODE_RUNNING_RED_BLUE] = &WS2812FX::mode_running_red_blue; + _mode[FX_MODE_RUNNING_RANDOM] = &WS2812FX::mode_running_random; + _mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner; + _mode[FX_MODE_COMET] = &WS2812FX::mode_comet; + _mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks; + _mode[FX_MODE_FIREWORKS_RANDOM] = &WS2812FX::mode_fireworks_random; + _mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas; + _mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker; + _mode[FX_MODE_FIRE_FLICKER_SOFT] = &WS2812FX::mode_fire_flicker_soft; + _mode[FX_MODE_INDIVIDUAL_CONTROL] = &WS2812FX::mode_individual_control; + + _name[FX_MODE_STATIC] = "Static"; + _name[FX_MODE_BLINK] = "Blink"; + _name[FX_MODE_BREATH] = "Breath"; + _name[FX_MODE_COLOR_WIPE] = "Color Wipe"; + _name[FX_MODE_COLOR_WIPE_RANDOM] = "Color Wipe Random"; + _name[FX_MODE_RANDOM_COLOR] = "Random Color"; + _name[FX_MODE_SINGLE_DYNAMIC] = "Single Dynamic"; + _name[FX_MODE_MULTI_DYNAMIC] = "Multi Dynamic"; + _name[FX_MODE_RAINBOW] = "Rainbow"; + _name[FX_MODE_RAINBOW_CYCLE] = "Rainbow Cycle"; + _name[FX_MODE_SCAN] = "Scan"; + _name[FX_MODE_DUAL_SCAN] = "Dual Scan"; + _name[FX_MODE_FADE] = "Fade"; + _name[FX_MODE_THEATER_CHASE] = "Theater Chase"; + _name[FX_MODE_THEATER_CHASE_RAINBOW] = "Theater Chase Rainbow"; + _name[FX_MODE_RUNNING_LIGHTS] = "Running Lights"; + _name[FX_MODE_TWINKLE] = "Twinkle"; + _name[FX_MODE_TWINKLE_RANDOM] = "Twinkle Random"; + _name[FX_MODE_TWINKLE_FADE] = "Twinkle Fade"; + _name[FX_MODE_TWINKLE_FADE_RANDOM] = "Twinkle Fade Random"; + _name[FX_MODE_SPARKLE] = "Sparkle"; + _name[FX_MODE_FLASH_SPARKLE] = "Flash Sparkle"; + _name[FX_MODE_HYPER_SPARKLE] = "Hyper Sparkle"; + _name[FX_MODE_STROBE] = "Strobe"; + _name[FX_MODE_STROBE_RAINBOW] = "Strobe Rainbow"; + _name[FX_MODE_MULTI_STROBE] = "Multi Strobe"; + _name[FX_MODE_BLINK_RAINBOW] = "Blink Rainbow"; + _name[FX_MODE_CHASE_WHITE] = "Chase White"; + _name[FX_MODE_CHASE_COLOR] = "Chase Color"; + _name[FX_MODE_CHASE_RANDOM] = "Chase Random"; + _name[FX_MODE_CHASE_RAINBOW] = "Chase Rainbow"; + _name[FX_MODE_CHASE_FLASH] = "Chase Flash"; + _name[FX_MODE_CHASE_FLASH_RANDOM] = "Chase Flash Random"; + _name[FX_MODE_CHASE_RAINBOW_WHITE] = "Chase Rainbow White"; + _name[FX_MODE_CHASE_BLACKOUT] = "Chase Blackout"; + _name[FX_MODE_CHASE_BLACKOUT_RAINBOW]= "Chase Blackout Rainbow"; + _name[FX_MODE_COLOR_SWEEP_RANDOM] = "Color Sweep Random"; + _name[FX_MODE_RUNNING_COLOR] = "Running Color"; + _name[FX_MODE_RUNNING_RED_BLUE] = "Running Red Blue"; + _name[FX_MODE_RUNNING_RANDOM] = "Running Random"; + _name[FX_MODE_LARSON_SCANNER] = "Larson Scanner"; + _name[FX_MODE_COMET] = "Comet"; + _name[FX_MODE_FIREWORKS] = "Fireworks"; + _name[FX_MODE_FIREWORKS_RANDOM] = "Fireworks Random"; + _name[FX_MODE_MERRY_CHRISTMAS] = "Merry Christmas"; + _name[FX_MODE_FIRE_FLICKER] = "Fire Flicker"; + _name[FX_MODE_FIRE_FLICKER_SOFT] = "Fire Flicker (soft)"; + _name[FX_MODE_INDIVIDUAL_CONTROL] = "Individual Pixel Control"; + + _mode_index = DEFAULT_MODE; + _speed = DEFAULT_SPEED; + _brightness = DEFAULT_BRIGHTNESS; + _running = false; + _led_count = n; + _mode_last_call_time = 0; + _mode_delay = 0; + _color = DEFAULT_COLOR; + _mode_color = DEFAULT_COLOR; + _counter_mode_call = 0; + _counter_mode_step = 0; + } + + void + init(void), + service(void), + start(void), + stop(void), + setMode(uint8_t m), + setSpeed(uint8_t s), + increaseSpeed(uint8_t s), + decreaseSpeed(uint8_t s), + setColor(uint8_t r, uint8_t g, uint8_t b), + setColor(uint32_t c), + setBrightness(uint8_t b), + increaseBrightness(uint8_t s), + decreaseBrightness(uint8_t s), + setIndividual(int i), + setRange(int i, int i2); + + boolean + isRunning(void); + + uint8_t + getMode(void), + getSpeed(void), + getBrightness(void), + getModeCount(void); + + uint32_t + getColor(void); + + const char* + getModeName(uint8_t m); + + private: + + void + strip_off(void), + mode_static(void), + mode_blink(void), + mode_color_wipe(void), + mode_color_wipe_random(void), + mode_random_color(void), + mode_single_dynamic(void), + mode_multi_dynamic(void), + mode_breath(void), + mode_fade(void), + mode_scan(void), + mode_dual_scan(void), + mode_theater_chase(void), + mode_theater_chase_rainbow(void), + mode_rainbow(void), + mode_rainbow_cycle(void), + mode_running_lights(void), + mode_twinkle(void), + mode_twinkle_random(void), + mode_twinkle_fade(void), + mode_twinkle_fade_random(void), + mode_sparkle(void), + mode_flash_sparkle(void), + mode_hyper_sparkle(void), + mode_strobe(void), + mode_strobe_rainbow(void), + mode_multi_strobe(void), + mode_blink_rainbow(void), + mode_chase_white(void), + mode_chase_color(void), + mode_chase_random(void), + mode_chase_rainbow(void), + mode_chase_flash(void), + mode_chase_flash_random(void), + mode_chase_rainbow_white(void), + mode_chase_blackout(void), + mode_chase_blackout_rainbow(void), + mode_color_sweep_random(void), + mode_running_color(void), + mode_running_red_blue(void), + mode_running_random(void), + mode_larson_scanner(void), + mode_comet(void), + mode_fireworks(void), + mode_fireworks_random(void), + mode_merry_christmas(void), + mode_fire_flicker(void), + mode_fire_flicker_soft(void), + mode_fire_flicker_int(int), + mode_individual_control(void); + + boolean + _running; + + uint8_t + get_random_wheel_index(uint8_t), + _mode_index, + _speed, + _brightness; + + uint16_t + _led_count; + + uint32_t + color_wheel(uint8_t), + _color, + _counter_mode_call, + _counter_mode_step, + _mode_color, + _mode_delay; + + unsigned long + _mode_last_call_time; + + const char* + _name[MODE_COUNT]; + + mode_ptr + _mode[MODE_COUNT]; +}; + +#endif diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 4cc35f35..b845a076 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -5,7 +5,7 @@ #include #include #include -#include +#include "WS2812FX.h" #include #include @@ -15,7 +15,7 @@ * @author Christian Schwinne */ //Hardware-settings (only changeble via code) -uint8_t led_amount = 9; +uint8_t led_amount = 84; uint8_t buttonPin = 0; //needs pull-up //Default CONFIG String serverDescription = "WLED 0.3pd"; diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index b17f8c6b..f118ccb1 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -176,15 +176,35 @@ boolean handleSet(String req) } pos = req.indexOf("FX="); if (pos > 0) { - effectCurrent = req.substring(pos + 3).toInt(); - strip.setMode(effectCurrent); - effectUpdated = true; + if (effectCurrent != req.substring(pos + 3).toInt()) + { + effectCurrent = req.substring(pos + 3).toInt(); + strip.setMode(effectCurrent); + effectUpdated = true; + } } pos = req.indexOf("XS="); if (pos > 0) { - effectSpeed = req.substring(pos + 3).toInt(); - strip.setSpeed(effectSpeed); - effectUpdated = true; + if (effectSpeed != req.substring(pos + 3).toInt()) + { + effectSpeed = req.substring(pos + 3).toInt(); + strip.setSpeed(effectSpeed); + effectUpdated = true; + } + } + pos = req.indexOf("I="); + if (pos > 0){ + if (strip.getMode() != 47) strip.setMode(47); + effectCurrent = 47; + int index = req.substring(pos + 2).toInt(); + pos = req.indexOf("I2="); + if (pos > 0){ + int index2 = req.substring(pos + 3).toInt(); + strip.setRange(index, index2); + } else + { + strip.setIndividual(index); + } } if (req.indexOf("NS=") > 0) {