This is a dead-simple way to test that GPIO on the Raspberry Pi is working. I have an SKPang Raspberry Pi starter kit A. But all you need is
- A Raspberry Pi.
- An LED.
- A button.
- A resistor, approximately 270Ω.
- Some way to connect these to each other and the GPIO pins.
In particular, you don't need to download any software, not even using your package manager. (I'm assuming you already have bash
.)
My main sources for this are the elinux page on Rpi low-level peripherals and Gordon Henderson's Tux Crossing.
We start by not using GPIO at all, and just powering an LED from the Rpi. Refer to this diagram of the pin layout. Pin 1 is the one closest to the SD card; pin 2 is adjacent to pin 1 on the short side, pin 3 is adjacent to pin 1 on the long side, and so on. If the SD card is "top" and the HDMI port is "left", then numbering proceedes left-to-right and top-to-bottom as if you were reading a book.
Pin 1 provides a constant 3.3V, and pin 6 is ground. So connect an LED and a resistor in between these, and the LED should light up. The +
terminal of the LED needs to be connected to pin 1, and the -
terminal to pin 6. The -
terminal is the one with the shorter leg, and also the one where the rim of the cap is slightly flattened.
If you have the starter kit, here's one way you can create that circuit. Attach pin 1 to 1f
on the breadboard. Place the LED with +
connected to 1g
and -
connected to 2g
. Place the resistor between 2h
and the -
strip on the right hand side of the breadboard. Connect another terminal on that strip to pin 6.
(The connections in a breadboard work like so: the rows are numbered, and each row has two sets of five columns taking letters a
through j
. On each row, a
through e
are all connected, and so are f
through j
. None of the rows are interconnected. Each side of the breadboard has a +
column in which every terminal is connected, and a -
column in which every terminal is connected. The purpose of these is to connect them to a source of power or grounding which can then be supplied to the whole board.)
Having done that, the LED should light up. If not, figure out why not and come back.
Now we'll make it so you can turn the LED on and off. Move the wire from pin 1 to pin 11, which is GPIO pin 17. (I have no idea why the numbers are as they are.)
The LED will be off, but we can turn it on from the command line. Pull up a root shell (using sudo
will become tedious), and type:
cd /sys/class/gpio
echo 17 > export
echo out > gpio17/direction
echo 1 > gpio17/value
The LED should turn on. The export
line seems to be telling the kernel to turn on that pin; without it, the gpio17
directory doesn't exist. The direction
line says GPIO pin 17 will be used for output; the value
line turns it on.
To turn it off, echo 0 > gpio17/value
.
Now we want to connect pin 3 to one side of a button, and the other side to pin 6. If you have the starter kit, it might not be obvious what the "sides" of the button are, since it has four terminals. If you place the button in a breadboard, it covers a 4x3 rectangle. The two terminals along each long side are connected, and the two long sides are connected only when the button is pressed.
So for example, you can place the button's terminals in 1g
, 1j
, 3g
and 3j
, connecting 1f
to pin 3 and 3f
to pin 6.
We need to use either pin 3 or pin 5 here because these are connected on the Pi to pin 1 through a pull-up resistor. This keeps them at 3.3V (1
) when they aren't connected to anything else, but when connected to ground they drop to 0V (0
).
Pin 3 is gpio0, so set it up for input:
echo 0 > export
echo in > gpio0/direction
Now we can read the value with cat gpio0/value
. When the button is down, we should read 0
; when up, we should read 1
.
Now let's put input and output together, and use the state of the button to turn the LED on or off.
The RPi has only one ground pin which you need to connect both the LED circuit and the button circuit to. If you have an M/M wire, you can easily do this by connecting the -
column to ground like we did with the LED. If not, it might seem like there isn't space to have a resistor, a wire connected to ground, and the button all in one group of five columns. But to make extra space, you can place the button bridging the gap in the middle of the breadboard.
One possible configuration has:
- Wires connecting pin 3 to
7d
, 6 to9j
and 11 to1f
. - The LED connecting
1g
(+
) to2g
(-
). - The resistor connecting
2h
to9h
. - The button in terminals
7e
,7f
,9e
and9f
.
With that set up, you can have the LED light up as long as the button is not pressed:
while true; do
cat gpio0/value > gpio17/value
done
(Use control-C to interrupt this and return to a prompt.) Or as long as the button is pressed:
while true; do
read val < gpio0/value
echo $(( ! val )) > gpio17/value
done
Or to toggle the LED every time the button is pressed:
while true; do
read val < gpio0/value
if (( val == 0 && last == 1 )); then
read state < gpio17/value
echo $(( ! state )) > gpio17/value
fi
last=$val
done
(This last one makes use of the fact that if you try to read an output pin, it tells you its current value.)
If that all worked, congratulations! Now you should probably install an actual GPIO library, and turn your mind to more interesting projects.