Introduction: Raspberry Pi: Python Scripting the GPIO

The GPIO: General Purpose Input/Output lets you interface your Raspberry Pi with the outside world, making it a powerful interactive device for just $40-$50.

This Instructable will show you how to install the GPIO package on your Raspberry Pi and how to wire up a simple push button circuit with an LED.

I use the command-line and Python for this, no web browser or GUI.

Before you do this Instructable, make sure you have your Raspberry Pi ready for action. My Ultimate Raspberry Pi Configuration Guide covers how to do this in detail.

You will want to have an internet connection to download the packages and probably use ssh. 

Step 1: Gather Your Components

* Raspberry Pi
* Cobbler breakout board with cable — you can order this from Adafruit for $8.
* Breadboard
* Wires — breadboard or otherwise
* standard LED
* 270 Ohm resistor
* 1K resistor
* 10K resistor
* Push button
* USB power for RPI (not pictured)
* Monitor + keyboard (not pictured)

* wire-stripper
* small diagonal snips
* multimeter for checking continuity

Step 2: Assemble Your Circuit

We will have a simple push button that will turn an LED on when the button is pressed and off when it is released. I know, it's not super-exciting, but think of this as a building block for digital input and output.

Here is the schematic and breadboard diagram.

The LED is straightforward: 270 Ohm resistor is needed to light up the LED from a 3.3V input.

The concept is simple: the LED is an output of pin 4 and the button is an input of pin 22. The button circuit has a pull-down resistor. Pin 22 will be pulled down to zero through the 10K resistor when the button is inactive. When it gets pressed, the 3.3V power from the Raspberry Pi goes into the pin 22 input, bypassing the 10K resistor.

Without the 10K resistor, you'll have a floating input and will get erratic behavior in your code. The 1K resistor protects the Raspberry Pi from too much current.

Step 3: Putting It on the Breadboard

After doing the wiring diagram in Fritzing, I laid out the components on a real breadboard. Strip the wires and use the diagonal snips for a clean-looking breadboard. 

This is what it looks like with the Cobbler breakout board before I attach the ribbon cable to the Pi.

Even with a simple circuit like this, double-check your components to make sure you're not shorting your circuit or anything else like that.

Step 4: Connect to the Pi

Use the breakout cable and connect the cobbler to your Raspberry Pi.

You will want to be connected to the internet to download the latest packages via Wifi or an Ethernet cable.

Power up your Raspberry Pi.

Step 5: Install the GPIO Package

The Raspberry Pi GPIO libraries may come with the latest versions of Wheezy, but maybe not.

Just in case, I suggest installing them again, which involves first installing the Python Development toolkit that RPi.GPIO uses and then the GPIO package itself.

Type in
sudo apt-get install python-dev
Then, for the GPIO libraries:
sudo apt-get install python-rpi.gpio
If asked for confirmation on either of these, press Y

You'll get the usual Linux garble like this. In my case, the Python development tools were not installed but GPIO was.

Step 6: Blink an LED in Python

At this point, I run the Raspberry Pi from my monitor with a keyboard plugged in — I usually do the package updates from ssh. On the command line, create a new python script by invoking nano.
sudo nano
And enter in this script. The advantage with using ssh is that you can just copy-and-paste the script. Alternatively, I have this on a GitHub repository.

# by Scott Kildall (
# LED is on pin 4, use a 270 Ohm resistor to ground

import RPi.GPIO as GPIO
import time

GPIO.setup(4, GPIO.OUT)

state = True

# endless loop, on/off for 1 second
while True:

Ctrl-X, Y to save the file.

Now run the script:
sudo python
Note: you have to invoke sudo — root access for the GPIO library.

You should have a blinking LED on your circuit. We're not using the switch at all at this point.

Ctrl-C to exit the script

how it works
- Pin 4 is an input pin. We alternate between high (True) and low (False) for 1 second at a time.
- I turn warnings off because I was getting errors in my script because the GPIO wasn't properly closed (this shouldn't matter and I found it an annoyance).
- Setting the mode to BCM means that the pin numbers etched on the Raspberry Cobbler match the ones that you are using in your code.

Step 7: Python Script for Switch-activated LED

Now, we'll try adding a switch, using the same circuit.

Type in:
sudo nano
You can also refer to the GitHub repository, if need be.

# by Scott Kildall (
# LED is on pin 4, use a 270 Ohm reistor to ground
# Switch is on pin 22, use a pull-down resistor (10K) to ground

import RPi.GPIO as GPIO
import time

GPIO.setup(4, GPIO.OUT)

# input of the switch will change the state of the LED
while True:

Cntl-X, Y to save the file
(note the indentations af
Now run the script:
sudo python
If you press the switch, the LED should turn on and when you let it go, it should turn off. Congratulations, you have an input and output into your Raspberry Pi.

how it works
This is like the previous script, except that we are designating Pin 22 as an input pin. We set the output of Pin 4 to match the input of Pin 22. When Pin 22 goes high, so does Pin 4. The time.sleep(0.05) is there to account for any debouncing in the button. 

Step 8: Troubleshooting...or Done!

Here is the GitHub repository for some of the GPIO scripts that I reference, and am adding to.

Adafruit, as always has some excellent material on the GPIO and Raspberry Pi.

There's a lot that can go awry with electronics and interfacing with the outside world. Here are some suggestions for things to look for:

- If you're getting no flashing LED or the switch doesn't seem to work, check your breadboard connections or the switch doesn't work, check your breadboard connections. Make sure you have the right components in the right places. Test for continuity with a multimeter.

- Make sure your LED is facing the right direction. Flat side goes to ground. Longer lead is oriented to the positive electron flow.

- You can test your LED and the GPIO connection by connecting the LED to the 3.3V output of the GPIO and to the 270 Ohm resistor and to the ground of the GPIO.

I hope this was helpful
For more Raspberry Pi projects and other programmatic artworks, you can find me here: @kildall or
Scott Kildall


VaibhavV18 made it! (author)2017-02-08


MichiL made it! (author)2016-01-13

I used a soldering iron. Way cheaper. And not as hard as it seems.
Now I have my led strip connected, and it works great.

kamalk21 made it! (author)2015-11-14

I need this pdf to use this feature for my project. But I cant afford this. Can anyone mail me this PDF.

TirusW made it! (author)2015-09-27

scottkildall made it! (author)2015-01-15

good catch! my circuit diagram has the LED flipped. I'll have to correct this at some point soon.

MarioH2 made it! (author)2015-01-15

Hey! thanks a lot for the tutorial! it's an indescriptible feeling when you make it work!. I just have a quick comment:

I am no expert on electronics, however, from other tutorials I have taken, I have noticed that in the breadboard diagrams, the anode (+) leg is usually depicted as the longer "curved" leg. however, in your diagram this leg is connected to ground (also the LED triangle in schematic points towards the output). Thus, the first time I tried it it didn't work but once I changed the direction of the legs it worked like magic!.

scottkildall made it! (author)2014-04-06

Good point. I'm usually stopping my Python scripts with a ctrl-C rather than an event like a keydown, and so the GPIO.cleanup() doesn't get called. My workaround is setting the warnings to false. But, as you point out, the GPIOs will stay at the state they were last in, leaving the LEDs on — better coding practice would be to properly close the ports.

ssokolow made it! (author)ssokolow2014-11-15

The simplest way to ensure some cleanup code gets run is to wrap your while loop in a try/finally block.

If you specifically want to catch Ctrl+C but nothing else, you can use try/except to catch KeyboardInterrupt.

Finally, if you want a more robust way to ensure some cleanup gets done, take a look at lines 312 through 322 in this revision of my Procrastinator's Timeclock utility.

First, it assigns the cleanup function to sys.exitfunc so it'll get called on clean exit, then it hooks all the common POSIX signals the kernel might send s ensure that they trigger a clean exit.

* SIGINT is sent by Ctrl+C, which INTerrupts the program.
* SIGTERM is sent by things like task managers politely asking your program to TERMinate itself.
* SIGHUP is sent by the kernel when your program loses the terminal it's attached to.
* SIGQUIT is sent by Ctrl+\, which asks the program to quit and dump core if core dumping is enabled.

(My code technically doesn't handle SIGQUIT properly, since it doesn't dump core, but I've never seen people using it properly.)

Finally, it also uses try/except to catch Ctrl+C, just to play it safe. (And it's still not perfect because PyGTK doesn't let the program attach a handler for "lost connection to X server")

If you want a version that's a bit more complicated, but also works on Windows, look at this revision:

(It checks that each signal exists before hooking it)

scottkildall made it! (author)scottkildall2014-11-16

Thanks for sharing!

This is beyond what I've tried to do so far. But, I'll check out the SIG___ interrupts that you've pointed out here.

And hopefully others can make use of your code on GitHub as well.

ssokolow made it! (author)ssokolow2014-11-15

Oh, I meant to mention where the name "SIGHUP" comes from.

Back in the days when computers cost a fortune and users had to share them, it meant that the modem connecting the terminal to the computer had Hung UP.

cudy789 made it! (author)2014-04-03

sometimes if your don't properly close the gpios they stay at the state they were last set. when I was making a robot with my pi, and I quickly cancelled the script so it wouldn't run into something, it continued on its merry way. simply put GPIO.cleanup() at the end of your program, and you should stop getting that warning. great little indestructible though:)

cudy789 made it! (author)cudy7892014-04-03

great little instructable*

About This Instructable




Bio: Scott Kildall is an new media artist and researcher. He works at Autodesk, Pier 9 and is an artist-in-residence with the SETI Institute
More by scottkildall:Pier 9 Guide: Fusion 360 to OMAX WaterjetStrewn Fields: Waterjet Etching Into StonePier 9 Resource: Setting up 2D profiles for CNC in Fusion 360
Add instructable to: