In this article by Tim Cox, author of the book Raspberry Pi Cookbook for Python Programmers – Second Edition, we will see how to control Raspberry Pi with the help of your own buttons and switches.
(For more resources related to this topic, see here.)
Responding to a button
Many applications using the Raspberry Pi require that actions are activated without a keyboard and screen attached to it. The GPIO pins provide an excellent way for the Raspberry Pi to be controlled by your own buttons and switches without a mouse/keyboard and screen.
You will need the following equipment:
- 2 x DuPont female to male patch wires
- Mini breadboard (170 tie points) or a larger one
- Push button switch (momentary close) or a wire connection
to make/break the circuit
- Breadboarding wire (solid core)
- 1k ohm resistor
The switches are as seen in the following diagram:
The push button switch and other types of switches
The switches used in the following examples are single pole single throw (SPST) momentary close push button switches. Single pole (SP) means that there is one set of contacts that makes a connection. In the case of the push switch used here, the legs on each side are connected together with a single pole switch in the middle. A double pole (DP) switch acts just like a single pole switch, except that the two sides are separated electrically, allowing you to switch two separate components on/off at the same time.
Single throw (ST) means the switch will make a connection with just one position; the other side will be left open. Double throw (DT) means both positions of the switch will connect to different parts.
Momentary close means that the button will close the switch when pressed and automatically open it when released. A latched push button switch will remain closed until it is pressed again.
The layout of the button circuit
We will use sound in this example, so you will also need speakers or headphones attached to audio socket of the Raspberry Pi.
You will need to install a program called flite using the following command, which will let us make the Raspberry Pi talk:
sudo apt-get install flite
After it has been installed, you can test it with the following command:
sudo flite -t "hello I can talk"
If it is a little too quiet (or too loud), you can adjust the volume (0-100 percent) using the following command:
amixer set PCM 100%
How to do it…
Create the btntest.py script as follows:
#!/usr/bin/python3 #btntest.py import time import os import RPi.GPIO as GPIO #HARDWARE SETUP # GPIO # 2[==X==1=======]26[=======]40 # 1[=============]25[=======]39 #Button Config BTN = 12 def gpio_setup(): #Setup the wiring GPIO.setmode(GPIO.BOARD) #Setup Ports GPIO.setup(BTN,GPIO.IN,pull_up_down=GPIO.PUD_UP) def main(): gpio_setup() count=0 btn_closed = True while True: btn_val = GPIO.input(BTN) if btn_val and btn_closed: print("OPEN") btn_closed=False elif btn_val==False and btn_closed==False: count+=1 print("CLOSE %s" % count) os.system("flite -t '%s'" % count) btn_closed=True time.sleep(0.1) try: main() finally: GPIO.cleanup() print("Closed Everything. END") #End
How it works…
We set up the GPIO pin as required, but this time as an input, and we also enable the internal pull-up resistor (refer to the Pull-up and pull-down resistor circuits subsection in the There’s more… section of this recipe for more information) using the following code:
After the GPIO pin is set up, we create a loop that will continuously check the state of BTN using GPIO.input(). If the value returned is false, the pin has been connected to 0V (ground) through the switch, and we will use flite to count out loud for us each time the button is pressed.
Since we have called the main function from within a try/finally condition, it will still call GPIO.cleanup() even if we close the program using Ctrl + Z.
We use a short delay in the loop; this ensures that any noise from the contacts on the switch is ignored. This is because when we press the button, there isn’t always perfect contact as we press or release it, and it may produce several triggers if we press it again too quickly. This is known as software debouncing; we ignore the bounce in the signal here.
The Raspberry Pi GPIO pins must be used with care; voltages used for inputs should be within specific ranges, and any current drawn from them should be minimized using protective resistors.
We must ensure that we only connect inputs that are between 0V (Ground) and 3.3V. Some processors use voltages between 0V and 5V, so extra components are required to interface safely with them. Never connect an input or component that uses 5V unless you are certain it is safe, or you will damage the GPIO ports of the Raspberry Pi.
Pull-up and pull-down resistor circuits
The previous code sets the GPIO pins to use an internal pull-up resistor. Without a pull-up resistor (or pull-down resistor) on the GPIO pin, the voltage is free to float somewhere between 3.3V and 0V, and the actual logical state remains undetermined (sometimes 1 and sometimes 0).
Raspberry Pi’s internal pull-up resistors are 50k ohm – 65k ohm and the pull-down resistors are 50k ohm – 65k ohm. External pull-up/pull-down resistors are often used in GPIO circuits (as shown in the following diagram), typically using 10k ohm or larger for similar reasons (giving a very small current draw when not active).
A pull-up resistor allows a small amount of current to flow through the GPIO pin and will provide a high voltage when the switch isn’t pressed. When the switch is pressed, the small current is replaced by the larger one flowing to 0V, so we get a low voltage on the GPIO pin instead. The switch is active low and logic 0 when pressed. It works as shown in the following diagram:
A pull-up resistor circuit
Pull-down resistors work in the same way, except the switch is active high (the GPIO pin is logic 1 when pressed). It works as shown in the following diagram:
A pull-down resistor circuit
In addition to the switch, the circuit includes a resistor in series with the switch to protect the GPIO pin as shown in the following diagram:
A GPIO protective current-limiting resistor
The purpose of the protection resistor is to protect the GPIO pin if it is accidentally set as an output rather than an input. Imagine, for instance, that we have our switch connected between the GPIO and ground. Now the GPIO pin is set as an output and switched on (driving it to 3.3V) as soon as we press the switch; without a resistor present, the GPIO pin will directly be connected to 0V. The GPIO will still try to drive it to 3.3V; this would cause the GPIO pin to burn out (since it would use too much current to drive the pin to the high state). If we use a 1k ohm resistor here, the pin is able to be driven high using an acceptable amount of current (I = V/R = 3.3/1k = 3.3mA).
Resources for Article:
- Raspberry Pi LED Blueprints [article]
- Raspberry Pi and 1-Wire [article]
- Learning BeagleBone Python Programming [article]