Loading...

Tutorial: Raspberry Pi GPIO Pins and Python

GPIO pins on the Raspberry Pi is a great way to interface physical devices such as buttons and LEDs with a small Linux processors. If you are a Python developer, there is a sweet called RPi.GPIO library that handles interact with pins. In just three lines of code, you can get the LED blinks at one GPIO pin.

INSTALLATION

The newest version of Raspbian has the RPi.GPIO library pre-installed. You’ll probably need to update your library, so using the command line, run:

sudo python

import RPi.GPIO as GPIO

GPIO.VERSION

The current version of RPi.GPIO is 0.5.4 If you need to update to a newer version, run:

sudo apt-get update

sudo apt-get upgrade

If you don’t have the RPi.GPIO library because you’re using an older version of Raspbian, there are great instructions on the Raspberry Pi Spy website on installing the package from scratch.

USING THE RPI.GPIO LIBRARY

Now that you’ve got the package installed and updated, let’s take a look at some of the functions that come with it. Open the Leafpad text editor and save your sketch as “myInputSketch.py”. From this point forward, we’ll execute this script using the command line:

sudo python myInputSketch.py

All of the following code can be added to this same file. Remember to save before you run the above command. To exit the sketch and make changes, press Ctrl+C.


To add the GPIO library to a Python sketch, you must first import it:

import RPi.GPIO as GPIO

Then we need to declare the type of numbering system we’re going to use for our pins:

#set up GPIO using BCM numbering

GPIO.setmode(GPIO.BCM)

#setup GPIO using Board numbering

GPIO.setmode(GPIO.BOARD)

The main difference between these modes is that the BOARD option uses the pins exactly as they are laid out on the Pi. No matter what revision you’re using, these will always be the same. The BCM option uses the Broadcom SoC numbering, which differs between version 1 and version 2 of the Pi.

Tutorial: Raspberry Pi GPIO Pins and Python

In the image above, you'll see that Pin 5 is GPIO01 / 03. This means that a v.1 Pi is GPIO 01, while a v.2 Pi is GPIO 03. The BCM numbering is what I'll be using for the rest of this entry, Because It's universal across other programming languages.

BUILDING A CIRCUIT

Now we're going to get into inputs and outputs. In the circuit shown below, two momentary switches are wired to the GPIO pins 23 and 24 (pins 16 and 18 on the board). The switch on pin 23 is tied to 3.3V, while the switch on pin 24 is tied to ground. The reason for this is that the Raspberry Pi has an internal pull-up and pull-down resistors that can be specified when the pin declarations are made.

Tutorial: Raspberry Pi GPIO Pins and Python

To set up these pins, write:

GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)

This will allow the pull-down resistor on pin 23 and pull-up resistors on the pin 24. Now, let's check to see if we can read it. Pi is looking for a high voltage at Pin 23 and a low voltage on Pin 24. We must also put into this from the circle, so constantly checking voltage pin. The code so far looks like this:

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_UP)

while True:

if(GPIO.input(23) ==1):

print(“Button 1 pressed”)

if(GPIO.input(24) == 0):

print(“Button 2 pressed”)

GPIO.cleanup()

The indents in Python are important when using loops, so be sure to include them. You also must run your script as “sudo” to access the GPIO pins. The GPIO.cleanup() command at the end is necessary to reset the status of any GPIO pins when you exit the program. If you don’t use this, then the GPIO pins will remain at whatever state they were last set to.


THE PROBLEM WITH POLLING

This code works, but prints a line for each frame that the button is pressed. This is extremely inconvenient if you want to use that button to trigger an action or command only one time. Luckily, the GPIO library has built in a rising-edge and falling-edge function. A rising-edge is defined by the time the pin changes from low to high, but it only detects the change. Similarly, the falling-edge is the moment the pin changes from high to low. Using this definition, let’s change our code slightly:

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_UP)

while True:

GPIO.wait_for_edge(23, GPIO.RISING)

print(“Button 1 Pressed”)

GPIO.wait_for_edge(23, GPIO.FALLING)

print(“Button 1 Released”)

GPIO.wait_for_edge(24, GPIO.FALLING)

print(“Button 2 Pressed”)

GPIO.wait_for_edge(24, GPIO.RISING)

print(“Button 2 Released”)

GPIO.cleanup()

When you run this code, notice how the statement only runs after the edge detection occurs. This is because Python is waiting for this specific edge to occur before proceeding with the rest of the code. What happens if you try to press button 2 before you let go of button 1? What happens if you try to press button 1 twice without pressing button 2? Because the code is written sequentially, the edges must occur in exactly the order written.

Edge Detection is great if you need to wait for an input before continuing with the rest of the code. However, if you need to trigger a function using an input device, then events and callback functions are the best way to do that.

EVENTS AND CALLBACK FUNCTIONS
Let’s say you’ve got the Raspberry Pi camera module, and you’d like it to snap a photo when you press a button. However, you don’t want your code to poll that button constantly, and you certainly don’t want to wait for an edge because you may have other code running simultaneously.

The best way to execute this code is using a callback function. This is a function that is attached to a specific GPIO pin and run whenever that edge is detected. Let’s try one:

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_UP)

def printFunction(channel):

print(“Button 1 pressed!”)

print(“Note how the bouncetime affects the button press”)

GPIO.add_event_detect(23, GPIO.RISING, callback=printFunction, bouncetime=300)

while True:

GPIO.wait_for_edge(24, GPIO.FALLING)

print(“Button 2 Pressed”)

GPIO.wait_for_edge(24, GPIO.RISING)

print(“Button 2 Released”)

GPIO.cleanup()

You'll see here that the first button will trigger printFunction consistently, even when the main loop waiting for excellence in the 2. This is because a callback function in a separate thread. The yarns are important in programming because they let things happen simultaneously without affecting other functions. 1 Pressing the button will not affect what happens in our main loop.

The event is also great, because you can remove it from the pin as easily as you can add them:

GPIO.remove_event_detect(23)

Now you’re free to add a different function to the same pin!

ADDING FUNCTIONALITY
As convenient as callback functions are for the GPIO pins, it still doesn’t change the fact that the Raspberry Pi is just not ideal for analog inputs or PWM outputs. However, because the Pi has Tx and Rx pins (pins 8 and 10, GPIO 14 and 15), it can easily communicate with an Arduino. If I have a project that requires an analog sensor input, or smooth PWM output, simply writing commands to the serial port to the Arduino can make things seamless.

0 Response to "Tutorial: Raspberry Pi GPIO Pins and Python"

Post a Comment