Detect physical button switch press (short/long press / double, tripple press) on GPIO of raspberry

1,887 views
Skip to first unread message

Dave

unread,
Apr 25, 2018, 9:59:58 AM4/25/18
to Node-RED
Dear comunity

I want to use a simple button switch on a raspberry pi with node-red. I failed to get this working after a lot of research and tries on my own...
Actually I am using an arduino board to detect the button press... (short press / long press / double, triple press) and then send a command over the serial interface to the raspberry pi where node-red is running.

I would like to get rid of the arduino board in the project, so do you know a easy way to handle this?
I tried it with the timed-counter (https://flows.nodered.org/node/node-red-contrib-timed-counter)... any expert here that could tell me best working setup including connection advice on the raspberry?

Thanks a lot in advance
Dave


Bart Butenaers

unread,
Apr 25, 2018, 5:09:22 PM4/25/18
to Node-RED
Hi Dave,

I'm not the 'button' expert of this community.  However - by coincidence - a colleague of mine asked a rather similar question today.  So two birds with one stone...

You could create a very compact flow with a single function node.  However a similar behaviour could be accomplished with existing nodes (see below).  I used the node-red-contrib-timed-counter and the node-red-contrib-interval-length node, which has been contributed by a very nice fellow ;-)

  1. The RPI-GPIO node reads the value from e.g. header pin 16 on your Raspberry.  The internal pull-up resistor pulls the pin to 1 (i.e. 3,3V), and with a hardware button you can pull the button to 0 (i.e. GND).  The software debouncer makes sure that you get a single pulse.
  2. To simulate a similar behaviour, I added a template node with a button for your dashboard.  When the button is pressed, the signal goes to 0.  And it will stay at 0 as long as the button is being hold down.  As soon as you release the buton, the signal goes back to 1.
  3. The simulated button signal can be displayed in a chart.
  4. The period between the successive messages is being calculated (in milliseconds), and the calculated period length is stored in msg.period.
  5. We are only interested how long the signal is 0 (not the length of 1), so we only watch the raising edges.
  6. When the pulse is longer then 2 seconds, it is considered as a long pulse (and the first output is triggered).  Otherwise it is a short pulse and the second output is triggered.
  7. We show a 'long pulse detected' in the debug window.
  8. For short pulses, all pulses within a period of 2 seconds are being counted.
  9. Depending on the number of short pulses, one of the three available outputs are being triggered.
  10. Show in the debug window how many successive short pulses are being displayed.

Good luck with it !!!

Bart

Bart Butenaers

unread,
Apr 25, 2018, 5:11:11 PM4/25/18
to Node-RED
Since you cannot import screenshots yet in your flow editor, here is the flow in json format ;-)

[{"id":"4fc9c41e.f8fa5c","type":"switch","z":"47b91ceb.38a754","name":"Long pulse?","property":"period","propertyType":"msg","rules":[{"t":"gte","v":"2000","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":706,"y":614,"wires":[["4987e844.2b99e8"],["8e3ae455.1f7d68"]],"outputLabels":["Long pulses",""]},{"id":"8e3ae455.1f7d68","type":"timed-counter","z":"47b91ceb.38a754","name":"Count short pulses","timelimit":"2000","withhold":true,"fixedtimeout":false,"x":926,"y":654,"wires":[["42ea87d1.824028"]]},{"id":"4987e844.2b99e8","type":"debug","z":"47b91ceb.38a754","name":"Long pulse detected","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":936,"y":607,"wires":[]},{"id":"4099663e.517818","type":"debug","z":"47b91ceb.38a754","name":"1-pulse series","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1356,"y":614,"wires":[]},{"id":"e8e980a3.55428","type":"ui_template","z":"47b91ceb.38a754","group":"16a1f12d.07c69f","name":"Long press button","order":0,"width":0,"height":0,"format":"<md-button ng-mousedown=\"send({payload: 0})\" ng-mouseup=\"send({payload: 1})\">Pulse</md-button>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":109,"y":680,"wires":[["378642e7.d6910e","e0ba4c5b.a158c"]]},{"id":"378642e7.d6910e","type":"ui_chart","z":"47b91ceb.38a754","name":"Show chart","group":"16a1f12d.07c69f","order":0,"width":0,"height":0,"label":"chart","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"step","nodata":"","dot":false,"ymin":"0","ymax":"2","removeOlder":1,"removeOlderPoints":"20","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":329,"y":680,"wires":[[],[]]},{"id":"42ea87d1.824028","type":"switch","z":"47b91ceb.38a754","name":"Short pulse series?","property":"count","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":1146,"y":654,"wires":[["4099663e.517818"],["5b4743e6.4f20ec"],["72adf9a2.f30e38"]],"outputLabels":["Long pulses","",""]},{"id":"5b4743e6.4f20ec","type":"debug","z":"47b91ceb.38a754","name":"2-pulse series","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1356,"y":654,"wires":[]},{"id":"72adf9a2.f30e38","type":"debug","z":"47b91ceb.38a754","name":"unsupported","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1346,"y":694,"wires":[]},{"id":"5d9955df.294f8c","type":"switch","z":"47b91ceb.38a754","name":"Rising edge?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":529,"y":614,"wires":[["4fc9c41e.f8fa5c"]]},{"id":"e0ba4c5b.a158c","type":"interval-length","z":"47b91ceb.38a754","format":"mills","bytopic":false,"minimum":"","maximum":"","window":"","timeout":false,"msgTimeout":"","minimumunit":"msecs","maximumunit":"msecs","windowunit":"msecs","msgTimeoutUnit":"msecs","startup":true,"msgField":"period","repeatTimeout":false,"name":"","x":339,"y":620,"wires":[["5d9955df.294f8c"],[]]},{"id":"be99df9d.9180a","type":"rpi-gpio in","z":"47b91ceb.38a754","name":"","pin":"16","intype":"up","debounce":"25","read":false,"x":139,"y":620,"wires":[["e0ba4c5b.a158c"]]},{"id":"16a1f12d.07c69f","type":"ui_group","z":"","name":"Default","tab":"f136a522.adc2a8","order":1,"disp":true,"width":"6"},{"id":"f136a522.adc2a8","type":"ui_tab","z":"","name":"Home","icon":"home","order":1}]

Dave

unread,
Apr 26, 2018, 1:33:58 AM4/26/18
to Node-RED
Dear Bart

Sadly I didn't see your, I must say AMAZING answer yesterday evening... but it looks great so far! thank you very much for help already, i'll get back to you here after trying it with the physical button switch. I'm not used to get such good answers that quickly! :-)

All the best, Dave

Stephen Mann

unread,
Apr 27, 2018, 1:15:01 AM4/27/18
to Node-RED
Maybe I am missing something...  Why don't you simply time the button press on the Pi and send the appropriate MQTT message?

 

Bart Butenaers

unread,
Apr 27, 2018, 2:15:20 AM4/27/18
to Node-RED
Hi Stephen,

I hope that is a rhetorical question, because I have no clue whether you are missing something :-)

Would be nice if you could provide an example flow of what you mean, and some explanation (e.g. how Dave can specify with your solution which short pulses belong together).  If it is a simpler solution, I will send my example flow straight to the garbage bin.

Kind regards,
Bart
Reply all
Reply to author
Forward
0 new messages