7/04/2012

Python on the Raspberry Pi: GPIO

Python on the Raspberry Pi: GPIO

If you want to experiment with GPIO on the Raspberry Pi, then be warned there is a danger to the Raspberry Pi. Please follow these instructions at your own risk. I make no warranty as to the correctness of the connections described, but they did work correctly for me without damaging my Raspberry Pi.

Understanding GPIO on the Raspberry Pi

One of the compelling things about the Raspberry Pi is that it includes GPIO pins. The Introduction to  Embedded Programming site has a great overview of GPIO, and how to wire various circuits. What can be confusing about the GPIO pins on the Raspberry Pi is how to locate them. The GPIO pins in the P1 header are the easiest to access, and will be the ones that will be referenced in this post on how to do basic output and input using them.

Reference Material

There is a pdf datasheet and a schematic hosted at RaspberryPi.org. The datasheet describes how GPIO works in detail, starting at page 89. 

The R-Pi_Hub for the Raspberry Pi has  also has several documents.

Referencing Pins

If you notice, in the first table in http://elinux.org/RPi_BCM2835_GPIOs there are two columns RPi connection, and RPi signal name. These are important to understand if you want to program a particular pin to perform a certain function. What I find most useful is the image on the page http://elinux.org/RPi_Low-level_peripherals shown below. If you are unsure as to what you are looking at locate P1 on the Raspberry Pi. It is next to P1-01. There are several methods to refer to a pin:
  • RPi Connection Method:
    • This refers to a physical pin on the board on the P1 header
    • Pins are numbered within the header from 1 to 26
    • If you look at the under side of the connector, the pin with a square pad is pin 1, or P1-01
    • The diagram shows the position of P1-01, P1-02, P1-25, and P1-26 just outside the white box
    • The pins in the bottom row have odd numbers P1-01 through P1-25
    • The pins in the top row have even numbers P1-02 though P1-26
    • For the person making a connection, this method makes the most sense. 
      • Locate a header like P1
      • Locate pin 1 by checking the underside of the connector for the square pad
      • Check diagram for correct numbering of pins
      • Count the position to the pin that you want to reference
      • For example,to access the functionality of GPIO18, or PCM_CLK, locate P1-12.
    • By default, the RPi.GPIO Python module references physical pin numbers like 12 for GPIO18.
  • WiringPi Method:
    • This method refers to the pin referenced in wiringPi functions
    • wiringPi functions are analogous to Arduino GPIO functions   
    • The author of wiringPi that has a table with the pin names and numbers
    • There is also a WiringPython Module based upon wiringPi
    • According to the wiringPi table, P1-12 (GPIO18) is referred to as pin 1.
  • GPIO Number Method:
    • This method refers to a pin by the GPIO number Broadcom gave it
    • This method makes the most sense in the implementation of the software
    • This method is independent of a specific physical implementation 
    • Reference the pin by the signal name, such as GPIO18, or 18.
    • The RPi.GPIO Python module can reference these names: GPIO.setmode(GPIO.BCM)
    • The WiringPython Module can also reference these names: wiringPiGpioMode(True)
    • This is the method that I prefer for any code I write

So What's The Confusion?

Depending on which library you are using, and what mode it is in, then the numbers or names used to reference pins may vary. However, with each of these libraries, it is possible to set the mode to reference the GPIO number, and then they all reference the same number. Let's take a simple example. 

An example using a LED connected

A LED cathode(-) is connected to a 270 Ohm resistor, which is then connected to ground on physical pin P1-06. At least, this ground pin is not referenced in any of the programs. The LED anode(+) is connected to physical pin P1-12, which is the GPIO18. As we will see, there are several ways to refer to this pin.

Using Python to control GPIO for output

There are a couple of Python modules to control the GPIO pins. The  RPi.GPIO Python module by default uses the physical pin number, but shown can refer to the GPIO pin. Likewise, the WiringPython Module use a different scheme to refer to pin numbers, but can be configured to use GPIO pin numbers. This module has more capabilities, and is based upon the wiringPi library.

Starting up Python for GPIO

First of all, make sure that both the RPi.GPIO Python module and the WiringPython Module modules installed. Second, due to root access being necessary to be able to read or write to the GPIO files, use sudo  to start Python

pi@raspberrypi:~/PlayingWithPython$ sudo python
Python 2.7.3 (default, Jun 18 2012, 16:19:55) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

RPi.GPIO Python module
>>> import RPi.GPIO as GPIO
# By Default References Physical 12 number
... 
>>> GPIO.setup(12, GPIO.OUT)
>>> GPIO.output(12, True)
>>> GPIO.output(12, False)
# If setmode(GPIO.BCM), then reference GPIO number
... 
>>> GPIO.setmode(GPIO.BCM)
>>> GPIO.setup(18, GPIO.OUT)
>>> GPIO.output(18, True)
>>> GPIO.output(18, False)

>>> import wiringpi
>>> # initialize the module
... 
>>> wiringpi.wiringPiSetup()
0
>>> # reference wiringPi pin by default
... 
>>> INPUT=0
>>> OUTPUT=1
>>> PWM=2
>>> wiringpi.pinMode(1, OUTPUT)
>>> wiringpi.digitalWrite(1, True)
>>> wiringpi.digitalWrite(1, False)
>>> # Change to reference GPIO numbers
... 
>>> wiringpi.wiringPiGpioMode(True)
>>> wiringpi.pinMode(18, OUTPUT)
>>> wiringpi.digitalWrite(18, True)
>>> wiringpi.digitalWrite(18, False)
>>> # wiringpi also support PWM mode only on GPIO18 or wiringPi pin 1
...
>>> wiringpi.pinMode(18, PWM)
>>> # pwmWrite(pin, 0) is off
...
>>> wiringpi.pwmWrite(18, 0)
>>> wiringpi.pwmWrite(18, 256)
>>> wiringpi.pwmWrite(18, 512)
>>> # pwmWrite(pin, 1023) is full power
...
>>> wiringpi.pwmWrite(18, 1023)
>>> wiringpi.pwmWrite(18, 0)

An example using a Switch and LED connected

A simple two wire switch is used in this example. One wire is then connected to ground on physical pin P1-06. Update: Also use a 270 Ohm resistor between ground and the first wire, as to provide extra protection. The other wire is connection to signal GPIO7 on physical pin P1-26. The LED is connected as in the previous example.

pi@raspberrypi:~/PlayingWithPython$ sudo python
Python 2.7.3 (default, Jun 18 2012, 16:19:55) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 


>>> import RPi.GPIO as GPIO

>>> # display variables and functions in GPIO namespace
... 
>>> dir(GPIO)
['BCM', 'BOARD', 'IN', 'InvalidChannelException', 'InvalidDirectionException', 'InvalidModeException', 'OUT', 'WrongDirectionException', '_BCM', '_ExportedIds', '_GPIO_PINS', '_GetValidId', '_MODE', '_MODES', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '_unexport', 'atexit', 'input', 'os', 'output', 'setmode', 'setup']
>>> # set the mode to use GPIO numbers
... 
>>> GPIO.setmode(GPIO.BCM)
>>> # set up the GPIO to read input
... 
>>> GPIO.setup(7, GPIO.IN)
>>> # read switch initial position
... 
>>> GPIO.input(7)
False
>>> # read switch after changing positions
... 
>>> GPIO.input(7)
True
>>> GPIO.input(7)
False
>>> # use the switch to toggle the LED
... 
>>> # setup GPIO18 for output
... 
>>> GPIO.setup(18, GPIO.OUT)
>>> # loop forever checking if switch is on or off
... 
>>> while True:
...     if GPIO.input(7):
...             GPIO.output(18, True)
...     else:
...             GPIO.output(18, False)
... 
# Press CTRL-c to exit the loop

>>> import wiringpi
>>> dir(wiringpi)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic', '_wiringpi', 'digitalRead', 'digitalWrite', 'pinMode', 'pullUpDnControl', 'pwmWrite', 'serialClose', 'serialDataAvail', 'serialGetchar', 'serialOpen', 'serialPutchar', 'serialPuts', 'shiftIn', 'shiftOut', 'wiringPiGpioMode', 'wiringPiSetup']
>>> INPUT=0
>>> OUTPUT=1
>>> wiringpi.wiringPiSetup()
0
>>> wiringpi.wiringPiGpioMode(True)
>>> wiringpi.pinMode(18, OUTPUT)
>>> wiringpi.pinMode(7, INPUT)
>>> while 1:
...     if wiringpi.digitalRead(7):
...             wiringpi.digitalWrite(18, True)
...     else:
...             wiringpi.digitalWrite(18, False)
... 
# Press CTRL-c to exit the loop

In and Out

This post only discusses how to use the GPIO pins for reading input or sending output. Hopefully, the references provided made it clear how to refer to a specific pin using both the RPi.GPIO and wiringpi Python modules. While there are many other possible functions for these GPIO pins, at least how to connect a LED for observing output, or a switch for observing input have been covered.

Update: There is now available at https://github.com/wrightrocket/PythonOnTheRaspberryPi a file called blinkgpio18.py, which also demonstrates the LED connected in these examples.

No comments:

About Me - WrightRocket

My photo

I've worked with computers for over 30 years, programming, administering, using and building them from scratch.

I'm an instructor for technical computer courses, an editor and developer of training manuals, and an Android developer.