Easy way to detect multiple push-buttons on GPIO

4 posts
by TimG » Sun Feb 14, 2016 12:37 am
Today I was writing a script to automate a few things. It only needed a few simple controls, so I wanted to run without screen or keyboard. A handful of LEDs and push-buttons was enough for the user interface. I also wanted to write in bash, since I was executing a lot of system commands.

To control the LEDs and buttons I was using the gpio command-line utility from the excellent WiringPi package. This provides the gpio wfi command which waits for a rising or falling edge on a GPIO pin. The problem was how to monitor more than one pin at a time, without resorting to a "proper" programming language.

I wrote a few versions of my script, employing various combinations of coprocesses, background processes, and fifo buffers. But in the end I discovered a very simple and elegant solution using command substitution, which I thought was worth posting here.

The button subroutine loops and prints the pin number every time it detects a falling edge. The last line of the main loop launches this subroutine twice, in two background processes, and sends any output to the read command inside the while loop. The if statements figure out which button was pressed, and act accordingly. My version blocks until a button press is detected, but you could add a timeout to the read command without any risk of missing any presses.

Code: Select all
# momentary push-buttons are connected between GPIOs and Gnd

button() {
  gpio -g mode $pin in # make sure pin is configured as an input
  gpio -g mode $pin up # enable pull-up resistor

  while :; do
    gpio -g wfi $pin falling # wait for a falling-edge
    echo $pin
    sleep 1 # debounce

# --- main loop ---
while :; do
  read numbut
  if [ $numbut -eq 22 ]; then
    echo Button A was pressed
  elif [ $numbut -eq 23 ]; then
    echo Button B was pressed
done < <( button 22 & button 23 & ) # buttons on GPIOs 22 & 23
User avatar
Posts: 225
Joined: Tue Apr 03, 2012 12:15 am
Location: Switzerland
by madsen » Mon Mar 14, 2016 8:58 pm
Hi there,

Very nice script you have created there.

I can´t seem to get it to work, mabye you can tell me why it won´t work for me?

root@raspberrypi:/home/pi# sh buttons.sh 21
buttons.sh: 24: buttons.sh: Syntax error: redirection unexpected

Best regards
Posts: 1
Joined: Mon Mar 14, 2016 8:50 pm
by TimG » Tue Mar 15, 2016 7:48 am
Hi Madsen,
The script needs to run in bash. Drop the 'sh' part of your command-line and let the system choose the shell according to the #! on the first line. It will also run as a normal user, so no need for root.
User avatar
Posts: 225
Joined: Tue Apr 03, 2012 12:15 am
Location: Switzerland
by spicycheddar » Thu Jan 26, 2017 4:40 pm
Thank you so damn much for this. :mrgreen: :mrgreen: :mrgreen:
Posts: 7
Joined: Thu Jan 26, 2017 4:37 pm