GPIO Button control Neopixels & timer switch off

Hi Folks I'm a total newbie here. I'm looking to do a simple setup where i press a button and turn a neopixel strip white then off after 10sec/second button press.

This is what i've done so far.

[{"id":"2cad73de.1e799c","type":"rpi-neopixels","z":"bc6ce009.a9549","name":"WS2812B LED STRIP","pixels":"30","bgnd":"","fgnd":"","wipe":"1","mode":"pixels","rgb":"rgb","brightness":"100","gamma":true,"x":660,"y":340,"wires":[]}]

My current problem is when i press the button a 3rd time the light stay off because the led strip is still waiting 10seconds. How can i rectify?


You may need to post a bit more than just the node.


(My machine with NeoPixels is offline and I can't get to it. Otherwise I would be able to give a lot better help)

What are you sending to it to turn the LEDs on/off?

Forget about the other 29 LEDs. Just work on 1 for now.
See if you can control just one quickly with pressing buttons.
Then when you get that working, add the other 29 and see what happens.

Hello. Appologies for teh lack of detail. I wasnt sure what was needed.

So when i press the button it triggers and sends a string 255,255,255 setting the led colour to white(on) waits 10 sedongs and sends another string 0,0,0 efectively setting the led to an (off) state.
The second button press sends a string 0,0,0 effectively (off)

if i press a third time within a 10 second period nothing happens as the initial press was still waiting i guess.

I hope this makes it a bit clearer/ Do you have a better suggestion of a string to achieve what I've tried to describe.


Yes, that helps.

So how about posting the code that is the button so I can/we can see what is going on WRT the signals.

Hello again. The button in a physical button connected to a raspberry pi GPIO pin.

yes - but the flow you posted above is just a single neopixel node - we have no idea how you have currently connected the two together.

OOPs. The full code hadn't pasted. sorry.

[{"id":"bc6ce009.a9549","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"2cad73de.1e799c","type":"rpi-neopixels","z":"bc6ce009.a9549","name":"WS2812B LED STRIP","pixels":"30","bgnd":"","fgnd":"","wipe":"1","mode":"pixels","rgb":"rgb","brightness":"100","gamma":true,"x":660,"y":340,"wires":[]},{"id":"e251ef8e.e7c39","type":"trigger","z":"bc6ce009.a9549","op1":"255,255,255","op2":"0,0,0","op1type":"str","op2type":"str","duration":"10","extend":false,"units":"s","reset":"0,0,0","bytopic":"all","name":"","x":410,"y":300,"wires":[["2cad73de.1e799c"]]},{"id":"effc5c2b.5a43d","type":"rpi-gpio in","z":"bc6ce009.a9549","name":"Button","pin":"40","intype":"up","debounce":"25","read":false,"x":70,"y":340,"wires":[["20ee8ed1.f18a82"]]},{"id":"20ee8ed1.f18a82","type":"switch","z":"bc6ce009.a9549","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"0","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":230,"y":340,"wires":[["e251ef8e.e7c39"],["7f9348dc.dee618"]]},{"id":"7f9348dc.dee618","type":"trigger","z":"bc6ce009.a9549","op1":"0,0,0","op2":"0,0,0","op1type":"str","op2type":"str","duration":"1","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":410,"y":380,"wires":[["2cad73de.1e799c"]]}]

Ok, good. But I think you are missing a lot on what is happening.

Going on your first post you are doing what you want.

Why are you pressing the button a third time within the 10 second time period?

When you press the button it sends a "1". When the button goes up it sends a "0" (text)

I'm not sure why you have the switch node in there.
All you need is the top trigger node and it will do what you want/said in the first post.

Actually you may need to explain that a bit more.

It doesn't make sense to me. Yeah, ok. I'm not the definitive action on things, but I suspect that if it is not clearly understood what you want to do/happen, it will be difficult to write the code to achieve that.

Well I was testing if I wanted to turn the led's back on within that period/reset the timer if that makes sense.

So 1 press on for 10 seconds 2nd press off and third press back on for 10 seconds etc

So, ok. Not wanting to be difficult, how about you try to explain that better?

What you do and what happens.

As in: Starting from "nothing"...... What happens if you press the button.
What happens if you don't press the button again with in 10 seconds.
What happens if you do press the button before the 10 seconds happens.
(note: that is only 2 presses. Not 3)

  1. What happens if you press the button. - The Led comes on white
  2. What happens if you don't press the button again with in 10 seconds. - The led turns off
  3. What happens if you do press the button before the 10 seconds happens. - The led turns off

What i'd like is if i press it again within the initial 10 seconds that we start again as if button was pressed for the first time.

Train of thought/logic all the way through is
If when button pressed led is off then turn it on for 10 seconds
If when button pressed led is on turn it off

Where you are "falling over" is the signals from the input.

It isn't a simple signal - which can be good in some cases - it is a "button pressed" signal and a "button released" signal.

Really all you are interested in is the "pressed" side of things. the "released" is problematic.

I don't like giving people the answer to their questions all the time, but there are exceptions.

Ok, I shall post a bit of code which does what you want, but it an EXAMPLE.

Let's walk through the stages as I see them:

You press the button and the LED(s) are turned ON for 10 seconds.
After that, they are turned OFF.

That's easy as it is.

But when you introduce conditionality: it's a whole different game.

Alas I have to revert to using things I originally didn't like using. But I can't see a better way without complicating it in a whole other way.

So: When the button is pressed, a 10 second count down starts. If the button is pressed again, it has to cancel the (other) existing count down.

That is where the tricks come in.

You set another variable (a flow context - please look into what they are) and it controls what happens during the main countdown.

If the button is pressed again: A signal has to be sent to the trigger node to stop.
That is msg.reset.


After 10 seconds, all has to be reset again back to Square one.

[{"id":"6d7fa7a4.e16ff","type":"function","z":"cc2f40ef.95dc","name":"INPUT","func":"\nreturn msg;","outputs":1,"noerr":0,"x":390,"y":360,"wires":[["53f44ea2.c4cd98","e92fd930.c1501"]]},{"id":"896bd893.3c131","type":"trigger","z":"cc2f40ef.95dc","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"500","extend":false,"units":"ms","reset":"","bytopic":"all","name":"Press simulation","x":190,"y":360,"wires":[["6d7fa7a4.e16ff"]]},{"id":"53f44ea2.c4cd98","type":"switch","z":"cc2f40ef.95dc","name":"","property":"thing","propertyType":"flow","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"eq","v":"1","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":570,"y":360,"wires":[["5ae8be15.34522"],["47be4cfc.689b04"]]},{"id":"e92fd930.c1501","type":"delay","z":"cc2f40ef.95dc","name":"","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":590,"y":460,"wires":[["d3882ded.97f0f8"]]},{"id":"57f7d6cc.d8349","type":"inject","z":"cc2f40ef.95dc","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":320,"wires":[["896bd893.3c131"]]},{"id":"5ae8be15.34522","type":"trigger","z":"cc2f40ef.95dc","op1":"255,255,255","op2":"0,0,0","op1type":"str","op2type":"str","duration":"10","extend":false,"units":"s","reset":"0,0,0","bytopic":"all","name":"","x":760,"y":360,"wires":[["c4ee780.f601808"]]},{"id":"47be4cfc.689b04","type":"change","z":"cc2f40ef.95dc","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":420,"wires":[["5ae8be15.34522"]]},{"id":"d3882ded.97f0f8","type":"switch","z":"cc2f40ef.95dc","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":510,"wires":[["16cf59f5.5d78ce","9c03a370.a91fe"]]},{"id":"c4ee780.f601808","type":"debug","z":"cc2f40ef.95dc","name":"output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":930,"y":360,"wires":[]},{"id":"16cf59f5.5d78ce","type":"debug","z":"cc2f40ef.95dc","name":"Set flow to","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":590,"y":560,"wires":[]},{"id":"9c03a370.a91fe","type":"trigger","z":"cc2f40ef.95dc","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"10","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":750,"y":510,"wires":[["8677a2e2.d08a58"]]},{"id":"8677a2e2.d08a58","type":"change","z":"cc2f40ef.95dc","name":"","rules":[{"t":"set","p":"thing","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":920,"y":510,"wires":[[]]}]

you were very close with your original flow... you just need to also wire the second switch output to the top trigger and set it to reset on a 0 payload. (and the second trigger doesn't really need to send anything after the delay - so could be replaced by a change node if you wanted but meh... it works.


I'll explain more of my flow now:

I have two nodes to simulate the button press, as it has been determined that when you press it, you get a "1" and when it is released you get a "0".
The "0"'s have to be removed from the system.

Anway: The inject and trigger node at the left simulate the button being pressed.
It sends a "1" and then shortly there after a "0".
They aren't really needed. The main flow/code starts at the INPUT node (function node)

So that can be your GPIO node. But don't forget to connect BOTH wires as they are now.

The top part of the code is a switch node that looks if the flow.thing (context) is set to "0" or "1". See further down *
If it is "1" I will explain below.
All things being equal, it will be "0" so it passes to the first output.
That then goes to the trigger node that sends the "255,255,255" message to turn on the LEDs.
(BTW, I think you will need more than that, but I am not sure. I think you need which LEDS this is for in there somewhere too - but anyway.)
Then, if nothing else happens: after 10 seconds the "0,0,0" is sent.
Try it and see.

Now, back to the start:
You press the button (inject node)

Now go down to the delay node. 500ms. That is so the message is delayed - just a little.
The msg.payload is "1".
That the goes through a switch node that checks if msg.payload is set to "1"
If it is (remember: we need only see the "1" and not the "0") it is then sent to the second trigger node.
It's output is sent to a change node that sets flow.thing to "1" for 10 seconds then sets it to "0". This controls what happens earlier on. See earlier *

Now going back to the flow.thing and the switch node.
Originally it was processing a "0". Now it is a "1".
That now sends the signal down to another change node.

This node generates a signal msg.reset and sets it to true.
That then goes into the first trigger node and resets it.

Therefore: the countdown is cancelled and the LEDs will stay on.
Or more correctly: They won't be told to turn off.

And your output is labled OUTPUT. Just send that to the NEOPIXEL node.

@dceejay.... If you can find a better way: I'd appreciate it.
But I can't think of a better way without looping stuff on a function node and doing node.context stuff.

1 Like

I am now slightly suspicious I got it really wrong with what I read of your request.

Oh, @cscmario.... if you have done as I explained and Double pressed the button so the LEDs are always ON.

To turn the OFF, just press the inject node (press the button) and they will turn off after 10 seconds.

Here is a simpler version... yes I hadn't appreciated that the input was a push button so sends a 1 the on release - so the first two node simulate that - the first function then sets up the context - the second resets it if reset by a timeout

[{"id":"e251ef8e.e7c39","type":"trigger","z":"bc6ce009.a9549","name":"","op1":"255,255,255","op2":"0,0,0","op1type":"str","op2type":"str","duration":"10","extend":false,"overrideDelay":false,"units":"s","reset":"false","bytopic":"all","topic":"topic","outputs":1,"x":410,"y":300,"wires":[["569d62f.dece79c","a661a69c.90baf8"]]},{"id":"20ee8ed1.f18a82","type":"switch","z":"bc6ce009.a9549","name":"","property":"payload","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":230,"y":340,"wires":[["e251ef8e.e7c39"],["e251ef8e.e7c39","64be0249.89604c"]]},{"id":"569d62f.dece79c","type":"debug","z":"bc6ce009.a9549","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":610,"y":340,"wires":[]},{"id":"a661a69c.90baf8","type":"function","z":"bc6ce009.a9549","name":"reset the state if timed out","func":"if (msg.payload == \"0,0,0\") {\n    flow.set(\"oldpayload\",false);\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":660,"y":300,"wires":[[]]},{"id":"f74beea5.107e5","type":"function","z":"bc6ce009.a9549","name":"toggle the state","func":"if (msg.payload == 1) { // Only handle 1s\n    msg.payload = !(flow.get(\"oldpayload\") || false);\n    flow.set(\"oldpayload\",msg.payload);\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":160,"y":280,"wires":[["20ee8ed1.f18a82"]]},{"id":"64be0249.89604c","type":"change","z":"bc6ce009.a9549","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"0,0,0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":360,"wires":[["569d62f.dece79c"]]},{"id":"97f18e3f.d9d2b","type":"trigger","z":"bc6ce009.a9549","name":"","op1":"1","op2":"0","op1type":"num","op2type":"num","duration":"250","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":280,"y":120,"wires":[["f74beea5.107e5"]]},{"id":"91bb0dc4.e450c","type":"inject","z":"bc6ce009.a9549","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":120,"wires":[["97f18e3f.d9d2b"]]}]

But you can't double press it to get the LEDs to stay on all the time with that.

(oh. Just saw you edited the flow.)

I don't see any requirement for staying on... all it says it go back to start.
If when button pressed led is off then turn it on for 10 seconds
If when button pressed led is on turn it off