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
#!/bin/bash
# momentary push-buttons are connected between GPIOs and Gnd
button() {
pin=$1
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
done
}
# --- 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
fi
done < <( button 22 & button 23 & ) # buttons on GPIOs 22 & 23