From 98c486606bccc84b5ef8bdc6c0f07020de747979 Mon Sep 17 00:00:00 2001 From: BPoH_Voodoo Date: Sun, 17 Feb 2019 12:16:38 +0100 Subject: [PATCH] Code Cleanup Code Cleanup --- Arduino/McLighting/McLighting.ino | 268 ++-- Arduino/McLighting/WS2812FX.cpp | 1613 --------------------- Arduino/McLighting/WS2812FX.h | 613 -------- Arduino/McLighting/colormodes.h | 197 +-- Arduino/McLighting/custom/BlockDissolve.h | 68 - Arduino/McLighting/custom/DualLarson.h | 67 - Arduino/McLighting/custom/MultiComet.h | 70 - Arduino/McLighting/custom/Oscillate.h | 84 -- Arduino/McLighting/custom/Popcorn.h | 94 -- Arduino/McLighting/custom/Rain.h | 66 - Arduino/McLighting/custom/RainbowLarson.h | 67 - Arduino/McLighting/custom/RandomChase.h | 54 - Arduino/McLighting/custom/TriFade.h | 83 -- Arduino/McLighting/custom/VUMeter.h | 80 - Arduino/McLighting/definitions.h | 42 +- Arduino/McLighting/request_handlers.h | 76 +- Arduino/McLighting/spiffs_webserver.h | 210 +-- 17 files changed, 399 insertions(+), 3353 deletions(-) delete mode 100644 Arduino/McLighting/WS2812FX.cpp delete mode 100644 Arduino/McLighting/WS2812FX.h delete mode 100644 Arduino/McLighting/custom/BlockDissolve.h delete mode 100644 Arduino/McLighting/custom/DualLarson.h delete mode 100644 Arduino/McLighting/custom/MultiComet.h delete mode 100644 Arduino/McLighting/custom/Oscillate.h delete mode 100644 Arduino/McLighting/custom/Popcorn.h delete mode 100644 Arduino/McLighting/custom/Rain.h delete mode 100644 Arduino/McLighting/custom/RainbowLarson.h delete mode 100644 Arduino/McLighting/custom/RandomChase.h delete mode 100644 Arduino/McLighting/custom/TriFade.h delete mode 100644 Arduino/McLighting/custom/VUMeter.h diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index fd5e8dc..669209b 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -1,26 +1,27 @@ #include "definitions.h" #include "version.h" + // *************************************************************************** // Load libraries for: WebServer / WiFiManager / WebSockets // *************************************************************************** -#include //https://github.com/esp8266/Arduino +#include //https://github.com/esp8266/Arduino // needed for library WiFiManager #include #include -#include //https://github.com/tzapu/WiFiManager +#include //https://github.com/tzapu/WiFiManager #include #include #include #include -#include //https://github.com/Links2004/arduinoWebSockets +#include //https://github.com/Links2004/arduinoWebSockets #include #ifdef ENABLE_BUTTON_GY33 // needed for MCU - #include //https://github.com/FabLab-Luenen/GY33_MCU/archive/master.zip ; //https://github.com/pasko-zh/brzo_i2c + #include //https://github.com/FabLab-Luenen/GY33_MCU/archive/master.zip ; //https://github.com/pasko-zh/brzo_i2c // *************************************************************************** // Initialize Color Sensor // *************************************************************************** @@ -35,14 +36,14 @@ //SPIFFS Save #if !defined(ENABLE_HOMEASSISTANT) and defined(ENABLE_STATE_SAVE_SPIFFS) - #include //https://github.com/bblanchon/ArduinoJson + #include //https://github.com/bblanchon/ArduinoJson #endif // MQTT #ifdef ENABLE_MQTT #include #ifdef ENABLE_HOMEASSISTANT - #include //https://github.com/bblanchon/ArduinoJson + #include //https://github.com/bblanchon/ArduinoJson #endif WiFiClient espClient; @@ -50,8 +51,8 @@ #endif #ifdef ENABLE_AMQTT - #include //https://github.com/marvinroger/async-mqtt-client - //https://github.com/me-no-dev/ESPAsyncTCP + #include //https://github.com/marvinroger/async-mqtt-client + //https://github.com/me-no-dev/ESPAsyncTCP #ifdef ENABLE_HOMEASSISTANT #include #endif @@ -73,7 +74,6 @@ ESPAsyncE131 e131(END_UNIVERSE - START_UNIVERSE + 1); #endif - // *************************************************************************** // Instanciate HTTP(80) / WebSockets(81) Server // *************************************************************************** @@ -88,8 +88,8 @@ ESP8266HTTPUpdateServer httpUpdater; // *************************************************************************** // Load libraries / Instanciate WS2812FX library // *************************************************************************** -// https://github.com/kitesurfer1404/WS2812FX -#include "WS2812FX.h" + +#include // https://github.com/kitesurfer1404/WS2812FX #ifdef RGBW WS2812FX strip = WS2812FX(NUMLEDS, PIN, NEO_GRBW + NEO_KHZ800); @@ -417,7 +417,7 @@ DBG_OUTPUT_PORT.println("Starting...."); } #endif #endif - + #ifdef ENABLE_AMQTT wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect); wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect); @@ -677,7 +677,7 @@ DBG_OUTPUT_PORT.println("Starting...."); // *************************************************************************** server.on("/set_brightness", []() { getArgs(); - mode = BRIGHTNESS; + mode = BRIGHTNESS; #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String(String("OK %") + String(brightness)).c_str()); #endif @@ -688,9 +688,6 @@ DBG_OUTPUT_PORT.println("Starting...."); stateOn = true; if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif getStatusJSON(); }); @@ -703,21 +700,17 @@ DBG_OUTPUT_PORT.println("Starting...."); }); server.on("/set_speed", []() { - if (server.arg("d").toInt() >= 0) { - ws2812fx_speed = server.arg("d").toInt(); - ws2812fx_speed = constrain(ws2812fx_speed, 0, 255); - strip.setSpeed(convertSpeed(ws2812fx_speed)); - #ifdef ENABLE_MQTT + getArgs(); + mode = SETSPEED; + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String(String("OK ?") + String(ws2812fx_speed)).c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ?") + String(ws2812fx_speed)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - } - + #endif + #ifdef ENABLE_HOMEASSISTANT + if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); + #endif getStatusJSON(); }); @@ -764,16 +757,13 @@ DBG_OUTPUT_PORT.println("Starting...."); #ifdef ENABLE_HOMEASSISTANT stateOn = false; #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif }); server.on("/auto", []() { #ifdef ENABLE_TV exit_func = true; #endif - mode = AUTO; + handleAutoStart(); getArgs(); getStatusJSON(); #ifdef ENABLE_MQTT @@ -785,9 +775,6 @@ DBG_OUTPUT_PORT.println("Starting...."); #ifdef ENABLE_HOMEASSISTANT stateOn = false; #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif }); server.on("/all", []() { @@ -808,9 +795,6 @@ DBG_OUTPUT_PORT.println("Starting...."); #ifdef ENABLE_HOMEASSISTANT stateOn = true; #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif }); #ifdef ENABLE_LEGACY_ANIMATIONS @@ -821,18 +805,15 @@ DBG_OUTPUT_PORT.println("Starting...."); mode = WIPE; getArgs(); getStatusJSON(); - #ifdef ENABLE_MQTT + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =wipe").c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =wipe").c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT + #endif + #ifdef ENABLE_HOMEASSISTANT stateOn = true; - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif + #endif }); server.on("/rainbow", []() { @@ -842,18 +823,15 @@ DBG_OUTPUT_PORT.println("Starting...."); mode = RAINBOW; getArgs(); getStatusJSON(); - #ifdef ENABLE_MQTT + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =rainbow").c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =rainbow").c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT + #endif + #ifdef ENABLE_HOMEASSISTANT stateOn = true; - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif + #endif }); server.on("/rainbowCycle", []() { @@ -863,18 +841,15 @@ DBG_OUTPUT_PORT.println("Starting...."); mode = RAINBOWCYCLE; getArgs(); getStatusJSON(); - #ifdef ENABLE_MQTT + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =rainbowCycle").c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =rainbowCycle").c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + #endif }); server.on("/theaterchase", []() { @@ -884,18 +859,15 @@ DBG_OUTPUT_PORT.println("Starting...."); mode = THEATERCHASE; getArgs(); getStatusJSON(); - #ifdef ENABLE_MQTT + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =theaterchase").c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =theaterchase").c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + #endif }); server.on("/twinkleRandom", []() { @@ -905,18 +877,15 @@ DBG_OUTPUT_PORT.println("Starting...."); mode = TWINKLERANDOM; getArgs(); getStatusJSON(); - #ifdef ENABLE_MQTT + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =twinkleRandom").c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =twinkleRandom").c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + #endif }); server.on("/theaterchaseRainbow", []() { @@ -926,18 +895,15 @@ DBG_OUTPUT_PORT.println("Starting...."); mode = THEATERCHASERAINBOW; getArgs(); getStatusJSON(); - #ifdef ENABLE_MQTT + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =theaterchaseRainbow").c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =theaterchaseRainbow").c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT + #endif + #ifdef ENABLE_HOMEASSISTANT stateOn = true; - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif + #endif }); #endif @@ -948,18 +914,15 @@ DBG_OUTPUT_PORT.println("Starting...."); #endif mode = E131; getStatusJSON(); - #ifdef ENABLE_MQTT + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =e131").c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =e131").c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT + #endif + #ifdef ENABLE_HOMEASSISTANT stateOn = true; - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif + #endif }); #endif @@ -969,18 +932,15 @@ DBG_OUTPUT_PORT.println("Starting...."); mode = TV; //getArgs(); getStatusJSON(); - #ifdef ENABLE_MQTT + #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =tv").c_str()); - #endif - #ifdef ENABLE_AMQTT + #endif + #ifdef ENABLE_AMQTT amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =tv").c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT + #endif + #ifdef ENABLE_HOMEASSISTANT stateOn = true; - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif + #endif }); #endif @@ -1003,9 +963,6 @@ DBG_OUTPUT_PORT.println("Starting...."); stateOn = true; if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif }); #ifdef HTTP_OTA @@ -1023,9 +980,9 @@ DBG_OUTPUT_PORT.println("Starting...."); // Choose one to begin listening for E1.31 data // if (e131.begin(E131_UNICAST)) // Listen via Unicast if (e131.begin(E131_MULTICAST, START_UNIVERSE, END_UNIVERSE)) // Listen via Multicast - Serial.println(F("Listening for data...")); + DBG_OUTPUT_PORT.println(F("Listening for data...")); else - Serial.println(F("*** e131.begin failed ***")); + DBG_OUTPUT_PORT.println(F("*** e131.begin failed ***")); #endif #ifdef ENABLE_STATE_SAVE_SPIFFS @@ -1097,31 +1054,61 @@ void loop() { #endif // Simple statemachine that handles the different modes + if (mode == OFF) { + if(strip.isRunning()) strip.stop(); //should clear memory + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + } + + #ifdef ENABLE_TV + if (mode == TV) { + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + if(!strip.isRunning()) strip.start(); + tv(); + } + #endif + + #ifdef ENABLE_E131 + if (mode == E131) { + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + handleE131(); + } + #endif if (mode == SET_MODE) { DBG_OUTPUT_PORT.printf("SET_MODE: %d %d\n", ws2812fx_mode, mode); strip.setMode(ws2812fx_mode); //strip.trigger(); // is done later anyway, why do it more than once? prevmode = SET_MODE; mode = SETCOLOR; - } - if (mode == OFF) { - if(strip.isRunning()) strip.stop(); //should clear memory - // mode = HOLD; - } + } if (mode == SETCOLOR) { strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white); mode = (prevmode == SET_MODE) ? SETSPEED : prevmode; if (mode == HOLD) strip.trigger(); + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } if (mode == SETSPEED) { strip.setSpeed(convertSpeed(ws2812fx_speed)); mode = (prevmode == SET_MODE) ? BRIGHTNESS : prevmode; if (mode == HOLD) strip.trigger(); + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } if (mode == BRIGHTNESS) { strip.setBrightness(brightness); mode = (prevmode == SET_MODE) ? HOLD : prevmode; if (mode == HOLD) strip.trigger(); + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } #ifdef ENABLE_LEGACY_ANIMATIONS if (mode == WIPE) { @@ -1129,59 +1116,64 @@ void loop() { strip.setMode(FX_MODE_COLOR_WIPE); strip.trigger(); mode = HOLD; + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } if (mode == RAINBOW) { strip.setMode(FX_MODE_RAINBOW); strip.trigger(); mode = HOLD; + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } if (mode == RAINBOWCYCLE) { strip.setMode(FX_MODE_RAINBOW_CYCLE); strip.trigger(); mode = HOLD; + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } if (mode == THEATERCHASE) { //strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white); strip.setMode(FX_MODE_THEATER_CHASE); strip.trigger(); mode = HOLD; + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } if (mode == TWINKLERANDOM) { //strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white); strip.setMode(FX_MODE_TWINKLE_RANDOM); strip.trigger(); mode = HOLD; + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } if (mode == THEATERCHASERAINBOW) { strip.setMode(FX_MODE_THEATER_CHASE_RAINBOW); strip.trigger(); mode = HOLD; + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } #endif - #ifdef ENABLE_E131 - if (mode == E131) { - handleE131(); - } - #endif - if (mode == HOLD || mode == CUSTOM) { - if(!strip.isRunning()) strip.start(); #ifdef ENABLE_TV if (exit_func) { exit_func = false; } #endif + if(!strip.isRunning()) strip.start(); if (prevmode == SET_MODE) prevmode = HOLD; } - #ifdef ENABLE_TV - if (mode == TV) { - if(!strip.isRunning()) strip.start(); - tv(); - } - #endif - // Only for modes with WS2812FX functionality #ifdef ENABLE_TV if (mode != TV && mode != CUSTOM) { diff --git a/Arduino/McLighting/WS2812FX.cpp b/Arduino/McLighting/WS2812FX.cpp deleted file mode 100644 index 55fbb6e..0000000 --- a/Arduino/McLighting/WS2812FX.cpp +++ /dev/null @@ -1,1613 +0,0 @@ -/* - 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) - 2017-02-02 added external trigger functionality (e.g. for sound-to-light) - 2017-02-02 removed "blackout" on mode, speed or color-change - 2017-09-26 implemented segment and reverse features - 2017-11-16 changed speed calc, reduced memory footprint - 2018-02-24 added hooks for user created custom effects -*/ - -#include "WS2812FX.h" - -void WS2812FX::init() { - resetSegmentRuntimes(); - Adafruit_NeoPixel::begin(); -} - -// void WS2812FX::timer() { -// for (int j=0; j < 1000; j++) { -// uint16_t delay = (this->*_mode[SEGMENT.mode])(); -// } -// } - -void WS2812FX::service() { - if(_running || _triggered) { - unsigned long now = millis(); // Be aware, millis() rolls over every 49 days - bool doShow = false; - for(uint8_t i=0; i < _num_segments; i++) { - _segment_index = i; - CLR_FRAME; - if(now > SEGMENT_RUNTIME.next_time || _triggered) { - SET_FRAME; - doShow = true; - uint16_t delay = (this->*_mode[SEGMENT.mode])(); - SEGMENT_RUNTIME.next_time = now + max(delay, SPEED_MIN); - SEGMENT_RUNTIME.counter_mode_call++; - } - } - if(doShow) { - delay(1); // for ESP32 (see https://forums.adafruit.com/viewtopic.php?f=47&t=117327) - show(); - } - _triggered = false; - } -} - -// overload setPixelColor() functions so we can use gamma correction -// (see https://learn.adafruit.com/led-tricks-gamma-correction/the-issue) -void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { - if(IS_GAMMA) { - uint8_t w = (c >> 24) & 0xFF; - uint8_t r = (c >> 16) & 0xFF; - uint8_t g = (c >> 8) & 0xFF; - uint8_t b = c & 0xFF; - Adafruit_NeoPixel::setPixelColor(n, gamma8(r), gamma8(g), gamma8(b), gamma8(w)); - } else { - Adafruit_NeoPixel::setPixelColor(n, c); - } -} - -void WS2812FX::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) { - if(IS_GAMMA) { - Adafruit_NeoPixel::setPixelColor(n, gamma8(r), gamma8(g), gamma8(b)); - } else { - Adafruit_NeoPixel::setPixelColor(n, r, g, b); - } -} - -void WS2812FX::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { - if(IS_GAMMA) { - Adafruit_NeoPixel::setPixelColor(n, gamma8(r), gamma8(g), gamma8(b), gamma8(w)); - } else { - Adafruit_NeoPixel::setPixelColor(n, r, g, b, w); - } -} - -void WS2812FX::copyPixels(uint16_t dest, uint16_t src, uint16_t count) { - uint8_t *pixels = getPixels(); - uint8_t bytesPerPixel = (wOffset == rOffset) ? 3 : 4; // 3=RGB, 4=RGBW - - memmove(pixels + (dest * bytesPerPixel), pixels + (src * bytesPerPixel), count * bytesPerPixel); -} - -// overload show() functions so we can use custom show() -void WS2812FX::show(void) { - if(customShow == NULL) { - Adafruit_NeoPixel::show(); - } else { - customShow(); - } -} - -void WS2812FX::start() { - resetSegmentRuntimes(); - _running = true; -} - -void WS2812FX::stop() { - _running = false; - strip_off(); -} - -void WS2812FX::pause() { - _running = false; -} - -void WS2812FX::resume() { - _running = true; -} - -void WS2812FX::trigger() { - _triggered = true; -} - -void WS2812FX::setMode(uint8_t m) { - setMode(0, m); -} - -void WS2812FX::setMode(uint8_t seg, uint8_t m) { - resetSegmentRuntime(seg); - _segments[seg].mode = constrain(m, 0, MODE_COUNT - 1); -} - -void WS2812FX::setOptions(uint8_t seg, uint8_t o) { - _segments[seg].options = o; -} - -void WS2812FX::setSpeed(uint16_t s) { - setSpeed(0, s); -} - -void WS2812FX::setSpeed(uint8_t seg, uint16_t s) { - resetSegmentRuntime(seg); - _segments[seg].speed = constrain(s, SPEED_MIN, SPEED_MAX); -} - -void WS2812FX::increaseSpeed(uint8_t s) { - uint16_t newSpeed = constrain(SEGMENT.speed + s, SPEED_MIN, SPEED_MAX); - setSpeed(newSpeed); -} - -void WS2812FX::decreaseSpeed(uint8_t s) { - uint16_t newSpeed = constrain(SEGMENT.speed - s, SPEED_MIN, SPEED_MAX); - setSpeed(newSpeed); -} - -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(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { - setColor((((uint32_t)w << 24)| ((uint32_t)r << 16) | ((uint32_t)g << 8)| ((uint32_t)b))); -} - -void WS2812FX::setColor(uint32_t c) { - setColor(0, c); -} - -void WS2812FX::setColor(uint8_t seg, uint32_t c) { - resetSegmentRuntime(seg); - _segments[seg].colors[0] = c; -} - -void WS2812FX::setColors(uint8_t seg, uint32_t* c) { - resetSegmentRuntime(seg); - for(uint8_t i=0; i 1); - - _segments[0].start = 0; - _segments[0].stop = Adafruit_NeoPixel::numLEDs - 1; -} - -void WS2812FX::increaseLength(uint16_t s) { - s = _segments[0].stop - _segments[0].start + 1 + s; - setLength(s); -} - -void WS2812FX::decreaseLength(uint16_t s) { - if (s > _segments[0].stop - _segments[0].start + 1) s = 1; - s = _segments[0].stop - _segments[0].start + 1 - s; - - for(uint16_t i=_segments[0].start + s; i <= (_segments[0].stop - _segments[0].start + 1); i++) { - setPixelColor(i, 0); - } - show(); - - setLength(s); -} - -boolean WS2812FX::isRunning() { - return _running; -} - -boolean WS2812FX::isTriggered() { - return _triggered; -} - -boolean WS2812FX::isFrame() { - return isFrame(0); -} - -boolean WS2812FX::isFrame(uint8_t segIndex) { - return (_segment_runtimes[segIndex].aux_param2 & FRAME); -} - -boolean WS2812FX::isCycle() { - return isCycle(0); -} - -boolean WS2812FX::isCycle(uint8_t segIndex) { - return (_segment_runtimes[segIndex].aux_param2 & CYCLE); -} - -uint8_t WS2812FX::getMode(void) { - return getMode(0); -} - -uint8_t WS2812FX::getMode(uint8_t seg) { - return _segments[seg].mode; -} - -uint16_t WS2812FX::getSpeed(void) { - return getSpeed(0); -} - -uint16_t WS2812FX::getSpeed(uint8_t seg) { - return _segments[seg].speed; -} - - -uint8_t WS2812FX::getOptions(uint8_t seg) { - return _segments[seg].options; -} - -uint16_t WS2812FX::getLength(void) { - return numPixels(); -} - -uint16_t WS2812FX::getNumBytes(void) { - return numBytes; -} - -uint8_t WS2812FX::getModeCount(void) { - return MODE_COUNT; -} - -uint8_t WS2812FX::getNumSegments(void) { - return _num_segments; -} - -void WS2812FX::setNumSegments(uint8_t n) { - _num_segments = n; -} - -uint32_t WS2812FX::getColor(void) { - return getColor(0); -} - -uint32_t WS2812FX::getColor(uint8_t seg) { - return _segments[seg].colors[0]; -} - -uint32_t* WS2812FX::getColors(uint8_t seg) { - return _segments[seg].colors; -} - -WS2812FX::Segment* WS2812FX::getSegment(void) { - return &_segments[_segment_index]; -} - -WS2812FX::Segment* WS2812FX::getSegment(uint8_t seg) { - return &_segments[seg]; -} - -WS2812FX::Segment* WS2812FX::getSegments(void) { - return _segments; -} - -WS2812FX::Segment_runtime* WS2812FX::getSegmentRuntime(void) { - return &_segment_runtimes[_segment_index]; -} - -WS2812FX::Segment_runtime* WS2812FX::getSegmentRuntime(uint8_t seg) { - return &_segment_runtimes[seg]; -} - -WS2812FX::Segment_runtime* WS2812FX::getSegmentRuntimes(void) { - return _segment_runtimes; -} - -const __FlashStringHelper* WS2812FX::getModeName(uint8_t m) { - if(m < MODE_COUNT) { - return _names[m]; - } else { - return F(""); - } -} - -void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, bool reverse) { - uint32_t colors[] = {color, 0, 0}; - setSegment(n, start, stop, mode, colors, speed, reverse); -} - -void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, uint8_t options) { - uint32_t colors[] = {color, 0, 0}; - setSegment(n, start, stop, mode, colors, speed, options); -} - -void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, bool reverse) { - setSegment(n, start, stop, mode, colors, speed, (uint8_t)(reverse ? REVERSE : NO_OPTIONS)); -} - -void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, uint8_t options) { - if(n < (sizeof(_segments) / sizeof(_segments[0]))) { - if(n + 1 > _num_segments) _num_segments = n + 1; - _segments[n].start = start; - _segments[n].stop = stop; - _segments[n].mode = mode; - _segments[n].speed = speed; - _segments[n].options = options; - - for(uint8_t i=0; i 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 = random8(); - x = abs(pos - r); - y = 255 - x; - d = min(x, y); - } - - return r; -} - -// fast 8-bit random number generator shamelessly borrowed from FastLED -uint8_t WS2812FX::random8() { - _rand16seed = (_rand16seed * 2053) + 13849; - return (uint8_t)((_rand16seed + (_rand16seed >> 8)) & 0xFF); -} - -// note random8(lim) generates numbers in the range 0 to (lim -1) -uint8_t WS2812FX::random8(uint8_t lim) { - uint8_t r = random8(); - r = (r * lim) >> 8; - return r; -} - -uint16_t WS2812FX::random16() { - return random8() * 256 + random8(); -} - -// note random16(lim) generates numbers in the range 0 to (lim - 1) -uint16_t WS2812FX::random16(uint16_t lim) { - uint16_t r = random16(); - r = (r * lim) >> 16; - return r; -} - -// Return the sum of all LED intensities (can be used for -// rudimentary power calculations) -uint32_t WS2812FX::intensitySum() { - uint8_t *pixels = getPixels(); - uint32_t sum = 0; - for(uint16_t i=0; i 255) lum = 511 - lum; // lum = 15 -> 255 -> 15 - - uint16_t delay; - if(lum == 15) delay = 970; // 970 pause before each breath - else if(lum <= 25) delay = 38; // 19 - else if(lum <= 50) delay = 36; // 18 - else if(lum <= 75) delay = 28; // 14 - else if(lum <= 100) delay = 20; // 10 - else if(lum <= 125) delay = 14; // 7 - else if(lum <= 150) delay = 11; // 5 - else delay = 10; // 4 - - uint32_t color = SEGMENT.colors[0]; - uint8_t w = (color >> 24 & 0xFF) * lum / 256; - uint8_t r = (color >> 16 & 0xFF) * lum / 256; - uint8_t g = (color >> 8 & 0xFF) * lum / 256; - uint8_t b = (color & 0xFF) * lum / 256; - for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { - setPixelColor(i, r, g, b, w); - } - - SEGMENT_RUNTIME.counter_mode_step += 2; - if(SEGMENT_RUNTIME.counter_mode_step > (512-15)) SEGMENT_RUNTIME.counter_mode_step = 15; - return delay; -} - - -/* - * Fades the LEDs between two colors - */ -uint16_t WS2812FX::mode_fade(void) { - int lum = SEGMENT_RUNTIME.counter_mode_step; - if(lum > 255) lum = 511 - lum; // lum = 0 -> 255 -> 0 - - uint32_t color = color_blend(SEGMENT.colors[0], SEGMENT.colors[1], lum); - for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { - setPixelColor(i, color); - } - - SEGMENT_RUNTIME.counter_mode_step += 4; - if(SEGMENT_RUNTIME.counter_mode_step > 511) SEGMENT_RUNTIME.counter_mode_step = 0; - return (SEGMENT.speed / 128); -} - - -/* - * scan function - runs a block of pixels back and forth. - */ -uint16_t WS2812FX::scan(uint32_t color1, uint32_t color2, bool dual) { - int8_t dir = SEGMENT_RUNTIME.aux_param ? -1 : 1; - uint8_t size = 1 << SIZE_OPTION; - - for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { - setPixelColor(i, color2); - } - - for(uint8_t i = 0; i < size; i++) { - if(IS_REVERSE || dual) { - setPixelColor(SEGMENT.stop - SEGMENT_RUNTIME.counter_mode_step - i, color1); - } - if(!IS_REVERSE || dual) { - setPixelColor(SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step + i, color1); - } - } - - SEGMENT_RUNTIME.counter_mode_step += dir; - if(SEGMENT_RUNTIME.counter_mode_step == 0) SEGMENT_RUNTIME.aux_param = 0; - if(SEGMENT_RUNTIME.counter_mode_step >= (SEGMENT_LENGTH - size)) SEGMENT_RUNTIME.aux_param = 1; - - return (SEGMENT.speed / (SEGMENT_LENGTH * 2)); -} - - -/* - * Runs a block of pixels back and forth. - */ -uint16_t WS2812FX::mode_scan(void) { - return scan(SEGMENT.colors[0], SEGMENT.colors[1], false); -} - - -/* - * Runs two blocks of pixels back and forth in opposite directions. - */ -uint16_t WS2812FX::mode_dual_scan(void) { - return scan(SEGMENT.colors[0], SEGMENT.colors[1], true); -} - - -/* - * Cycles all LEDs at once through a rainbow. - */ -uint16_t WS2812FX::mode_rainbow(void) { - uint32_t color = color_wheel(SEGMENT_RUNTIME.counter_mode_step); - for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { - setPixelColor(i, color); - } - - SEGMENT_RUNTIME.counter_mode_step = (SEGMENT_RUNTIME.counter_mode_step + 1) & 0xFF; - return (SEGMENT.speed / 256); -} - - -/* - * Cycles a rainbow over the entire string of LEDs. - */ -uint16_t WS2812FX::mode_rainbow_cycle(void) { - for(uint16_t i=0; i < SEGMENT_LENGTH; i++) { - uint32_t color = color_wheel(((i * 256 / SEGMENT_LENGTH) + SEGMENT_RUNTIME.counter_mode_step) & 0xFF); - setPixelColor(SEGMENT.start + i, color); - } - - SEGMENT_RUNTIME.counter_mode_step = (SEGMENT_RUNTIME.counter_mode_step + 1) & 0xFF; - return (SEGMENT.speed / 256); -} - - -/* - * Theatre-style crawling lights. - * Inspired by the Adafruit examples. - */ -uint16_t WS2812FX::mode_theater_chase(void) { - return tricolor_chase(SEGMENT.colors[0], SEGMENT.colors[1], SEGMENT.colors[1]); -} - - -/* - * Theatre-style crawling lights with rainbow effect. - * Inspired by the Adafruit examples. - */ -uint16_t WS2812FX::mode_theater_chase_rainbow(void) { - SEGMENT_RUNTIME.counter_mode_step = (SEGMENT_RUNTIME.counter_mode_step + 1) & 0xFF; - uint32_t color = color_wheel(SEGMENT_RUNTIME.counter_mode_step); - return tricolor_chase(color, SEGMENT.colors[1], SEGMENT.colors[1]); -} - - -/* - * Running lights effect with smooth sine transition. - */ -uint16_t WS2812FX::mode_running_lights(void) { - uint8_t w = ((SEGMENT.colors[0] >> 24) & 0xFF); - uint8_t r = ((SEGMENT.colors[0] >> 16) & 0xFF); - uint8_t g = ((SEGMENT.colors[0] >> 8) & 0xFF); - uint8_t b = (SEGMENT.colors[0] & 0xFF); - - uint8_t sineIncr = max(1, (256 / SEGMENT_LENGTH)); - for(uint16_t i=0; i < SEGMENT_LENGTH; i++) { - int lum = (int)sine8(((i + SEGMENT_RUNTIME.counter_mode_step) * sineIncr)); - if(IS_REVERSE) { - setPixelColor(SEGMENT.start + i, (r * lum) / 256, (g * lum) / 256, (b * lum) / 256, (w * lum) / 256); - } else { - setPixelColor(SEGMENT.stop - i, (r * lum) / 256, (g * lum) / 256, (b * lum) / 256, (w * lum) / 256); - } - } - SEGMENT_RUNTIME.counter_mode_step = (SEGMENT_RUNTIME.counter_mode_step + 1) % 256; - return (SEGMENT.speed / SEGMENT_LENGTH); -} - - -/* - * twinkle function - */ -uint16_t WS2812FX::twinkle(uint32_t color1, uint32_t color2) { - if(SEGMENT_RUNTIME.counter_mode_step == 0) { - for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { - setPixelColor(i, color2); - } - uint16_t min_leds = max(1, SEGMENT_LENGTH / 5); // make sure, at least one LED is on - uint16_t max_leds = max(1, SEGMENT_LENGTH / 2); // make sure, at least one LED is on - SEGMENT_RUNTIME.counter_mode_step = random(min_leds, max_leds); - } - - setPixelColor(SEGMENT.start + random16(SEGMENT_LENGTH), color1); - - SEGMENT_RUNTIME.counter_mode_step--; - return (SEGMENT.speed / SEGMENT_LENGTH); -} - -/* - * Blink several LEDs on, reset, repeat. - * Inspired by www.tweaking4all.com/hardware/arduino/arduino-led-strip-effects/ - */ -uint16_t WS2812FX::mode_twinkle(void) { - return twinkle(SEGMENT.colors[0], SEGMENT.colors[1]); -} - -/* - * Blink several LEDs in random colors on, reset, repeat. - * Inspired by www.tweaking4all.com/hardware/arduino/arduino-led-strip-effects/ - */ -uint16_t WS2812FX::mode_twinkle_random(void) { - return twinkle(color_wheel(random8()), SEGMENT.colors[1]); -} - - -/* - * fade out function - */ -void WS2812FX::fade_out() { - static const uint8_t rateMapH[] = {0, 1, 1, 1, 2, 3, 4, 6}; - static const uint8_t rateMapL[] = {0, 2, 3, 8, 8, 8, 8, 8}; - - uint8_t rate = FADE_RATE; - uint8_t rateH = rateMapH[rate]; - uint8_t rateL = rateMapL[rate]; - - uint32_t color = SEGMENT.colors[1]; // target color - int w2 = (color >> 24) & 0xff; - int r2 = (color >> 16) & 0xff; - int g2 = (color >> 8) & 0xff; - int b2 = color & 0xff; - - for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { - color = getPixelColor(i); - if(rate == 0) { // old fade-to-black algorithm - setPixelColor(i, (color >> 1) & 0x7F7F7F7F); - } else { // new fade-to-color algorithm - int w1 = (color >> 24) & 0xff; // current color - int r1 = (color >> 16) & 0xff; - int g1 = (color >> 8) & 0xff; - int b1 = color & 0xff; - - // calculate the color differences between the current and target colors - int wdelta = w2 - w1; - int rdelta = r2 - r1; - int gdelta = g2 - g1; - int bdelta = b2 - b1; - - // if the current and target colors are almost the same, jump right to the target - // color, otherwise calculate an intermediate color. (fixes rounding issues) - wdelta = abs(wdelta) < 3 ? wdelta : (wdelta >> rateH) + (wdelta >> rateL); - rdelta = abs(rdelta) < 3 ? rdelta : (rdelta >> rateH) + (rdelta >> rateL); - gdelta = abs(gdelta) < 3 ? gdelta : (gdelta >> rateH) + (gdelta >> rateL); - bdelta = abs(bdelta) < 3 ? bdelta : (bdelta >> rateH) + (bdelta >> rateL); - - setPixelColor(i, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); - } - } -} - - -/* - * color blend function - */ -uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) { - if(blend == 0) return color1; - if(blend == 255) return color2; - - uint8_t w1 = (color1 >> 24) & 0xff; - uint8_t r1 = (color1 >> 16) & 0xff; - uint8_t g1 = (color1 >> 8) & 0xff; - uint8_t b1 = color1 & 0xff; - - uint8_t w2 = (color2 >> 24) & 0xff; - uint8_t r2 = (color2 >> 16) & 0xff; - uint8_t g2 = (color2 >> 8) & 0xff; - uint8_t b2 = color2 & 0xff; - - uint32_t w3 = ((w2 * blend) + (w1 * (255U - blend))) / 256U; - uint32_t r3 = ((r2 * blend) + (r1 * (255U - blend))) / 256U; - uint32_t g3 = ((g2 * blend) + (g1 * (255U - blend))) / 256U; - uint32_t b3 = ((b2 * blend) + (b1 * (255U - blend))) / 256U; - - return ((w3 << 24) | (r3 << 16) | (g3 << 8) | (b3)); -} - - -/* - * twinkle_fade function - */ -uint16_t WS2812FX::twinkle_fade(uint32_t color) { - fade_out(); - - if(random8(3) == 0) { - uint8_t size = 1 << SIZE_OPTION; - uint16_t index = SEGMENT.start + random16(SEGMENT_LENGTH - size); - for(uint8_t i=0; i= ((SEGMENT_LENGTH * 2) - 2)) { - SEGMENT_RUNTIME.counter_mode_step = 0; - } - - return (SEGMENT.speed / (SEGMENT_LENGTH * 2)); -} - - -/* - * Firing comets from one end. - */ -uint16_t WS2812FX::mode_comet(void) { - fade_out(); - - if(IS_REVERSE) { - setPixelColor(SEGMENT.stop - SEGMENT_RUNTIME.counter_mode_step, SEGMENT.colors[0]); - } else { - setPixelColor(SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step, SEGMENT.colors[0]); - } - - SEGMENT_RUNTIME.counter_mode_step = (SEGMENT_RUNTIME.counter_mode_step + 1) % SEGMENT_LENGTH; - return (SEGMENT.speed / SEGMENT_LENGTH); -} - - -/* - * Fireworks function. - */ -uint16_t WS2812FX::fireworks(uint32_t color) { - fade_out(); - -// for better performance, manipulate the Adafruit_NeoPixels pixels[] array directly - uint8_t *pixels = getPixels(); - uint8_t bytesPerPixel = (wOffset == rOffset) ? 3 : 4; // 3=RGB, 4=RGBW - uint16_t startPixel = SEGMENT.start * bytesPerPixel + bytesPerPixel; - uint16_t stopPixel = SEGMENT.stop * bytesPerPixel ; - for(uint16_t i=startPixel; i > 2) + - pixels[i] + - (pixels[i + bytesPerPixel] >> 2); - pixels[i] = tmpPixel > 255 ? 255 : tmpPixel; - } - - uint8_t size = 2 << SIZE_OPTION; - if(!_triggered) { - for(uint16_t i=0; i> 24) & 0xFF; - byte r = (SEGMENT.colors[0] >> 16) & 0xFF; - byte g = (SEGMENT.colors[0] >> 8) & 0xFF; - byte b = (SEGMENT.colors[0] & 0xFF); - byte lum = max(w, max(r, max(g, b))) / rev_intensity; - for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) { - int flicker = random8(lum); - setPixelColor(i, max(r - flicker, 0), max(g - flicker, 0), max(b - flicker, 0), max(w - flicker, 0)); - } - return (SEGMENT.speed / SEGMENT_LENGTH); -} - -/* - * Random flickering. - */ -uint16_t WS2812FX::mode_fire_flicker(void) { - return fire_flicker(3); -} - -/* -* Random flickering, less intensity. -*/ -uint16_t WS2812FX::mode_fire_flicker_soft(void) { - return fire_flicker(6); -} - -/* -* Random flickering, more intensity. -*/ -uint16_t WS2812FX::mode_fire_flicker_intense(void) { - return fire_flicker(1.7); -} - - -/* - * Tricolor chase function - */ -uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2, uint32_t color3) { - uint8_t sizeCnt = 1 << SIZE_OPTION; - uint16_t index = SEGMENT_RUNTIME.counter_mode_call % (sizeCnt * 3); - for(uint16_t i=0; i < SEGMENT_LENGTH; i++, index++) { - index = index % (sizeCnt * 3); - - uint32_t color = color3; - if(index < sizeCnt) color = color1; - else if(index < (sizeCnt * 2)) color = color2; - - if(IS_REVERSE) { - setPixelColor(SEGMENT.start + i, color); - } else { - setPixelColor(SEGMENT.stop - i, color); - } - } - - return (SEGMENT.speed / SEGMENT_LENGTH); -} - - -/* - * Tricolor chase mode - */ -uint16_t WS2812FX::mode_tricolor_chase(void) { - return tricolor_chase(SEGMENT.colors[0], SEGMENT.colors[1], SEGMENT.colors[2]); -} - - -/* - * Alternating white/red/black pixels running. - */ -uint16_t WS2812FX::mode_circus_combustus(void) { - return tricolor_chase(RED, WHITE, BLACK); -} - -/* - * ICU mode - */ -uint16_t WS2812FX::mode_icu(void) { - uint16_t dest = SEGMENT_RUNTIME.counter_mode_step & 0xFFFF; - - setPixelColor(SEGMENT.start + dest, SEGMENT.colors[0]); - setPixelColor(SEGMENT.start + dest + SEGMENT_LENGTH/2, SEGMENT.colors[0]); - - if(SEGMENT_RUNTIME.aux_param3 == dest) { // pause between eye movements - if(random8(6) == 0) { // blink once in a while - setPixelColor(SEGMENT.start + dest, BLACK); - setPixelColor(SEGMENT.start + dest + SEGMENT_LENGTH/2, BLACK); - return 200; - } - SEGMENT_RUNTIME.aux_param3 = random16(SEGMENT_LENGTH/2); - return 1000 + random16(2000); - } - - setPixelColor(SEGMENT.start + dest, BLACK); - setPixelColor(SEGMENT.start + dest + SEGMENT_LENGTH/2, BLACK); - - if(SEGMENT_RUNTIME.aux_param3 > SEGMENT_RUNTIME.counter_mode_step) { - SEGMENT_RUNTIME.counter_mode_step++; - dest++; - } else if (SEGMENT_RUNTIME.aux_param3 < SEGMENT_RUNTIME.counter_mode_step) { - SEGMENT_RUNTIME.counter_mode_step--; - dest--; - } - - setPixelColor(SEGMENT.start + dest, SEGMENT.colors[0]); - setPixelColor(SEGMENT.start + dest + SEGMENT_LENGTH/2, SEGMENT.colors[0]); - - return (SEGMENT.speed / SEGMENT_LENGTH); -} - -/* - * Custom modes - */ -uint16_t WS2812FX::mode_custom_0() { - return customModes[0](); -} -uint16_t WS2812FX::mode_custom_1() { - return customModes[1](); -} -uint16_t WS2812FX::mode_custom_2() { - return customModes[2](); -} -uint16_t WS2812FX::mode_custom_3() { - return customModes[3](); -} - -/* - * Custom mode helpers - */ -void WS2812FX::setCustomMode(uint16_t (*p)()) { - customModes[0] = p; -} - -uint8_t WS2812FX::setCustomMode(const __FlashStringHelper* name, uint16_t (*p)()) { - static uint8_t custom_mode_index = 0; - return setCustomMode(custom_mode_index++, name, p); -} - -uint8_t WS2812FX::setCustomMode(uint8_t index, const __FlashStringHelper* name, uint16_t (*p)()) { - if((FX_MODE_CUSTOM_0 + index) < MODE_COUNT) { - _names[FX_MODE_CUSTOM_0 + index] = name; // store the custom mode name - customModes[index] = p; // store the custom mode - - return (FX_MODE_CUSTOM_0 + index); - } - return 0; -} - -/* - * Custom show helper - */ -void WS2812FX::setCustomShow(void (*p)()) { - customShow = p; -} diff --git a/Arduino/McLighting/WS2812FX.h b/Arduino/McLighting/WS2812FX.h deleted file mode 100644 index 0c2503a..0000000 --- a/Arduino/McLighting/WS2812FX.h +++ /dev/null @@ -1,613 +0,0 @@ -/* - 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) - 2017-02-02 added external trigger functionality (e.g. for sound-to-light) -*/ - -#ifndef WS2812FX_h -#define WS2812FX_h - -#define FSH(x) (__FlashStringHelper*)(x) - -#include - -#define DEFAULT_BRIGHTNESS (uint8_t)50 -#define DEFAULT_MODE (uint8_t)0 -#define DEFAULT_SPEED (uint16_t)1000 -#define DEFAULT_COLOR (uint32_t)0xFF0000 - -#if defined(ESP8266) || defined(ESP32) - //#pragma message("Compiling for ESP") - #define SPEED_MIN (uint16_t)2 -#else - //#pragma message("Compiling for Arduino") - #define SPEED_MIN (uint16_t)10 -#endif -#define SPEED_MAX (uint16_t)65535 - -#define BRIGHTNESS_MIN (uint8_t)0 -#define BRIGHTNESS_MAX (uint8_t)255 - -/* each segment uses 36 bytes of SRAM memory, so if you're application fails because of - insufficient memory, decreasing MAX_NUM_SEGMENTS may help */ -#define MAX_NUM_SEGMENTS 10 -#define NUM_COLORS 3 /* number of colors per segment */ -#define MAX_CUSTOM_MODES 4 -#define SEGMENT _segments[_segment_index] -#define SEGMENT_RUNTIME _segment_runtimes[_segment_index] -#define SEGMENT_LENGTH (SEGMENT.stop - SEGMENT.start + 1) - -// some common colors -#define RED (uint32_t)0xFF0000 -#define GREEN (uint32_t)0x00FF00 -#define BLUE (uint32_t)0x0000FF -#define WHITE (uint32_t)0xFFFFFF -#define BLACK (uint32_t)0x000000 -#define YELLOW (uint32_t)0xFFFF00 -#define CYAN (uint32_t)0x00FFFF -#define MAGENTA (uint32_t)0xFF00FF -#define PURPLE (uint32_t)0x400080 -#define ORANGE (uint32_t)0xFF3000 -#define PINK (uint32_t)0xFF1493 -#define ULTRAWHITE (uint32_t)0xFFFFFFFF -#define DARK(c) (uint32_t)((c >> 4) & 0x0f0f0f0f) - -// segment options -// bit 7: reverse animation -// bits 4-6: fade rate (0-7) -// bit 3: gamma correction -// bits 1-2: size -// bits 0: TBD -#define NO_OPTIONS (uint8_t)B00000000 -#define REVERSE (uint8_t)B10000000 -#define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE) -#define FADE_XFAST (uint8_t)B00010000 -#define FADE_FAST (uint8_t)B00100000 -#define FADE_MEDIUM (uint8_t)B00110000 -#define FADE_SLOW (uint8_t)B01000000 -#define FADE_XSLOW (uint8_t)B01010000 -#define FADE_XXSLOW (uint8_t)B01100000 -#define FADE_GLACIAL (uint8_t)B01110000 -#define FADE_RATE ((SEGMENT.options >> 4) & 7) -#define GAMMA (uint8_t)B00001000 -#define IS_GAMMA ((SEGMENT.options & GAMMA) == GAMMA) -#define SIZE_SMALL (uint8_t)B00000000 -#define SIZE_MEDIUM (uint8_t)B00000010 -#define SIZE_LARGE (uint8_t)B00000100 -#define SIZE_XLARGE (uint8_t)B00000110 -#define SIZE_OPTION ((SEGMENT.options >> 1) & 3) - -// segment runtime options (aux_param2) -#define FRAME (uint8_t)B10000000 -#define SET_FRAME (SEGMENT_RUNTIME.aux_param2 |= FRAME) -#define CLR_FRAME (SEGMENT_RUNTIME.aux_param2 &= ~FRAME) -#define CYCLE (uint8_t)B01000000 -#define SET_CYCLE (SEGMENT_RUNTIME.aux_param2 |= CYCLE) -#define CLR_CYCLE (SEGMENT_RUNTIME.aux_param2 &= ~CYCLE) - -#define MODE_COUNT (sizeof(_names)/sizeof(_names[0])) - -#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_INV 4 -#define FX_MODE_COLOR_WIPE_REV 5 -#define FX_MODE_COLOR_WIPE_REV_INV 6 -#define FX_MODE_COLOR_WIPE_RANDOM 7 -#define FX_MODE_RANDOM_COLOR 8 -#define FX_MODE_SINGLE_DYNAMIC 9 -#define FX_MODE_MULTI_DYNAMIC 10 -#define FX_MODE_RAINBOW 11 -#define FX_MODE_RAINBOW_CYCLE 12 -#define FX_MODE_SCAN 13 -#define FX_MODE_DUAL_SCAN 14 -#define FX_MODE_FADE 15 -#define FX_MODE_THEATER_CHASE 16 -#define FX_MODE_THEATER_CHASE_RAINBOW 17 -#define FX_MODE_RUNNING_LIGHTS 18 -#define FX_MODE_TWINKLE 19 -#define FX_MODE_TWINKLE_RANDOM 20 -#define FX_MODE_TWINKLE_FADE 21 -#define FX_MODE_TWINKLE_FADE_RANDOM 22 -#define FX_MODE_SPARKLE 23 -#define FX_MODE_FLASH_SPARKLE 24 -#define FX_MODE_HYPER_SPARKLE 25 -#define FX_MODE_STROBE 26 -#define FX_MODE_STROBE_RAINBOW 27 -#define FX_MODE_MULTI_STROBE 28 -#define FX_MODE_BLINK_RAINBOW 29 -#define FX_MODE_CHASE_WHITE 30 -#define FX_MODE_CHASE_COLOR 31 -#define FX_MODE_CHASE_RANDOM 32 -#define FX_MODE_CHASE_RAINBOW 33 -#define FX_MODE_CHASE_FLASH 34 -#define FX_MODE_CHASE_FLASH_RANDOM 35 -#define FX_MODE_CHASE_RAINBOW_WHITE 36 -#define FX_MODE_CHASE_BLACKOUT 37 -#define FX_MODE_CHASE_BLACKOUT_RAINBOW 38 -#define FX_MODE_COLOR_SWEEP_RANDOM 39 -#define FX_MODE_RUNNING_COLOR 40 -#define FX_MODE_RUNNING_RED_BLUE 41 -#define FX_MODE_RUNNING_RANDOM 42 -#define FX_MODE_LARSON_SCANNER 43 -#define FX_MODE_COMET 44 -#define FX_MODE_FIREWORKS 45 -#define FX_MODE_FIREWORKS_RANDOM 46 -#define FX_MODE_MERRY_CHRISTMAS 47 -#define FX_MODE_FIRE_FLICKER 48 -#define FX_MODE_FIRE_FLICKER_SOFT 49 -#define FX_MODE_FIRE_FLICKER_INTENSE 50 -#define FX_MODE_CIRCUS_COMBUSTUS 51 -#define FX_MODE_HALLOWEEN 52 -#define FX_MODE_BICOLOR_CHASE 53 -#define FX_MODE_TRICOLOR_CHASE 54 -#define FX_MODE_ICU 55 -#define FX_MODE_CUSTOM 56 // keep this for backward compatiblity -#define FX_MODE_CUSTOM_0 56 // custom modes need to go at the end -#define FX_MODE_CUSTOM_1 57 -#define FX_MODE_CUSTOM_2 58 -#define FX_MODE_CUSTOM_3 59 - -// create GLOBAL names to allow WS2812FX to compile with sketches and other libs that store strings -// in PROGMEM (get rid of the "section type conflict with __c" errors once and for all. Amen.) -const char name_0[] PROGMEM = "Static"; -const char name_1[] PROGMEM = "Blink"; -const char name_2[] PROGMEM = "Breath"; -const char name_3[] PROGMEM = "Color Wipe"; -const char name_4[] PROGMEM = "Color Wipe Inverse"; -const char name_5[] PROGMEM = "Color Wipe Reverse"; -const char name_6[] PROGMEM = "Color Wipe Reverse Inverse"; -const char name_7[] PROGMEM = "Color Wipe Random"; -const char name_8[] PROGMEM = "Random Color"; -const char name_9[] PROGMEM = "Single Dynamic"; -const char name_10[] PROGMEM = "Multi Dynamic"; -const char name_11[] PROGMEM = "Rainbow"; -const char name_12[] PROGMEM = "Rainbow Cycle"; -const char name_13[] PROGMEM = "Scan"; -const char name_14[] PROGMEM = "Dual Scan"; -const char name_15[] PROGMEM = "Fade"; -const char name_16[] PROGMEM = "Theater Chase"; -const char name_17[] PROGMEM = "Theater Chase Rainbow"; -const char name_18[] PROGMEM = "Running Lights"; -const char name_19[] PROGMEM = "Twinkle"; -const char name_20[] PROGMEM = "Twinkle Random"; -const char name_21[] PROGMEM = "Twinkle Fade"; -const char name_22[] PROGMEM = "Twinkle Fade Random"; -const char name_23[] PROGMEM = "Sparkle"; -const char name_24[] PROGMEM = "Flash Sparkle"; -const char name_25[] PROGMEM = "Hyper Sparkle"; -const char name_26[] PROGMEM = "Strobe"; -const char name_27[] PROGMEM = "Strobe Rainbow"; -const char name_28[] PROGMEM = "Multi Strobe"; -const char name_29[] PROGMEM = "Blink Rainbow"; -const char name_30[] PROGMEM = "Chase White"; -const char name_31[] PROGMEM = "Chase Color"; -const char name_32[] PROGMEM = "Chase Random"; -const char name_33[] PROGMEM = "Chase Rainbow"; -const char name_34[] PROGMEM = "Chase Flash"; -const char name_35[] PROGMEM = "Chase Flash Random"; -const char name_36[] PROGMEM = "Chase Rainbow White"; -const char name_37[] PROGMEM = "Chase Blackout"; -const char name_38[] PROGMEM = "Chase Blackout Rainbow"; -const char name_39[] PROGMEM = "Color Sweep Random"; -const char name_40[] PROGMEM = "Running Color"; -const char name_41[] PROGMEM = "Running Red Blue"; -const char name_42[] PROGMEM = "Running Random"; -const char name_43[] PROGMEM = "Larson Scanner"; -const char name_44[] PROGMEM = "Comet"; -const char name_45[] PROGMEM = "Fireworks"; -const char name_46[] PROGMEM = "Fireworks Random"; -const char name_47[] PROGMEM = "Merry Christmas"; -const char name_48[] PROGMEM = "Fire Flicker"; -const char name_49[] PROGMEM = "Fire Flicker (soft)"; -const char name_50[] PROGMEM = "Fire Flicker (intense)"; -const char name_51[] PROGMEM = "Circus Combustus"; -const char name_52[] PROGMEM = "Halloween"; -const char name_53[] PROGMEM = "Bicolor Chase"; -const char name_54[] PROGMEM = "Tricolor Chase"; -const char name_55[] PROGMEM = "ICU"; -const char name_56[] PROGMEM = "Custom 0"; // custom modes need to go at the end -const char name_57[] PROGMEM = "Custom 1"; -const char name_58[] PROGMEM = "Custom 2"; -const char name_59[] PROGMEM = "Custom 3"; - -static const __FlashStringHelper* _names[] = { - FSH(name_0), - FSH(name_1), - FSH(name_2), - FSH(name_3), - FSH(name_4), - FSH(name_5), - FSH(name_6), - FSH(name_7), - FSH(name_8), - FSH(name_9), - FSH(name_10), - FSH(name_11), - FSH(name_12), - FSH(name_13), - FSH(name_14), - FSH(name_15), - FSH(name_16), - FSH(name_17), - FSH(name_18), - FSH(name_19), - FSH(name_20), - FSH(name_21), - FSH(name_22), - FSH(name_23), - FSH(name_24), - FSH(name_25), - FSH(name_26), - FSH(name_27), - FSH(name_28), - FSH(name_29), - FSH(name_30), - FSH(name_31), - FSH(name_32), - FSH(name_33), - FSH(name_34), - FSH(name_35), - FSH(name_36), - FSH(name_37), - FSH(name_38), - FSH(name_39), - FSH(name_40), - FSH(name_41), - FSH(name_42), - FSH(name_43), - FSH(name_44), - FSH(name_45), - FSH(name_46), - FSH(name_47), - FSH(name_48), - FSH(name_49), - FSH(name_50), - FSH(name_51), - FSH(name_52), - FSH(name_53), - FSH(name_54), - FSH(name_55), - FSH(name_56), - FSH(name_57), - FSH(name_58), - FSH(name_59) -}; - -class WS2812FX : public Adafruit_NeoPixel { - - typedef uint16_t (WS2812FX::*mode_ptr)(void); - - // segment parameters - public: - typedef struct Segment { // 20 bytes - uint16_t start; - uint16_t stop; - uint16_t speed; - uint8_t mode; - uint8_t options; - uint32_t colors[NUM_COLORS]; - } segment; - - // segment runtime parameters - typedef struct Segment_runtime { // 16 bytes - unsigned long next_time; - uint32_t counter_mode_step; - uint32_t counter_mode_call; - uint8_t aux_param; // auxilary param (usually stores a color_wheel index) - uint8_t aux_param2; // auxilary param (usually stores bitwise options) - uint16_t aux_param3; // auxilary param (usually stores a segment index) - } segment_runtime; - - 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_COLOR_WIPE] = &WS2812FX::mode_color_wipe; - _mode[FX_MODE_COLOR_WIPE_INV] = &WS2812FX::mode_color_wipe_inv; - _mode[FX_MODE_COLOR_WIPE_REV] = &WS2812FX::mode_color_wipe_rev; - _mode[FX_MODE_COLOR_WIPE_REV_INV] = &WS2812FX::mode_color_wipe_rev_inv; - _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_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_FIRE_FLICKER_INTENSE] = &WS2812FX::mode_fire_flicker_intense; - _mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus; - _mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween; - _mode[FX_MODE_BICOLOR_CHASE] = &WS2812FX::mode_bicolor_chase; - _mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase; -// if flash memory is constrained (I'm looking at you Arduino Nano), replace modes -// that use a lot of flash with mode_static (reduces flash footprint by about 2100 bytes) -#ifdef REDUCED_MODES - _mode[FX_MODE_BREATH] = &WS2812FX::mode_static; - _mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_static; - _mode[FX_MODE_ICU] = &WS2812FX::mode_static; -#else - _mode[FX_MODE_BREATH] = &WS2812FX::mode_breath; - _mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights; - _mode[FX_MODE_ICU] = &WS2812FX::mode_icu; -#endif - _mode[FX_MODE_CUSTOM_0] = &WS2812FX::mode_custom_0; - _mode[FX_MODE_CUSTOM_1] = &WS2812FX::mode_custom_1; - _mode[FX_MODE_CUSTOM_2] = &WS2812FX::mode_custom_2; - _mode[FX_MODE_CUSTOM_3] = &WS2812FX::mode_custom_3; - - brightness = DEFAULT_BRIGHTNESS + 1; // Adafruit_NeoPixel internally offsets brightness by 1 - _running = false; - _num_segments = 1; - _segments[0].mode = DEFAULT_MODE; - _segments[0].colors[0] = DEFAULT_COLOR; - _segments[0].start = 0; - _segments[0].stop = n - 1; - _segments[0].speed = DEFAULT_SPEED; - resetSegmentRuntimes(); - } - - void -// timer(void), - init(void), - service(void), - start(void), - stop(void), - pause(void), - resume(void), - strip_off(void), - fade_out(void), - setMode(uint8_t m), - setMode(uint8_t seg, uint8_t m), - setOptions(uint8_t seg, uint8_t o), - setCustomMode(uint16_t (*p)()), - setCustomShow(void (*p)()), - setSpeed(uint16_t s), - setSpeed(uint8_t seg, uint16_t s), - increaseSpeed(uint8_t s), - decreaseSpeed(uint8_t s), - setColor(uint8_t r, uint8_t g, uint8_t b), - setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w), - setColor(uint32_t c), - setColor(uint8_t seg, uint32_t c), - setColors(uint8_t seg, uint32_t* c), - setBrightness(uint8_t b), - increaseBrightness(uint8_t s), - decreaseBrightness(uint8_t s), - setLength(uint16_t b), - increaseLength(uint16_t s), - decreaseLength(uint16_t s), - trigger(void), - setNumSegments(uint8_t n), - setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, bool reverse), - setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, uint8_t options), - setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, bool reverse), - setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, uint8_t options), - resetSegments(), - resetSegmentRuntimes(), - resetSegmentRuntime(uint8_t), - setPixelColor(uint16_t n, uint32_t c), - setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b), - setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w), - copyPixels(uint16_t d, uint16_t s, uint16_t c), - show(void); - - boolean - isRunning(void), - isTriggered(void), - isFrame(void), - isFrame(uint8_t), - isCycle(void), - isCycle(uint8_t); - - uint8_t - random8(void), - random8(uint8_t), - getMode(void), - getMode(uint8_t), - getModeCount(void), - setCustomMode(const __FlashStringHelper* name, uint16_t (*p)()), - setCustomMode(uint8_t i, const __FlashStringHelper* name, uint16_t (*p)()), - getNumSegments(void), - get_random_wheel_index(uint8_t), - getOptions(uint8_t); - - uint16_t - random16(void), - random16(uint16_t), - getSpeed(void), - getSpeed(uint8_t), - getLength(void), - getNumBytes(void); - - uint32_t - color_wheel(uint8_t), - getColor(void), - getColor(uint8_t), - intensitySum(void); - - uint32_t* getColors(uint8_t); - uint32_t* intensitySums(void); - - const __FlashStringHelper* getModeName(uint8_t m); - - WS2812FX::Segment* getSegment(void); - - WS2812FX::Segment* getSegment(uint8_t); - - WS2812FX::Segment* getSegments(void); - - WS2812FX::Segment_runtime* getSegmentRuntime(void); - - WS2812FX::Segment_runtime* getSegmentRuntime(uint8_t); - - WS2812FX::Segment_runtime* getSegmentRuntimes(void); - - // mode helper functions - uint16_t - blink(uint32_t, uint32_t, bool strobe), - color_wipe(uint32_t, uint32_t, bool), - twinkle(uint32_t, uint32_t), - twinkle_fade(uint32_t), - chase(uint32_t, uint32_t, uint32_t), - running(uint32_t, uint32_t), - fireworks(uint32_t), - fire_flicker(int), - tricolor_chase(uint32_t, uint32_t, uint32_t), - scan(uint32_t, uint32_t, bool); - uint32_t - color_blend(uint32_t, uint32_t, uint8_t); - - // builtin modes - uint16_t - mode_static(void), - mode_blink(void), - mode_blink_rainbow(void), - mode_strobe(void), - mode_strobe_rainbow(void), - mode_color_wipe(void), - mode_color_wipe_inv(void), - mode_color_wipe_rev(void), - mode_color_wipe_rev_inv(void), - mode_color_wipe_random(void), - mode_color_sweep_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_multi_strobe(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_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_halloween(void), - mode_fire_flicker(void), - mode_fire_flicker_soft(void), - mode_fire_flicker_intense(void), - mode_circus_combustus(void), - mode_bicolor_chase(void), - mode_tricolor_chase(void), - mode_icu(void), - mode_custom_0(void), - mode_custom_1(void), - mode_custom_2(void), - mode_custom_3(void); - - private: - uint16_t _rand16seed; - uint16_t (*customModes[MAX_CUSTOM_MODES])(void) { - []{ return (uint16_t)1000; }, - []{ return (uint16_t)1000; }, - []{ return (uint16_t)1000; }, - []{ return (uint16_t)1000; } - }; - void (*customShow)(void) = NULL; - - boolean - _running, - _triggered; - - mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element - - uint8_t _segment_index = 0; - uint8_t _num_segments = 1; - segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 20 bytes per element - // start, stop, speed, mode, options, color[] - { 0, 7, DEFAULT_SPEED, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}} - }; - segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element -}; - -#endif diff --git a/Arduino/McLighting/colormodes.h b/Arduino/McLighting/colormodes.h index 4873701..039c464 100644 --- a/Arduino/McLighting/colormodes.h +++ b/Arduino/McLighting/colormodes.h @@ -1,99 +1,100 @@ -// *************************************************************************** -// Color modes -// *************************************************************************** - -int dipInterval = 10; -int darkTime = 250; -unsigned long currentDipTime; -unsigned long dipStartTime; -unsigned long currentMillis; -int ledState = LOW; -long previousMillis = 0; -int led = 5; -int interval = 2000; -int twitch = 50; -int dipCount = 0; -int analogLevel = 100; -boolean timeToDip = false; -int ledStates[NUMLEDS]; - - -void hsb2rgbAN1(uint16_t index, uint8_t sat, uint8_t bright, uint8_t myled) { - // Source: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ - uint8_t temp[5], n = (index >> 8) % 3; - temp[0] = temp[3] = (uint8_t)(( (sat ^ 255) * bright) / 255); - temp[1] = temp[4] = (uint8_t)((((( (index & 255) * sat) / 255) + (sat ^ 255)) * bright) / 255); - temp[2] = (uint8_t)(((((((index & 255) ^ 255) * sat) / 255) + (sat ^ 255)) * bright) / 255); - - strip.setPixelColor(myled, temp[n + 2], temp[n + 1], temp[n], 0); -} - - -void updateLed (int led, int brightness) { - ledStates[led] = brightness; - - for (int i=0; i interval) - { - previousMillis = currentMillis; - interval = random(750,4001);//Adjusts the interval for more/less frequent random light changes - twitch = random(40,100);// Twitch provides motion effect but can be a bit much if too high - dipCount = dipCount++; - } - if(currentMillis-previousMillis dipInterval) - { - DBG_OUTPUT_PORT.println("dip"); - timeToDip = true; - dipCount = 0; - dipStartTime = millis(); - darkTime = random(50,150); - dipInterval = random(5,250);// cycles of flicker - } - //strip.show(); - } - } - else - { - DBG_OUTPUT_PORT.println("Dip Time"); - currentDipTime = millis(); - if (currentDipTime - dipStartTime < darkTime) - { - for (int i=3; i> 8) % 3; + temp[0] = temp[3] = (uint8_t)(( (sat ^ 255) * bright) / 255); + temp[1] = temp[4] = (uint8_t)((((( (index & 255) * sat) / 255) + (sat ^ 255)) * bright) / 255); + temp[2] = (uint8_t)(((((((index & 255) ^ 255) * sat) / 255) + (sat ^ 255)) * bright) / 255); + + strip.setPixelColor(myled, temp[n + 2], temp[n + 1], temp[n], 0); +} + + +void updateLed (int led, int brightness) { + ledStates[led] = brightness; + + for (int i=0; i interval) + { + previousMillis = currentMillis; + //interval = random(750,4001);//Adjusts the interval for more/less frequent random light changes + interval = random(1000-(ws2812fx_speed*2),5001-(ws2812fx_speed*8)); + twitch = random(40,100);// Twitch provides motion effect but can be a bit much if too high + dipCount = dipCount++; + } + if(currentMillis-previousMillis dipInterval) + { + DBG_OUTPUT_PORT.println("dip"); + timeToDip = true; + dipCount = 0; + dipStartTime = millis(); + darkTime = random(50,150); + dipInterval = random(5,250);// cycles of flicker + } + //strip.show(); + } + } + else + { + DBG_OUTPUT_PORT.println("Dip Time"); + currentDipTime = millis(); + if (currentDipTime - dipStartTime < darkTime) + { + for (int i=3; i - -extern WS2812FX ws2812fx; - -uint16_t blockDissolve(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); - WS2812FX::Segment_runtime* segrt = ws2812fx.getSegmentRuntime(); - int seglen = seg->stop - seg->start + 1; - - uint32_t color = seg->colors[segrt->aux_param]; - ws2812fx.setPixelColor(seg->start, color); - // get the decimated color after setPixelColor() has mangled it - // in accordance to the brightness setting - uint32_t desColor = ws2812fx.getPixelColor(seg->start); - - for(uint16_t i=0; istart + ws2812fx.random16(seglen); - if(ws2812fx.getPixelColor(index) != desColor) { - ws2812fx.setPixelColor(index, color); - return seg->speed; - } - } - - for(uint16_t i=seg->start; istop; i++) { - ws2812fx.setPixelColor(i, color); - } - - segrt->aux_param = (segrt->aux_param + 1) % NUM_COLORS; - return seg->speed; -} - -#endif diff --git a/Arduino/McLighting/custom/DualLarson.h b/Arduino/McLighting/custom/DualLarson.h deleted file mode 100644 index dcceff6..0000000 --- a/Arduino/McLighting/custom/DualLarson.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Custom effect that creates two Larson scanners moving in opposite directions. - If you set the REVERSE option, an offset will be added to the comet after each - cycle (so if the LEDs are arranged in a circle, the animation will appear to - "walk" around the circle.) - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-02-26 initial version -*/ - -#ifndef DualLarson_h -#define DualLarson_h - -#include - -extern WS2812FX ws2812fx; - -uint16_t dualLarson(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment - WS2812FX::Segment_runtime* segrt = ws2812fx.getSegmentRuntime(); - int seglen = seg->stop - seg->start + 1; - - static int16_t offset = 0; - int8_t dir = segrt->aux_param ? -1 : 1; - segrt->aux_param3 += dir; - - ws2812fx.fade_out(); - - int16_t segIndex = (segrt->aux_param3 + offset) % seglen; - ws2812fx.setPixelColor(seg->start + segIndex, seg->colors[0]); - ws2812fx.setPixelColor(seg->stop - segIndex, seg->colors[2]); - - if(segrt->aux_param3 >= (seg->stop - seg->start) || segrt->aux_param3 <= 0) { - segrt->aux_param = !segrt->aux_param; - if(seg->options & REVERSE) offset = (offset + 1) % seglen; - } - - return (seg->speed / (seglen * 2)); -} - -#endif diff --git a/Arduino/McLighting/custom/MultiComet.h b/Arduino/McLighting/custom/MultiComet.h deleted file mode 100644 index 8f0b850..0000000 --- a/Arduino/McLighting/custom/MultiComet.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Custom effect that creates random comets - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-02-26 initial version -*/ - -#ifndef MultiComet_h -#define MultiComet_h - -#include - -extern WS2812FX ws2812fx; - -uint16_t multiComet(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment - int seglen = seg->stop - seg->start + 1; - - bool isReverse = (seg->options & REVERSE) == REVERSE; - - ws2812fx.fade_out(); - - static int16_t comets[] = {UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX}; - static int8_t numComets = sizeof(comets)/sizeof(comets[0]); - - for(uint8_t i=0; i < numComets; i++) { - if(comets[i] < seglen) { - if(isReverse) { - ws2812fx.setPixelColor(seg->stop - comets[i], i % 2 ? seg->colors[0] : seg->colors[2]); - } else { - ws2812fx.setPixelColor(seg->start + comets[i], i % 2 ? seg->colors[0] : seg->colors[2]); - } - comets[i]++; - } else { - if(!random(seglen)) { - comets[i] = 0; - } - } - } - - return (seg->speed / seglen); -} - -#endif diff --git a/Arduino/McLighting/custom/Oscillate.h b/Arduino/McLighting/custom/Oscillate.h deleted file mode 100644 index d44c69a..0000000 --- a/Arduino/McLighting/custom/Oscillate.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Custom effect that creates three color spans that oscillate back and forth. - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-07-26 initial version -*/ - -#ifndef Oscillate_h -#define Oscillate_h - -#include - -extern WS2812FX ws2812fx; - -typedef struct Oscillator { - int16_t pos; - int8_t size; - int8_t dir; - int8_t speed; -} oscillator; - -uint16_t oscillate(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment - int seglen = seg->stop - seg->start + 1; - - static oscillator oscillators[NUM_COLORS] = { - {seglen/4, seglen/8, 1, 1}, - {seglen/4*2, seglen/8, -1, 1}, - {seglen/4*3, seglen/8, 1, 2} - }; - - for(int8_t i=0; i < sizeof(oscillators)/sizeof(oscillators[0]); i++) { - oscillators[i].pos += oscillators[i].dir * oscillators[i].speed; - if((oscillators[i].dir == -1) && (oscillators[i].pos <= 0)) { - oscillators[i].pos = 0; - oscillators[i].dir = 1; - oscillators[i].speed = random(1, 3); - } - if((oscillators[i].dir == 1) && (oscillators[i].pos >= (seglen - 1))) { - oscillators[i].pos = seglen - 1; - oscillators[i].dir = -1; - oscillators[i].speed = random(1, 3); - } - } - - for(int16_t i=0; i < seglen; i++) { - uint32_t color = BLACK; - for(int8_t j=0; j < sizeof(oscillators)/sizeof(oscillators[0]); j++) { - if(i >= oscillators[j].pos - oscillators[j].size && i <= oscillators[j].pos + oscillators[j].size) { - color = (color == BLACK) ? seg->colors[j] : ws2812fx.color_blend(color, seg->colors[j], 128); - } - } - ws2812fx.setPixelColor(seg->start + i, color); - } - return(seg->speed / 8); -} - -#endif diff --git a/Arduino/McLighting/custom/Popcorn.h b/Arduino/McLighting/custom/Popcorn.h deleted file mode 100644 index 53d2942..0000000 --- a/Arduino/McLighting/custom/Popcorn.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - Custom effect that looks like popcorn. - The 'popcorn' is color[0] and the background color is color[1]. - If color[0] is the same as color[1], the 'popcorn' will be a random color. - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-11-13 initial version -*/ - -#ifndef Popcorn_h -#define Popcorn_h - -#include - -#define MAX_NUM_POPCORN 10 -#define GRAVITY 0.1 - -extern WS2812FX ws2812fx; - -typedef struct Kernel { - float position; - float velocity; - int32_t color; -} kernel; - -uint16_t popcorn(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment - uint16_t seglen = seg->stop - seg->start + 1; - uint32_t popcornColor = seg->colors[0]; - uint32_t bgColor = seg->colors[1]; - if(popcornColor == bgColor) popcornColor = ws2812fx.color_wheel(ws2812fx.random8()); - bool isReverse = (seg->options & REVERSE) != 0; - - static kernel popcorn[MAX_NUM_POPCORN]; - static float coeff = 0.0f; - if(coeff == 0.0f) { // calculate the velocity coeff once (the secret sauce) - coeff = pow((float)seglen, 0.5223324f) * 0.3944296f; - } - - // reset all LEDs to background color - for(uint16_t i=seg->start; i <= seg->stop; i++) { - ws2812fx.setPixelColor(i, bgColor); - } - - uint16_t ledIndex; - for(int8_t i=0; i < MAX_NUM_POPCORN; i++) { - bool isActive = popcorn[i].position >= 0.0f; - - if(isActive) { // if kernel is active, update its position - popcorn[i].position += popcorn[i].velocity; - popcorn[i].velocity -= GRAVITY; - ledIndex = isReverse ? seg->stop - popcorn[i].position : seg->start + popcorn[i].position; - if(ledIndex >= seg->start && ledIndex <= seg->stop) ws2812fx.setPixelColor(ledIndex, popcorn[i].color); - } else { // if kernel is inactive, randomly pop it - if(ws2812fx.random8() < 2) { // POP!!! - popcorn[i].position = 0.0f; - popcorn[i].velocity = coeff * (random(66, 100) / 100.0f); - popcorn[i].color = popcornColor; - ledIndex = isReverse ? seg->stop : seg->start; - ws2812fx.setPixelColor(ledIndex, popcorn[i].color); - } - } - } - - return(seg->speed / seglen); -} - -#endif diff --git a/Arduino/McLighting/custom/Rain.h b/Arduino/McLighting/custom/Rain.h deleted file mode 100644 index 45045ae..0000000 --- a/Arduino/McLighting/custom/Rain.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Custom effect that combines the fireworks effect and running effect - to produce a rain-like effect. Depending on the size of your LED strip, you - may want to play with the FADE and SIZE options. - The background color is black, unless you use a FADE_RATE other then DEFAULT, - in which case the background color is color[1]. - The color of the rain is either color[0] or color[2] (chosen randomly), unless - color[0]==color[1], in which case the rain is a random color. - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-12-14 initial version -*/ - -#ifndef Rain_h -#define Rain_h - -#include - -extern WS2812FX ws2812fx; - -uint16_t rain(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment - uint16_t seglen = seg->stop - seg->start + 1; - uint32_t rainColor = (ws2812fx.random8() & 1) == 0 ? seg->colors[0] : seg->colors[2]; - if(seg->colors[0] == seg->colors[1]) rainColor = ws2812fx.color_wheel(ws2812fx.random8()); - - ws2812fx.fireworks(rainColor); - - // shift everything two pixels - bool isReverse = (seg->options & REVERSE) != 0; - if(isReverse) { - ws2812fx.copyPixels(seg->start + 2, seg->start, seglen - 2); - } else { - ws2812fx.copyPixels(seg->start, seg->start + 2, seglen - 2); - } - - return(seg->speed / seglen); -} - -#endif diff --git a/Arduino/McLighting/custom/RainbowLarson.h b/Arduino/McLighting/custom/RainbowLarson.h deleted file mode 100644 index 281803c..0000000 --- a/Arduino/McLighting/custom/RainbowLarson.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Custom effect that creates a Larson Scanner with rainbow colors - It has two modes: - 1) if the segment options parameter is set to NO_OPTIONS, then - the rainbow of colors span the 'comet'. - 2) if the segment options parameter is set to a FADE option - (e.g. FADE_MEDIUM), then the rainbow of colors span the segment - and the 'comet' merely shows the colors at that point in the segment. - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-08-26 initial version -*/ - -#ifndef RainbowLarson_h -#define RainbowLarson_h - -#include - -extern WS2812FX ws2812fx; - -uint16_t rainbowLarson(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment - int seglen = seg->stop - seg->start + 1; - - static int16_t index = 0, dir = 1, cnt = 0; - index += dir; - - ws2812fx.fade_out(); - - if(seg->options == NO_OPTIONS) { - ws2812fx.setPixelColor(seg->start + index, ws2812fx.color_wheel((cnt++ % 8) * 32)); - } else { - ws2812fx.setPixelColor(seg->start + index, ws2812fx.color_wheel((index * 256) / seglen)); - } - - if(index >= (seg->stop - seg->start) || index <= 0) dir = -dir; - - return (seg->speed / (seglen * 2)); -} - -#endif diff --git a/Arduino/McLighting/custom/RandomChase.h b/Arduino/McLighting/custom/RandomChase.h deleted file mode 100644 index cb99c7c..0000000 --- a/Arduino/McLighting/custom/RandomChase.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Custom effect that creates a random chase effect - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-02-26 initial version -*/ - -#ifndef RandomChase_h -#define RandomChase_h - -#include - -extern WS2812FX ws2812fx; - -uint16_t randomChase(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); - for(uint16_t i=seg->stop; i>seg->start; i--) { - ws2812fx.setPixelColor(i, ws2812fx.getPixelColor(i-1)); - } - uint32_t color = ws2812fx.getPixelColor(seg->start + 1); - int r = random(6) != 0 ? (color >> 16 & 0xFF) : random(256); - int g = random(6) != 0 ? (color >> 8 & 0xFF) : random(256); - int b = random(6) != 0 ? (color & 0xFF) : random(256); - ws2812fx.setPixelColor(seg->start, r, g, b); - return seg->speed; -} - -#endif diff --git a/Arduino/McLighting/custom/TriFade.h b/Arduino/McLighting/custom/TriFade.h deleted file mode 100644 index 1104d65..0000000 --- a/Arduino/McLighting/custom/TriFade.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - Custom effect that fades between three colors. You can add the TRIFADE_BLACK option - in the setSegment() call to fade to black between each color. - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-07-26 initial version -*/ - -#ifndef TriFade_h -#define TriFade_h - -#define TRIFADE_BLACK (uint8_t)0x80 - -#include - -extern WS2812FX ws2812fx; - -uint16_t triFade(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment - uint8_t options = seg->options; - bool trifade_black = (options & TRIFADE_BLACK) == TRIFADE_BLACK; - - static int count = 0; - static uint32_t color1 = 0, color2 = 0; - - if(count == 0) { - color1 = seg->colors[0]; - color2 = trifade_black ? BLACK : seg->colors[1]; - } else if(count == 256) { - color1 = trifade_black ? BLACK : seg->colors[1]; - color2 = trifade_black ? seg->colors[1] : seg->colors[2]; - } else if(count == 512) { - color1 = trifade_black ? seg->colors[1] : seg->colors[2]; - color2 = trifade_black ? BLACK : seg->colors[0]; - } else if(count == 768) { - color1 = trifade_black ? BLACK : seg->colors[0]; - color2 = trifade_black ? seg->colors[2] : seg->colors[1]; - } else if(count == 1024) { - color1 = trifade_black ? seg->colors[2] : seg->colors[1]; - color2 = trifade_black ? BLACK : seg->colors[2]; - } else if(count == 1280) { - color1 = trifade_black ? BLACK: seg->colors[2]; - color2 = seg->colors[0]; - } - - uint32_t color = ws2812fx.color_blend(color1, color2, count % 256); - for(uint16_t i=seg->start; i <= seg->stop; i++) { - ws2812fx.setPixelColor(i, color); - } - - count += 4; - if(count >= 1536) count = 0; - - return (seg->speed / 128); -} - -#endif diff --git a/Arduino/McLighting/custom/VUMeter.h b/Arduino/McLighting/custom/VUMeter.h deleted file mode 100644 index 77ca20c..0000000 --- a/Arduino/McLighting/custom/VUMeter.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Custom effect that mimics a multiband VU meter - - Keith Lord - 2018 - - LICENSE - - The MIT License (MIT) - - Copyright (c) 2018 Keith Lord - - 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, sub-license, 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 - 2018-08-21 initial version -*/ - -#ifndef VUMeter_h -#define VUMeter_h - -#include - -#ifndef NUM_BANDS - #define NUM_BANDS 2 -#endif - -// set USE_RANDOM_DATA to false in the line below if vuMeterBands[] is populated -// by an external data source. otherwise random data will be used for the effect. -#ifndef USE_RANDOM_DATA - #define USE_RANDOM_DATA true -#endif - -extern WS2812FX ws2812fx; - -uint8_t vuMeterBands[NUM_BANDS]; // global VU meter band amplitude data (range 0-255) - -uint16_t vuMeter(void) { - WS2812FX::Segment* seg = ws2812fx.getSegment(); - uint16_t seglen = seg->stop - seg->start + 1; - uint16_t bandSize = seglen / NUM_BANDS; - - for(uint8_t i=0; i 255) ? 128 : randomData; -#endif - - uint8_t scaledBand = (vuMeterBands[i] * bandSize) / 256; - for(uint16_t j=0; jstart + (i * bandSize) + j; - if(j <= scaledBand) { - if(j < bandSize - 4) ws2812fx.setPixelColor(index, seg->colors[0]); - else if(j < bandSize - 2) ws2812fx.setPixelColor(index, seg->colors[1]); - else ws2812fx.setPixelColor(index, seg->colors[2]); - } else { - ws2812fx.setPixelColor(index, BLACK); - } - } - } - - return seg->speed; -} - -#endif diff --git a/Arduino/McLighting/definitions.h b/Arduino/McLighting/definitions.h index 768243d..8f192e2 100644 --- a/Arduino/McLighting/definitions.h +++ b/Arduino/McLighting/definitions.h @@ -1,9 +1,9 @@ #define USE_WS2812FX_DMA // Uses PIN is ignored & set to RX/GPIO3 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX -//#define USE_WS2812FX_UART1 // Uses PIN is ignored & set to D4/GPIO2 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX -//#define USE_WS2812FX_UART2 // Uses PIN is ignored & set to TX/GPIO1 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX +//#define USE_WS2812FX_UART1 // Uses PIN is ignored & set to D4/GPIO2 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX +//#define USE_WS2812FX_UART2 // Uses PIN is ignored & set to TX/GPIO1 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX // Neopixel -#define PIN 3 // PIN (15 / D8) where neopixel / WS2811 strip is attached +#define PIN 3 // PIN (15 / D8) where neopixel / WS2811 strip is attached #define NUMLEDS 144 // Number of leds in the strip #define BUILTIN_LED 2 // ESP-12F has the built in LED on GPIO2, see https://github.com/esp8266/Arduino/issues/2192 #define BUTTON 14 // Input pin (14 / D5) for switching the LED strip on / off, connect this PIN to ground to trigger button. @@ -12,20 +12,20 @@ const char HOSTNAME[] = "McLightingRGBW"; // Friedly hostname -#define HTTP_OTA // If defined, enable ESP8266HTTPUpdateServer OTA code. -//#define ENABLE_OTA // If defined, enable Arduino OTA code. -#define ENABLE_AMQTT // If defined, enable Async MQTT code, see: https://github.com/marvinroger/async-mqtt-client -//#define ENABLE_MQTT // If defined, enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API -//#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT or ENABLE_AMQTT must be active -#define ENABLE_BUTTON // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control -//#define ENABLE_BUTTON_GY33 // If defined, enable button handling code for GY-33 color sensor to scan color +#define HTTP_OTA // If defined, enable ESP8266HTTPUpdateServer OTA code. +//#define ENABLE_OTA // If defined, enable Arduino OTA code. +#define ENABLE_AMQTT // If defined, enable Async MQTT code, see: https://github.com/marvinroger/async-mqtt-client +//#define ENABLE_MQTT // If defined, enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API +//#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT or ENABLE_AMQTT must be active +#define ENABLE_BUTTON // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control +//#define ENABLE_BUTTON_GY33 // If defined, enable button handling code for GY-33 color sensor to scan color //#define MQTT_HOME_ASSISTANT_SUPPORT // If defined, use AMQTT and select Tools -> IwIP Variant -> Higher Bandwidth -#define ENABLE_LEGACY_ANIMATIONS // Enable Legacy Animations -#define ENABLE_E131 // E1.31 implementation You have to uncomment #define USE_WS2812FX_DMA -#define ENABLE_TV // Enable TV Animation +#define ENABLE_LEGACY_ANIMATIONS // Enable Legacy Animations +#define ENABLE_E131 // E1.31 implementation You have to uncomment #define USE_WS2812FX_DMA +#define ENABLE_TV // Enable TV Animation #ifdef ENABLE_E131 - #define START_UNIVERSE 1 // First DMX Universe to listen for + #define START_UNIVERSE 1 // First DMX Universe to listen for #define END_UNIVERSE 2 // Total number of Universes to listen for, starting at UNIVERSE #endif @@ -56,7 +56,7 @@ const char HOSTNAME[] = "McLightingRGBW"; // Friedly hostname #endif // parameters for automatically cycling favorite patterns -uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds) +uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds) {0xff000000, 120, 1, 5}, // blink red for 5 seconds {0x00ff0000, 120, 3, 10}, // wipe green for 10 seconds {0x0000ff00, 196, 14, 5}, // dual scan blue for 5 seconds @@ -126,14 +126,14 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds) #endif MODE prevmode = mode; -int ws2812fx_speed = 196; // Global variable for storing the delay between color changes --> smaller == faster -int brightness = 196; // Global variable for storing the brightness (255 == 100%) +int ws2812fx_speed = 196; // Global variable for storing the delay between color changes --> smaller == faster +int brightness = 196; // Global variable for storing the brightness (255 == 100%) -int ws2812fx_mode = 0; // Helper variable to set WS2812FX modes +int ws2812fx_mode = 0; // Helper variable to set WS2812FX modes -bool shouldSaveConfig = false; // For WiFiManger custom config +bool shouldSaveConfig = false; // For WiFiManger custom config -struct ledstate // Data structure to store a state of a single led +struct ledstate // Data structure to store a state of a single led { uint8_t red; uint8_t green; @@ -149,7 +149,7 @@ LEDState main_color = { 255, 0, 0, 0 }; // Store the "main color" of the strip #define ENABLE_STATE_SAVE_SPIFFS // If defined, saves state on SPIFFS //#define ENABLE_STATE_SAVE_EEPROM // If defined, save state on reboot -char beforeauto_state[36]; // Keeps the state representation before auto mode +char beforeoffauto_state[36]; // Keeps the state representation before auto mode #ifdef ENABLE_STATE_SAVE_EEPROM char current_state[36]; // Keeps the current state representation char last_state[36]; // Save the last state as string representation diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index e1a0659..cb92102 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -67,7 +67,6 @@ void getArgs() { main_color.white = server.arg("w").toInt(); } } - if ((server.arg("s") != "") && (server.arg("s").toInt() >= 0) && (server.arg("s").toInt() <= 255)) { ws2812fx_speed = constrain(server.arg("s").toInt(), 0, 255); } @@ -75,7 +74,7 @@ void getArgs() { if ((server.arg("m") != "") && (server.arg("m").toInt() >= 0) && (server.arg("m").toInt() <= strip.getModeCount())) { ws2812fx_mode = constrain(server.arg("m").toInt(), 0, strip.getModeCount() - 1); } - + if ((server.arg("c") != "") && (server.arg("c").toInt() >= 0) && (server.arg("c").toInt() <= 100)) { brightness = constrain((int) server.arg("c").toInt() * 2.55, 0, 255); } else if ((server.arg("p") != "") && (server.arg("p").toInt() >= 0) && (server.arg("p").toInt() <= 255)) { @@ -117,7 +116,6 @@ uint16_t convertSpeed(uint8_t mcl_speed) { return ws2812_speed; } - // *************************************************************************** // Handler functions for WS and MQTT // *************************************************************************** @@ -139,20 +137,15 @@ void handleSetMainColor(uint8_t * mypayload) { void handleSetAllMode(uint8_t * mypayload) { // decode rgb data uint32_t rgb = (uint32_t) strtoul((const char *) &mypayload[1], NULL, 16); - main_color.white = ((rgb >> 24) & 0xFF); main_color.red = ((rgb >> 16) & 0xFF); main_color.green = ((rgb >> 8) & 0xFF); main_color.blue = ((rgb >> 0) & 0xFF); - DBG_OUTPUT_PORT.printf("WS: Set all leds to main color: R: [%u] G: [%u] B: [%u] W: [%u]\n", main_color.red, main_color.green, main_color.blue, main_color.white); #ifdef ENABLE_TV exit_func = true; #endif ws2812fx_mode = FX_MODE_STATIC; - #ifdef ENABLE_TV - exit_func = true; - #endif mode = SET_MODE; } @@ -167,11 +160,11 @@ void handleSetSingleLED(uint8_t * mypayload, uint8_t firstChar = 0) { char redhex[3]; char greenhex[3]; char bluehex[3]; - char whitehex[3]; + char whitehex[3]; strncpy (redhex, (const char *) &mypayload[2 + firstChar], 2 ); strncpy (greenhex, (const char *) &mypayload[4 + firstChar], 2 ); strncpy (bluehex, (const char *) &mypayload[6 + firstChar], 2 ); - strncpy (whitehex, (const char *) &mypayload[8 + firstChar], 2 ); + strncpy (whitehex, (const char *) &mypayload[8 + firstChar], 2 ); ledstates[led].red = strtol(redhex, NULL, 16); ledstates[led].green = strtol(greenhex, NULL, 16); ledstates[led].blue = strtol(bluehex, NULL, 16); @@ -179,8 +172,6 @@ void handleSetSingleLED(uint8_t * mypayload, uint8_t firstChar = 0) { DBG_OUTPUT_PORT.printf("rgb.red: [%s] rgb.green: [%s] rgb.blue: [%s] rgb.white: [%s]\n", redhex, greenhex, bluehex, whitehex); DBG_OUTPUT_PORT.printf("rgb.red: [%i] rgb.green: [%i] rgb.blue: [%i] rgb.white: [%i]\n", strtol(redhex, NULL, 16), strtol(greenhex, NULL, 16), strtol(bluehex, NULL, 16), strtol(whitehex, NULL, 16)); DBG_OUTPUT_PORT.printf("WS: Set single led [%i] to [%i] [%i] [%i] [%i] (%s)!\n", led, ledstates[led].red, ledstates[led].green, ledstates[led].blue, ledstates[led].white, mypayload); - - strip.setPixelColor(led, ledstates[led].red, ledstates[led].green, ledstates[led].blue, ledstates[led].white); strip.show(); } @@ -237,6 +228,9 @@ void handleRangeDifferentColors(uint8_t * mypayload) { } void setModeByStateString(String saved_state_string) { +#ifdef ENABLE_TV + exit_func = true; +#endif String str_mode = getValue(saved_state_string, '|', 1); mode = static_cast(str_mode.toInt()); String str_ws2812fx_mode = getValue(saved_state_string, '|', 2); @@ -266,6 +260,7 @@ void setModeByStateString(String saved_state_string) { strip.setSpeed(convertSpeed(ws2812fx_speed)); strip.setBrightness(brightness); strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white); + strip.trigger(); } void handleSetNamedMode(String str_mode) { @@ -486,7 +481,7 @@ void handleAutoStart() { #ifdef ENABLE_TV exit_func = true; #endif - sprintf(beforeauto_state, "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, strip.getMode(), ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white); + sprintf(beforeoffauto_state, "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, strip.getMode(), ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white); mode = AUTO; autoCount = 0; autoTick(); @@ -495,9 +490,11 @@ void handleAutoStart() { } void handleAutoStop() { - autoTicker.detach(); - strip.stop(); - setModeByStateString(beforeauto_state); + if (mode==AUTO) { + autoTicker.detach(); + strip.stop(); + setModeByStateString(beforeoffauto_state); + } } void Dbg_Prefix(bool mqtt, uint8_t num) { @@ -525,9 +522,6 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) { stateOn = true; if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif } // ? ==> Set speed @@ -866,18 +860,23 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght //char modeName[30]; //strncpy_P(modeName, (PGM_P)strip.getModeName(strip.getMode()), sizeof(modeName)); // copy from progmem - #if defined(ENABLE_E131) and defined(ENABLE_HOMEASSISTANT) - if (mode == E131) - root["effect"] = "E131"; - else - root["effect"] = strip.getModeName(strip.getMode()); - #else - root["effect"] = strip.getModeName(strip.getMode()); + #if defined(ENABLE_HOMEASSISTANT) + if (mode == OFF){ + root["effect"] = "OFF"; + } else { + if (mode == TV){ + root["effect"] = "TV"; + } else { + if (mode == E131){ + root["effect"] = "E131"; + } else { + root["effect"] = strip.getModeName(strip.getMode()); + } + } + } #endif - char buffer[measureJson(root) + 1]; serializeJson(root, buffer, sizeof(buffer)); - #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_ha_state_out.c_str(), buffer, true); DBG_OUTPUT_PORT.printf("MQTT: Send [%s]: %s\n", mqtt_ha_state_out.c_str(), buffer); @@ -923,6 +922,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght main_color.red = (uint8_t) color["r"]; main_color.green = (uint8_t) color["g"]; main_color.blue = (uint8_t) color["b"]; + main_color.white = (uint8_t) color["w"]; prevmode = mode; mode = SETCOLOR; } @@ -1060,8 +1060,14 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght for (uint8_t i = 0; i < strip.getModeCount(); i++) { effect_list.add(strip.getModeName(i)); } - #if defined(ENABLE_E131) and defined(MQTT_HOME_ASSISTANT_SUPPORT) - effect_list.add("E131"); + #ifdef MQTT_HOME_ASSISTANT_SUPPORT + effect_list.add("OFF"); + #ifdef ENABLE_TV + effect_list.add("TV"); + #endif + #ifdef ENABLE_E131 + effect_list.add("E131"); + #endif #endif char buffer[measureJson(json) + 1]; serializeJson(json, buffer, sizeof(buffer)); @@ -1147,8 +1153,14 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght for (uint8_t i = 0; i < strip.getModeCount(); i++) { effect_list.add(strip.getModeName(i)); } - #if defined(ENABLE_E131) and defined(MQTT_HOME_ASSISTANT_SUPPORT) - effect_list.add("E131"); + #ifdef MQTT_HOME_ASSISTANT_SUPPORT + effect_list.add("OFF"); + #ifdef ENABLE_TV + effect_list.add("TV"); + #endif + #ifdef ENABLE_E131 + effect_list.add("E131"); + #endif #endif char buffer[measureJson(json) + 1]; serializeJson(json, buffer, sizeof(buffer)); diff --git a/Arduino/McLighting/spiffs_webserver.h b/Arduino/McLighting/spiffs_webserver.h index 3dd396b..3af2bb5 100644 --- a/Arduino/McLighting/spiffs_webserver.h +++ b/Arduino/McLighting/spiffs_webserver.h @@ -32,128 +32,128 @@ File fsUploadFile; //format bytes String formatBytes(size_t bytes) { - if (bytes < 1024) { - return String(bytes) + "B"; - } else if (bytes < (1024 * 1024)) { - return String(bytes / 1024.0) + "KB"; - } else if (bytes < (1024 * 1024 * 1024)) { - return String(bytes / 1024.0 / 1024.0) + "MB"; - } else { - return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB"; - } + if (bytes < 1024) { + return String(bytes) + "B"; + } else if (bytes < (1024 * 1024)) { + return String(bytes / 1024.0) + "KB"; + } else if (bytes < (1024 * 1024 * 1024)) { + return String(bytes / 1024.0 / 1024.0) + "MB"; + } else { + return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB"; + } } String getContentType(String filename) { - if (server.hasArg("download")) return "application/octet-stream"; - else if (filename.endsWith(".htm")) return "text/html"; - else if (filename.endsWith(".html")) return "text/html"; - else if (filename.endsWith(".css")) return "text/css"; - else if (filename.endsWith(".js")) return "application/javascript"; - else if (filename.endsWith(".png")) return "image/png"; - else if (filename.endsWith(".gif")) return "image/gif"; - else if (filename.endsWith(".jpg")) return "image/jpeg"; - else if (filename.endsWith(".ico")) return "image/x-icon"; - else if (filename.endsWith(".xml")) return "text/xml"; - else if (filename.endsWith(".pdf")) return "application/x-pdf"; - else if (filename.endsWith(".zip")) return "application/x-zip"; - else if (filename.endsWith(".gz")) return "application/x-gzip"; - return "text/plain"; + if (server.hasArg("download")) return "application/octet-stream"; + else if (filename.endsWith(".htm")) return "text/html"; + else if (filename.endsWith(".html")) return "text/html"; + else if (filename.endsWith(".css")) return "text/css"; + else if (filename.endsWith(".js")) return "application/javascript"; + else if (filename.endsWith(".png")) return "image/png"; + else if (filename.endsWith(".gif")) return "image/gif"; + else if (filename.endsWith(".jpg")) return "image/jpeg"; + else if (filename.endsWith(".ico")) return "image/x-icon"; + else if (filename.endsWith(".xml")) return "text/xml"; + else if (filename.endsWith(".pdf")) return "application/x-pdf"; + else if (filename.endsWith(".zip")) return "application/x-zip"; + else if (filename.endsWith(".gz")) return "application/x-gzip"; + return "text/plain"; } bool handleFileRead(String path) { - DBG_OUTPUT_PORT.println("handleFileRead: " + path); - if (path.endsWith("/")) path += "index.htm"; - String contentType = getContentType(path); - String pathWithGz = path + ".gz"; - if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { - if (SPIFFS.exists(pathWithGz)) - path += ".gz"; - File file = SPIFFS.open(path, "r"); + DBG_OUTPUT_PORT.println("handleFileRead: " + path); + if (path.endsWith("/")) path += "index.htm"; + String contentType = getContentType(path); + String pathWithGz = path + ".gz"; + if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { + if (SPIFFS.exists(pathWithGz)) + path += ".gz"; + File file = SPIFFS.open(path, "r"); server.sendHeader("Access-Control-Allow-Origin", "*"); - size_t sent = server.streamFile(file, contentType); - file.close(); - return true; - } - return false; + size_t sent = server.streamFile(file, contentType); + file.close(); + return true; + } + return false; } void handleFileUpload() { - if (server.uri() != "/edit") return; - HTTPUpload& upload = server.upload(); - if (upload.status == UPLOAD_FILE_START) { - String filename = upload.filename; - if (!filename.startsWith("/")) filename = "/" + filename; - DBG_OUTPUT_PORT.print("handleFileUpload Name: "); - DBG_OUTPUT_PORT.println(filename); - fsUploadFile = SPIFFS.open(filename, "w"); - filename = String(); - } else if (upload.status == UPLOAD_FILE_WRITE) { - //DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize); - if (fsUploadFile) - fsUploadFile.write(upload.buf, upload.currentSize); - } else if (upload.status == UPLOAD_FILE_END) { - if (fsUploadFile) - fsUploadFile.close(); - DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize); - } + if (server.uri() != "/edit") return; + HTTPUpload& upload = server.upload(); + if (upload.status == UPLOAD_FILE_START) { + String filename = upload.filename; + if (!filename.startsWith("/")) filename = "/" + filename; + DBG_OUTPUT_PORT.print("handleFileUpload Name: "); + DBG_OUTPUT_PORT.println(filename); + fsUploadFile = SPIFFS.open(filename, "w"); + filename = String(); + } else if (upload.status == UPLOAD_FILE_WRITE) { + //DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize); + if (fsUploadFile) + fsUploadFile.write(upload.buf, upload.currentSize); + } else if (upload.status == UPLOAD_FILE_END) { + if (fsUploadFile) + fsUploadFile.close(); + DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize); + } } void handleFileDelete() { - if (server.args() == 0) return server.send(500, "text/plain", "BAD ARGS"); - String path = server.arg(0); - DBG_OUTPUT_PORT.println("handleFileDelete: " + path); - if (path == "/") - return server.send(500, "text/plain", "BAD PATH"); - if (!SPIFFS.exists(path)) - return server.send(404, "text/plain", "FileNotFound"); - SPIFFS.remove(path); - server.send(200, "text/plain", ""); - path = String(); + if (server.args() == 0) return server.send(500, "text/plain", "BAD ARGS"); + String path = server.arg(0); + DBG_OUTPUT_PORT.println("handleFileDelete: " + path); + if (path == "/") + return server.send(500, "text/plain", "BAD PATH"); + if (!SPIFFS.exists(path)) + return server.send(404, "text/plain", "FileNotFound"); + SPIFFS.remove(path); + server.send(200, "text/plain", ""); + path = String(); } void handleFileCreate() { - if (server.args() == 0) - return server.send(500, "text/plain", "BAD ARGS"); - String path = server.arg(0); - DBG_OUTPUT_PORT.println("handleFileCreate: " + path); - if (path == "/") - return server.send(500, "text/plain", "BAD PATH"); - if (SPIFFS.exists(path)) - return server.send(500, "text/plain", "FILE EXISTS"); - File file = SPIFFS.open(path, "w"); - if (file) - file.close(); - else - return server.send(500, "text/plain", "CREATE FAILED"); - server.send(200, "text/plain", ""); - path = String(); + if (server.args() == 0) + return server.send(500, "text/plain", "BAD ARGS"); + String path = server.arg(0); + DBG_OUTPUT_PORT.println("handleFileCreate: " + path); + if (path == "/") + return server.send(500, "text/plain", "BAD PATH"); + if (SPIFFS.exists(path)) + return server.send(500, "text/plain", "FILE EXISTS"); + File file = SPIFFS.open(path, "w"); + if (file) + file.close(); + else + return server.send(500, "text/plain", "CREATE FAILED"); + server.send(200, "text/plain", ""); + path = String(); } void handleFileList() { - if (!server.hasArg("dir")) { - server.send(500, "text/plain", "BAD ARGS"); - return; - } - - String path = server.arg("dir"); - DBG_OUTPUT_PORT.println("handleFileList: " + path); - Dir dir = SPIFFS.openDir(path); - path = String(); - - String output = "["; - while (dir.next()) { - File entry = dir.openFile("r"); - if (output != "[") output += ','; - bool isDir = false; - output += "{\"type\":\""; - output += (isDir) ? "dir" : "file"; - output += "\",\"name\":\""; - output += String(entry.name()).substring(1); - output += "\"}"; - entry.close(); - } - - output += "]"; + if (!server.hasArg("dir")) { + server.send(500, "text/plain", "BAD ARGS"); + return; + } + + String path = server.arg("dir"); + DBG_OUTPUT_PORT.println("handleFileList: " + path); + Dir dir = SPIFFS.openDir(path); + path = String(); + + String output = "["; + while (dir.next()) { + File entry = dir.openFile("r"); + if (output != "[") output += ','; + bool isDir = false; + output += "{\"type\":\""; + output += (isDir) ? "dir" : "file"; + output += "\",\"name\":\""; + output += String(entry.name()).substring(1); + output += "\"}"; + entry.close(); + } + + output += "]"; server.sendHeader("Access-Control-Allow-Origin", "*"); - server.send(200, "text/json", output); -} + server.send(200, "text/json", output); +}