From 3e716e429fee7fec682ffb4af833dc526abaf4b1 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 11 Jan 2020 00:26:43 +0100 Subject: [PATCH] Add staircase wipe usermod --- usermods/stairway_wipe_basic/readme.md | 14 +++ .../stairway_wipe_basic/wled06_usermod.ino | 87 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 usermods/stairway_wipe_basic/readme.md create mode 100644 usermods/stairway_wipe_basic/wled06_usermod.ino diff --git a/usermods/stairway_wipe_basic/readme.md b/usermods/stairway_wipe_basic/readme.md new file mode 100644 index 000000000..632b7d85d --- /dev/null +++ b/usermods/stairway_wipe_basic/readme.md @@ -0,0 +1,14 @@ +### Stairway lighting + +Quick usermod to accomplish something similar to [this video](https://www.youtube.com/watch?v=NHkju5ncC4A). + +This usermod allows you to add a lightstrip alongside or on the steps of a staircase. +When the `userVar0` variable is set, the LEDs will gradually turn on in a Wipe effect. +Both directions are supported by setting userVar0 to 1 and 2, respectively (HTTP API commands `U0=1` and `U0=2`). + +After the Wipe is complete, the light will either stay on (Solid effect) indefinitely or after `userVar1` seconds have elapsed. +If userVar0 is updated (e.g. by triggering a second sensor) the light will slowly fade off. +This could be extended to also run a Wipe effect in reverse order to turn the LEDs back off. + +This is just a basic version to accomplish this using HTTP API calls `U0` and `U1` and/or macros. +It should be easy to adapt this code however to interface with motion sensors or other input devices. \ No newline at end of file diff --git a/usermods/stairway_wipe_basic/wled06_usermod.ino b/usermods/stairway_wipe_basic/wled06_usermod.ino new file mode 100644 index 000000000..9fafb6792 --- /dev/null +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -0,0 +1,87 @@ +/* + * This file allows you to add own functionality to WLED more easily + * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_eeprom.h) + * bytes 2400+ are currently ununsed, but might be used for future wled features + */ + +//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t) + +byte wipeState = 0; //0: inactive 1: wiping 2: solid +unsigned long timeStaticStart = 0; +uint16_t previousUserVar0 = 0; + +//gets called once at boot. Do all initialization that doesn't depend on network here +void userSetup() +{ + //setup PIR sensor here, if needed +} + +//gets called every time WiFi is (re-)connected. Initialize own network interfaces here +void userConnected() +{ + +} + +//loop. You can use "if (WLED_CONNECTED)" to check for successful connection +void userLoop() +{ + //userVar0 (U0 in HTTP API): + //has to be set to 1 if movement is detected on the PIR that is the same side of the staircase as the ESP8266 + //has to be set to 2 if movement is detected on the PIR that is the opposite side + //can be set to 0 if no movement is detected. Otherwise LEDs will turn off after a configurable timeout (userVar1 seconds) + + if (userVar0 > 0) + { + if ((previousUserVar0 == 1 && userVar0 == 2) || (previousUserVar0 == 2 && userVar0 == 1)) wipeState = 3; //turn off if other PIR triggered + previousUserVar0 = userVar0; + + if (wipeState == 0) { + startWipe(); + wipeState = 1; + } else if (wipeState == 1) { //wiping + uint32_t cycleTime = 360 + (255 - effectSpeed)*75; //this is how long one wipe takes (minus 25 ms to make sure we switch in time) + if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete + effectCurrent = FX_MODE_STATIC; + timeStaticStart = millis(); + colorUpdated(3); + wipeState = 2; + } + } else if (wipeState == 2) { //static + if (userVar1 > 0) //if U1 is not set, the light will stay on until second PIR or external command is triggered + { + if (millis() - timeStaticStart > userVar1*1000) wipeState = 3; + } + } else { //wipeState == 3, turn off slowly + turnOff(); + userVar0 = 0; + wipeState = 0; + } + } else { + if (previousUserVar0) turnOff(); + wipeState = 0; //reset for next time + previousUserVar0 = 0; + } +} + +void startWipe() +{ + bri = briLast; //turn on + transitionDelayTemp = 0; //no transition + effectCurrent = FX_MODE_COLOR_WIPE; + resetTimebase(); //make sure wipe starts from beginning + + //set wipe direction + WS2812FX::Segment& seg = strip.getSegment(0); + bool doReverse = (userVar0 == 2); + seg.setOption(1, doReverse); + + colorUpdated(3); +} + +void turnOff() +{ + transitionDelayTemp = 4000; + bri = 0; + colorUpdated(3); +}