|
PiButton - Simple user input for Raspberry Pi |
February 2014
Introduction
This project page describes a simple and cheap way of invoking commands on a Raspberry Pi without having to have a terminal session connected.
The objective was to be able to invoke one of a number of Operating System commands from a single button, by using the number of consecutive presses to represent the chosen command. The command would need to be set in a text configuration file which could be easily changed, and read in when the system boots up.
Background
Having set up a Raspberry Pi with a camera board and the motion software, so that it records .avi files and sends emails when movement is triggered, I realised that there were a couple of things I needed an SSH terminal connection to do when it was running. However, it would have been much nicer if I could have done these on the Raspberry Pi itself, rather than having to go to a computer and the connect a terminal session to it. These specific functions for the application in hand, were; stopping the motion service running, starting it again, halting the OS and restarting the OS.
Initially one answer seemed to be to provide a switch for each of these functions which each connected to an input on the GPIO, and then to have a program which would auto run at boot time, and continually monitor the status of the GPIO inputs and invoke any necessary commands. However, even with miniature switches, there not much room anywhere on a standard Raspberry Pi case for that many functions. A more practical (though not necessarily more ergonomic) solution is to overload a single switch. Software would instead; monitor a single input pin on the GPIO for presses from a switch, and multiple presses would be accumulated. If the user waits for two seconds after pressing the button, the number of presses accumulated so far is used to determine the appropriate command to execute.
These commands and the number of presses needed for each, would be stored in a text configuration file which the software program would read when the system starts up. The commands could obviously be used for a variety of purposes and would not need to be specific to any single Raspberry Pi application.
Example
Operation
Consider the following text configuration file which
allows the movement detection software, "motion" to be stopped or
started, and the Raspberry Pi OS to powered down or rebooted based on the
number of times a button is pressed:
Based on the settings above, the following video demonstrates :
Operation |
Action |
stopping motion |
two button presses, camera LED goes out as motion
stops |
starting motion |
three button presses, camera LED comes back on as
motion restarts |
halting the Raspberry Pi |
four button presses, Raspberry Pi powers down into halt state (takes
about 10s) |
Restarting the Raspberry |
one button press, utilising using GPIO ‘wake from
Halt’ feature, restarts the OS (takes about 30s) |
if video is not
visible, your browser does not support HTML5 video, you can download the video instead.
Hardware
Note shorting any pins on the GPIO header without ensuring that the current is suitably limited will permanently damage the GPIO. You normally need to provide a resistor in the circuit. I am not responsible for any damage to your hardware. If you are in doubt, don’t do it. Find out first.
|
There are a couple of GPIO pins which each have an internal pull up resistor. If one of these were used for the button input, all I would need would be a switch which shorted the pin to ground. Current limiting would be done internally. These pins with internal pull up resistors are the I2C pins, SDA and SCL. The SCL pin occupies the GPIO header pin (pin5) and is opposite one of the ground pins (pin 6). This makes it convenient for fitting a 2 pin connector across pins 5 and pin 6 from the switch.
One slight complication is that the GPIO pin used is different for Revision 1 boards (GPIO 1) than for Revision 2 boards (GPIO 3). This means that the software would need to work out which revision of board it was running on when it starts up, and select the appropriate input to monitor. That is a software problem though, and for now all I needed was the ability to short pins 5 and 6 (on the GPIO header) from a button, regardless of the board Revision.
A ‘momentary, SPST, normally open’ push switch was wired up to a 0.1 inch pitch, two way female connector.
A hole was drilled and then filed out in the USB socket end of an Adafruit PiBox to accommodate the switch, and the female connector was push fitted on pins 5 and 6 of the GPIO header.
After trying to fit this, I was found that using it together with a micro SD Card adapter (which is thicker than an SD Card) in an Adafruit PiBox was a very tight fit. So I removed the black plastic pin casing, applied heat shrink to the pins and push fitted them individually to pins 5 and 6 on the GPIO header.
Wake from Halt Feature
Note that many boards since 2012 include a feature which allows the OS to be woken following a halt/powerdown command. This is achieved by momentarily shorting GPIO header, pin 5 to ground (see http://elinux.org/RPI_safe_mode). This means that following halt/powerdown the Raspberry Pi can be restarted by pressing the same switch (once) which was used to halt it in the first place. This is the last action demonstrated in the video above
Software
The software uses a single C module (pibutton.c), and requires the bcm2835 library for accessing the GPIO from http://www.airspayce.com/mikem/bcm2835/
Functionality
The following steps are carried out by the pibutton software:
· Reads in the commands from /etc/pibutton.conf and displays them to stdout
· Initialises bcm2835 library
· Deduces whether the board is Revision 1 or Revision 2 or later (by analysing /proc/cmdline)
· Initialises the relevant GPIO pin as an input (based on board Revision found in the step above) for SCL on GPIO header pin 5
· Then it enters a continuous loop, monitoring for button press and accumulating presses. When 2 seconds has elapsed the relevant command is executed. Care is taken to use sleep rather than delay to prevent consuming cpu cycles unnecessarily.
Installation
Install the latest version of bcm2835 from the link above. Instructions are provided on that site for its own installation.
Compile pibutton.c using
gcc -o pibutton
pibutton.c -l bcm2835 –lrt
Ensure it is executable
sudo chmod
+x pibutton
Ensure that the switch is fitted across pins 5 and 6 of the GPIO header.
Edit the pibutton.conf file and save it to the /etc directory
Run pibutton from the command prompt and observe standard out.
You should see a program header, the contents of the configuration file as read in by the program, and which Revision Raspberry Pi board you are using, and whether it has been overclocked or not :
=================================
Pi Button
pibutton@mhr.me.uk February 2014
=================================
1
2
3
4 poweroff
5 reboot
6
7
8
9
Running, expecting switch on GPIO 1 (Board revision 1, overclocked
=0)
Pressing the button should output feedback on the terminal (e.g. 1 press = no command).
GPIO 1 pressed (1)
Detected 1 presses, Command 1 is not configured, ignoring this
button input
Pressing the button so that a command is invoked should output feedback on the terminal and carry out the command (e.g. 5 presses = reboot)
GPIO 1 pressed (1)
GPIO 1 pressed (2)
GPIO 1 pressed (3)
GPIO 1 pressed (4)
GPIO 1 pressed (5)
Detected 5 presses,
executing command [reboot]
The system is going
down for reboot NOW!k (pts/0) (Sun Feb 9
14:40:59 2014):
If that all works, we can now make it auto run (see next section).
The auto run technique being used here is to add the file to rc.local.
This runs as root so the pibutton executable needs to be owned by root
sudo chown root pibutton
and move it to /usr/sbin
sudo mv /usr/sbin
Edit /etc/rc.local
sudo nano /etc/rc.local
And add the line
/usr/sbin/pibutton
Just before the existing line:
exit 0
Save the file, and exit the editor (Ctrl-O, Enter, Ctrl-X)
Reboot the Raspberry Pi. When it has restarted check that pibutton has run up by checking it has a process number.
pi@dev:~# pidof pibutton
2502
root@mtu:~#
Carry further out checks by pressing the button and ensuring the expected commands are executed.
Warning: This project is a prototype, built for fun and
proof of concept.
Downloads are therefore made available in the hope that they
will be useful, but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose.
All source code is made available under GNU General Public
License.