From a7d473121fba13e6fc7a5fb29ca193cb7a151591 Mon Sep 17 00:00:00 2001 From: "Jordan W. Cobb" Date: Fri, 16 Jan 2026 12:39:06 -0500 Subject: [PATCH 1/3] Added support for inverting logic of PIR pins --- .../Animated_Staircase/Animated_Staircase.cpp | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/usermods/Animated_Staircase/Animated_Staircase.cpp b/usermods/Animated_Staircase/Animated_Staircase.cpp index 2d2d27cf43..aed68028b1 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.cpp +++ b/usermods/Animated_Staircase/Animated_Staircase.cpp @@ -25,6 +25,8 @@ class Animated_Staircase : public Usermod { unsigned int topMaxDist = 50; // default maximum measured distance in cm, top unsigned int bottomMaxDist = 50; // default maximum measured distance in cm, bottom bool togglePower = false; // toggle power on/off with staircase on/off + bool topAPinInvert = false; // invert output of top sensor + bool bottomAPinInvert = false; // invert output of bottom sensor /* runtime variables */ bool initDone = false; @@ -91,6 +93,8 @@ class Animated_Staircase : public Usermod { static const char _topEchoCm[]; static const char _bottomEchoCm[]; static const char _togglePower[]; + static const char _topPIRorTrigger_pin_invert[]; + static const char _bottomPIRorTrigger_pin_invert[]; void publishMqtt(bool bottom, const char* state) { #ifndef WLED_DISABLE_MQTT @@ -156,6 +160,12 @@ class Animated_Staircase : public Usermod { return pulseIn(echoPin, HIGH, maxTimeUs) > 0; } + bool readPIRPin(int8_t pin, bool invert) { + if (pin < 0) return false; + bool v = digitalRead(pin); + return invert ? !v : v; + } + bool checkSensors() { bool sensorChanged = false; @@ -164,15 +174,16 @@ class Animated_Staircase : public Usermod { bottomSensorRead = bottomSensorWrite || (!useUSSensorBottom ? - (bottomPIRorTriggerPin<0 ? false : digitalRead(bottomPIRorTriggerPin)) : + (bottomPIRorTriggerPin<0 ? false : readPIRPin(bottomPIRorTriggerPin, bottomAPinInvert)) : ultrasoundRead(bottomPIRorTriggerPin, bottomEchoPin, bottomMaxDist*59) // cm to us ); topSensorRead = topSensorWrite || (!useUSSensorTop ? - (topPIRorTriggerPin<0 ? false : digitalRead(topPIRorTriggerPin)) : + (topPIRorTriggerPin<0 ? false : readPIRPin(topPIRorTriggerPin, topAPinInvert)) : ultrasoundRead(topPIRorTriggerPin, topEchoPin, topMaxDist*59) // cm to us ); + if (bottomSensorRead != bottomSensorState) { bottomSensorState = bottomSensorRead; // change previous state sensorChanged = true; @@ -451,6 +462,8 @@ class Animated_Staircase : public Usermod { staircase[FPSTR(_topEchoCm)] = topMaxDist; staircase[FPSTR(_bottomEchoCm)] = bottomMaxDist; staircase[FPSTR(_togglePower)] = togglePower; + staircase[FPSTR(_topPIRorTrigger_pin_invert)] = topAPinInvert; + staircase[FPSTR(_bottomPIRorTrigger_pin_invert)] = bottomAPinInvert; DEBUG_PRINTLN(F("Staircase config saved.")); } @@ -462,10 +475,14 @@ class Animated_Staircase : public Usermod { bool readFromConfig(JsonObject& root) { bool oldUseUSSensorTop = useUSSensorTop; bool oldUseUSSensorBottom = useUSSensorBottom; + bool oldTopAPinInvert = topAPinInvert; + bool oldBottomAPinInvert = bottomAPinInvert; int8_t oldTopAPin = topPIRorTriggerPin; int8_t oldTopBPin = topEchoPin; int8_t oldBottomAPin = bottomPIRorTriggerPin; int8_t oldBottomBPin = bottomEchoPin; + + JsonObject top = root[FPSTR(_name)]; if (top.isNull()) { @@ -485,10 +502,13 @@ class Animated_Staircase : public Usermod { useUSSensorTop = top[FPSTR(_useTopUltrasoundSensor)] | useUSSensorTop; topPIRorTriggerPin = top[FPSTR(_topPIRorTrigger_pin)] | topPIRorTriggerPin; topEchoPin = top[FPSTR(_topEcho_pin)] | topEchoPin; + topAPinInvert = top[FPSTR(_topPIRorTrigger_pin_invert)] | topAPinInvert; + useUSSensorBottom = top[FPSTR(_useBottomUltrasoundSensor)] | useUSSensorBottom; bottomPIRorTriggerPin = top[FPSTR(_bottomPIRorTrigger_pin)] | bottomPIRorTriggerPin; bottomEchoPin = top[FPSTR(_bottomEcho_pin)] | bottomEchoPin; + bottomAPinInvert = top[FPSTR(_bottomPIRorTrigger_pin_invert)] | bottomAPinInvert; topMaxDist = top[FPSTR(_topEchoCm)] | topMaxDist; topMaxDist = min(150,max(30,(int)topMaxDist)); // max distance ~1.5m (a lag of 9ms may be expected) @@ -554,9 +574,11 @@ const char Animated_Staircase::_segmentDelay[] PROGMEM = "segment-d const char Animated_Staircase::_onTime[] PROGMEM = "on-time-s"; const char Animated_Staircase::_useTopUltrasoundSensor[] PROGMEM = "useTopUltrasoundSensor"; const char Animated_Staircase::_topPIRorTrigger_pin[] PROGMEM = "topPIRorTrigger_pin"; +const char Animated_Staircase::_topPIRorTrigger_pin_invert[] PROGMEM = "topPIRorTrigger_pin_invert"; const char Animated_Staircase::_topEcho_pin[] PROGMEM = "topEcho_pin"; const char Animated_Staircase::_useBottomUltrasoundSensor[] PROGMEM = "useBottomUltrasoundSensor"; const char Animated_Staircase::_bottomPIRorTrigger_pin[] PROGMEM = "bottomPIRorTrigger_pin"; +const char Animated_Staircase::_bottomPIRorTrigger_pin_invert[] PROGMEM = "bottomPIRorTrigger_pin_invert"; const char Animated_Staircase::_bottomEcho_pin[] PROGMEM = "bottomEcho_pin"; const char Animated_Staircase::_topEchoCm[] PROGMEM = "top-dist-cm"; const char Animated_Staircase::_bottomEchoCm[] PROGMEM = "bottom-dist-cm"; From 2ced9cfb9354a9fdd7e5569f23e29a48bd1d7950 Mon Sep 17 00:00:00 2001 From: Skykingjwc Date: Sun, 25 Jan 2026 22:04:38 -0500 Subject: [PATCH 2/3] Fixed indentations and removed whitespace --- .vscode/extensions.json | 2 +- .../Animated_Staircase/Animated_Staircase.cpp | 35 ++++++++----------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 080e70d08b..e29ee0f18e 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -7,4 +7,4 @@ "unwantedRecommendations": [ "ms-vscode.cpptools-extension-pack" ] -} +} \ No newline at end of file diff --git a/usermods/Animated_Staircase/Animated_Staircase.cpp b/usermods/Animated_Staircase/Animated_Staircase.cpp index aed68028b1..6cdcb06e62 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.cpp +++ b/usermods/Animated_Staircase/Animated_Staircase.cpp @@ -182,7 +182,6 @@ class Animated_Staircase : public Usermod { (topPIRorTriggerPin<0 ? false : readPIRPin(topPIRorTriggerPin, topAPinInvert)) : ultrasoundRead(topPIRorTriggerPin, topEchoPin, topMaxDist*59) // cm to us ); - if (bottomSensorRead != bottomSensorState) { bottomSensorState = bottomSensorRead; // change previous state @@ -450,18 +449,18 @@ class Animated_Staircase : public Usermod { if (staircase.isNull()) { staircase = root.createNestedObject(FPSTR(_name)); } - staircase[FPSTR(_enabled)] = enabled; - staircase[FPSTR(_segmentDelay)] = segment_delay_ms; - staircase[FPSTR(_onTime)] = on_time_ms / 1000; - staircase[FPSTR(_useTopUltrasoundSensor)] = useUSSensorTop; - staircase[FPSTR(_topPIRorTrigger_pin)] = topPIRorTriggerPin; - staircase[FPSTR(_topEcho_pin)] = useUSSensorTop ? topEchoPin : -1; - staircase[FPSTR(_useBottomUltrasoundSensor)] = useUSSensorBottom; - staircase[FPSTR(_bottomPIRorTrigger_pin)] = bottomPIRorTriggerPin; - staircase[FPSTR(_bottomEcho_pin)] = useUSSensorBottom ? bottomEchoPin : -1; - staircase[FPSTR(_topEchoCm)] = topMaxDist; - staircase[FPSTR(_bottomEchoCm)] = bottomMaxDist; - staircase[FPSTR(_togglePower)] = togglePower; + staircase[FPSTR(_enabled)] = enabled; + staircase[FPSTR(_segmentDelay)] = segment_delay_ms; + staircase[FPSTR(_onTime)] = on_time_ms / 1000; + staircase[FPSTR(_useTopUltrasoundSensor)] = useUSSensorTop; + staircase[FPSTR(_topPIRorTrigger_pin)] = topPIRorTriggerPin; + staircase[FPSTR(_topEcho_pin)] = useUSSensorTop ? topEchoPin : -1; + staircase[FPSTR(_useBottomUltrasoundSensor)] = useUSSensorBottom; + staircase[FPSTR(_bottomPIRorTrigger_pin)] = bottomPIRorTriggerPin; + staircase[FPSTR(_bottomEcho_pin)] = useUSSensorBottom ? bottomEchoPin : -1; + staircase[FPSTR(_topEchoCm)] = topMaxDist; + staircase[FPSTR(_bottomEchoCm)] = bottomMaxDist; + staircase[FPSTR(_togglePower)] = togglePower; staircase[FPSTR(_topPIRorTrigger_pin_invert)] = topAPinInvert; staircase[FPSTR(_bottomPIRorTrigger_pin_invert)] = bottomAPinInvert; DEBUG_PRINTLN(F("Staircase config saved.")); @@ -481,9 +480,7 @@ class Animated_Staircase : public Usermod { int8_t oldTopBPin = topEchoPin; int8_t oldBottomAPin = bottomPIRorTriggerPin; int8_t oldBottomBPin = bottomEchoPin; - - - + JsonObject top = root[FPSTR(_name)]; if (top.isNull()) { DEBUG_PRINT(FPSTR(_name)); @@ -502,13 +499,12 @@ class Animated_Staircase : public Usermod { useUSSensorTop = top[FPSTR(_useTopUltrasoundSensor)] | useUSSensorTop; topPIRorTriggerPin = top[FPSTR(_topPIRorTrigger_pin)] | topPIRorTriggerPin; topEchoPin = top[FPSTR(_topEcho_pin)] | topEchoPin; - topAPinInvert = top[FPSTR(_topPIRorTrigger_pin_invert)] | topAPinInvert; + topAPinInvert = top[FPSTR(_topPIRorTrigger_pin_invert)] | topAPinInvert; - useUSSensorBottom = top[FPSTR(_useBottomUltrasoundSensor)] | useUSSensorBottom; bottomPIRorTriggerPin = top[FPSTR(_bottomPIRorTrigger_pin)] | bottomPIRorTriggerPin; bottomEchoPin = top[FPSTR(_bottomEcho_pin)] | bottomEchoPin; - bottomAPinInvert = top[FPSTR(_bottomPIRorTrigger_pin_invert)] | bottomAPinInvert; + bottomAPinInvert = top[FPSTR(_bottomPIRorTrigger_pin_invert)] | bottomAPinInvert; topMaxDist = top[FPSTR(_topEchoCm)] | topMaxDist; topMaxDist = min(150,max(30,(int)topMaxDist)); // max distance ~1.5m (a lag of 9ms may be expected) @@ -584,6 +580,5 @@ const char Animated_Staircase::_topEchoCm[] PROGMEM = "top-dist- const char Animated_Staircase::_bottomEchoCm[] PROGMEM = "bottom-dist-cm"; const char Animated_Staircase::_togglePower[] PROGMEM = "toggle-on-off"; - static Animated_Staircase animated_staircase; REGISTER_USERMOD(animated_staircase); \ No newline at end of file From 27d2c89ff862281befb4a5f3ac5ae68751c121ba Mon Sep 17 00:00:00 2001 From: Skykingjwc Date: Sun, 25 Jan 2026 22:10:35 -0500 Subject: [PATCH 3/3] Added newlne to EOF --- .vscode/extensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e29ee0f18e..080e70d08b 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -7,4 +7,4 @@ "unwantedRecommendations": [ "ms-vscode.cpptools-extension-pack" ] -} \ No newline at end of file +}