Skip to content

Commit 6cb6a8e

Browse files
authored
create stairway-wipe-for-usermod-v2 (wled#1359)
* create stairway-wipe-for-usermod-v2 * Update and rename stairway-wipe-usermod.h to stairway-wipe-usermod-v2.h
1 parent 223bd96 commit 6cb6a8e

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#include "wled.h"
2+
3+
/*
4+
* Usermods allow you to add own functionality to WLED more easily
5+
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
6+
*
7+
* This is Stairway-Wipe as a v2 usermod.
8+
*
9+
* Using this usermod:
10+
* 1. Copy the usermod into the sketch folder (same folder as wled00.ino)
11+
* 2. Register the usermod by adding #include "stairway-wipe-usermod-v2.h" in the top and registerUsermod(new StairwayWipeUsermod()) in the bottom of usermods_list.cpp
12+
*/
13+
14+
class StairwayWipeUsermod : public Usermod {
15+
private:
16+
//Private class members. You can declare variables and functions only accessible to your usermod here
17+
unsigned long lastTime = 0;
18+
byte wipeState = 0; //0: inactive 1: wiping 2: solid
19+
unsigned long timeStaticStart = 0;
20+
uint16_t previousUserVar0 = 0;
21+
22+
//comment this out if you want the turn off effect to be just fading out instead of reverse wipe
23+
#define STAIRCASE_WIPE_OFF
24+
public:
25+
26+
void loop() {
27+
//userVar0 (U0 in HTTP API):
28+
//has to be set to 1 if movement is detected on the PIR that is the same side of the staircase as the ESP8266
29+
//has to be set to 2 if movement is detected on the PIR that is the opposite side
30+
//can be set to 0 if no movement is detected. Otherwise LEDs will turn off after a configurable timeout (userVar1 seconds)
31+
32+
if (userVar0 > 0)
33+
{
34+
if ((previousUserVar0 == 1 && userVar0 == 2) || (previousUserVar0 == 2 && userVar0 == 1)) wipeState = 3; //turn off if other PIR triggered
35+
previousUserVar0 = userVar0;
36+
37+
if (wipeState == 0) {
38+
startWipe();
39+
wipeState = 1;
40+
} else if (wipeState == 1) { //wiping
41+
uint32_t cycleTime = 360 + (255 - effectSpeed)*75; //this is how long one wipe takes (minus 25 ms to make sure we switch in time)
42+
if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete
43+
effectCurrent = FX_MODE_STATIC;
44+
timeStaticStart = millis();
45+
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION);
46+
wipeState = 2;
47+
}
48+
} else if (wipeState == 2) { //static
49+
if (userVar1 > 0) //if U1 is not set, the light will stay on until second PIR or external command is triggered
50+
{
51+
if (millis() - timeStaticStart > userVar1*1000) wipeState = 3;
52+
}
53+
} else if (wipeState == 3) { //switch to wipe off
54+
#ifdef STAIRCASE_WIPE_OFF
55+
effectCurrent = FX_MODE_COLOR_WIPE;
56+
strip.timebase = 360 + (255 - effectSpeed)*75 - millis(); //make sure wipe starts fully lit
57+
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION);
58+
wipeState = 4;
59+
#else
60+
turnOff();
61+
#endif
62+
} else { //wiping off
63+
if (millis() + strip.timebase > (725 + (255 - effectSpeed)*150)) turnOff(); //wipe complete
64+
}
65+
} else {
66+
wipeState = 0; //reset for next time
67+
if (previousUserVar0) {
68+
#ifdef STAIRCASE_WIPE_OFF
69+
userVar0 = previousUserVar0;
70+
wipeState = 3;
71+
#else
72+
turnOff();
73+
#endif
74+
}
75+
previousUserVar0 = 0;
76+
}
77+
}
78+
79+
void readFromJsonState(JsonObject& root)
80+
{
81+
userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value
82+
//if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!"));
83+
}
84+
85+
void addToConfig(JsonObject& root)
86+
{
87+
JsonObject top = root.createNestedObject("exampleUsermod");
88+
top["great"] = userVar0; //save this var persistently whenever settings are saved
89+
}
90+
91+
void readFromConfig(JsonObject& root)
92+
{
93+
JsonObject top = root["top"];
94+
userVar0 = top["great"] | 42; //The value right of the pipe "|" is the default value in case your setting was not present in cfg.json (e.g. first boot)
95+
}
96+
97+
uint16_t getId()
98+
{
99+
return USERMOD_ID_EXAMPLE;
100+
}
101+
102+
103+
void startWipe()
104+
{
105+
bri = briLast; //turn on
106+
transitionDelayTemp = 0; //no transition
107+
effectCurrent = FX_MODE_COLOR_WIPE;
108+
resetTimebase(); //make sure wipe starts from beginning
109+
110+
//set wipe direction
111+
WS2812FX::Segment& seg = strip.getSegment(0);
112+
bool doReverse = (userVar0 == 2);
113+
seg.setOption(1, doReverse);
114+
115+
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION);
116+
}
117+
118+
void turnOff()
119+
{
120+
#ifdef STAIRCASE_WIPE_OFF
121+
transitionDelayTemp = 0; //turn off immediately after wipe completed
122+
#else
123+
transitionDelayTemp = 4000; //fade out slowly
124+
#endif
125+
bri = 0;
126+
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION);
127+
wipeState = 0;
128+
userVar0 = 0;
129+
previousUserVar0 = 0;
130+
}
131+
132+
133+
134+
//More methods can be added in the future, this example will then be extended.
135+
//Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class!
136+
};

0 commit comments

Comments
 (0)