Chapter 7. Programming Inputs and Outputs with Python

At the end of Chapter 6, you did a little bit of programming with the Raspberry Pi’s GPIO pins using a shell script. In this chapter, you’re going to learn how to use Python to do the same thing…and a little more. As with the shell script, Python will let you access the GPIO pins with code that reads and controls the pins automatically.

The advantage that Python has over shell scripting is that Python code is easier to write and is more readable. There’s also a whole slew of Python modules that make it easy for you to do some complex stuff with basic code. See Table 4-2 for a list of a few modules that might be useful in your projects. Best of all, there’s a Python module called RPi.GPIO that makes it easy to read and control the GPIO pins. You’re going to learn how to use that module in this chapter.

Testing GPIO in Python

  1. Go into the Python interactive interpreter from the terminal prompt. (In older versions of Raspbian, RPi.GPIO requires root access to read and control the pins. If you’re using an older version of Raspbian and get a warning about permissions, you’ll need to launch Python as root with the command sudo python when using RPi.GPIO.)

    Here’s how to do it:

    $ python
    Python 2.7.3rc2 (default, May  6 2012, 20:02:25)
    [GCC 4.6.3] on linux2
    Type "help", "copyright", "credits" or "license" for more 
      information.
    >>>
    
  2. When you’re at the >>> prompt, try importing the module:

    >>> import RPi.GPIO as GPIO
    
Note

In this chapter, we’ll be using Python 2.7 instead of Python 3 because one of the modules we’ll be using is only installed for Python 2.x on the Raspberry Pi. When you type python at the command prompt on the Raspberry Pi, it runs Python 2.7 by default. This behavior could change in the future (you can run Python 2.7 explicitly by typing python2.7 instead of python).

One important difference between the two versions is how you print text to the console. You’ll use print "Hello, world!" in Python 2.x, but you’d use print("Hello, world!") in Python 3.

If you don’t get any errors after entering the import command, you know you’re ready to try it out for the first time:

  1. Before you can use the pins, you must tell the GPIO module how your code will refer to them. In Chapter 6, the pin numbers we used didn’t correlate to the way that they’re arranged on the board. You were actually using the on-board Broadcom chip’s signal name for each pin. With this Python module, you can choose to refer to the pins either way. To use the numbering from the physical layout, use GPIO.setmode(GPIO.BOARD). But let’s stick with the pin numbering that you used in Chapter 6 (GPIO.setmode(GPIO.BCM), where BCM is short for Broadcom), which is what Adafruit’s Pi Cobbler and similar breakout boards use for labels:

    >>> GPIO.setmode(GPIO.BCM)
    
  2. Set the direction of pin 25 to output:

    >>> GPIO.setup(25, GPIO.OUT)
    
  3. Connect an LED to pin 25 as you did in “Beginner’s Guide to Breadboarding”.

  4. Turn on the LED:

    >>> GPIO.output(25, GPIO.HIGH)
    
  5. Turn off the LED:

    >>> GPIO.output(25, GPIO.LOW)
    
  6. Unexport the pins that were used in this session:

    >>> GPIO.cleanup()
    
  7. Exit the Python interactive interpreter:

    >>> exit()
    $
    
Note
In Chapter 6, you learned that digital input and output signals on the Raspberry Pi must be either 3.3 volts or ground. In digital electronics, we refer to these signals as high or low, respectively. Keep in mind that not all hardware out there uses 3.3 volts to indicate high; some use 1.8 volts or 5 volts. If you plan on connecting your Raspberry Pi to digital hardware through its GPIO pins, it’s important that they also use 3.3 volts.

Those steps gave you a rough idea of how to control the GPIO pins by typing Python statements directly into the interactive interpreter. Just as you created a shell script to turn the pins on and off in Chapter 6, you’re going to create a Python script to read and control the pins automatically.

Blinking an LED

To blink an LED on and off with Python, you’re going to use the statements that you already tried in the interactive interpreter in addition to a few others. For the next few steps, we’ll assume you’re using the desktop environment (as shown in Figure 7-1), but feel free to use the command line to write and execute these Python scripts if you prefer.

Here’s how to blink an LED with a Python script:

  1. Open the Leafpad text editor by clicking the Raspberry Menu→ Accessories→Text Editor.

  2. Enter the following code:

    import RPi.GPIO as GPIO 1
    import time 2
    
    GPIO.setmode(GPIO.BCM) 3
    GPIO.setup(25, GPIO.OUT) 4
    
    while True: 5
       GPIO.output(25, GPIO.HIGH) 6
       time.sleep(1) 7
       GPIO.output(25, GPIO.LOW) 8
       time.sleep(1) 9
    1

    Import the code needed for GPIO control.

    2

    Import the code needed for for the sleep function.

    3

    Use the chip’s signal numbers.

    4

    Set pin 25 as an output.

    5

    Create an infinite loop consisting of the indented code below it.

    6

    Turn the LED on.

    7

    Wait for one second.

    8

    Turn the LED off.

    9

    Wait for one second.

  3. Save the file as blink.py within the home directory, /home/pi. There’s a shortcut to this folder in the places list on the left side of the Save As window.

Note
Remember—indentation matters in Python!
  1. Open LXTerminal, then use these commands to make sure the working directory is your home directory, and execute the script (see Figure 7-1):

    pi@raspberrypi ~/Documents $ cd ~
    pi@raspberrypi ~ $ python blink.py
    
  2. Your LED should now be blinking!

  3. Press Ctrl-C to stop the script and return to the command line.

gsrp 0901
Figure 7-1. Using Leafpad and LXTerminal to edit and launch Python scripts.

Try modifying the script to make the LED blink faster by using decimals in the time.sleep() functions. You can also try adding a few more LEDs and getting them to blink in a pattern. You can use any of the dedicated GPIO pins that are shown in Figure 6-2.

Reading a Button

If you want something to happen when you press a button, one way to do that is to use a technique called polling. Polling means continually checking over and over again for some condition. In this case, your program will be polling whether the button is connecting the input pin to 3.3 volts or to ground. To learn about polling, you’ll create a new Python script that will display text on screen when the user pushes a button:

  1. Connect a button the same way as in “Digital Input: Reading a Button”, using pin 24 as the input. Don’t forget the pull-down resistor, which goes between ground and the input pin.

  2. Create a file in your home directory called button.py and open it in the editor.

  3. Enter the following code:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(24, GPIO.IN) 1

count = 0 2

while True:
   inputValue = GPIO.input(24) 3
   if (inputValue == True): 4
      count = count + 1 5
      print("Button pressed " + str(count) + " times.") 6
   time.sleep(.01) 7
1

Set pin 24 as an input.

2

Create a variable called count and store 0 in it.

3

Save the value of pin 24 into inputValue.

4

Check if that value is True (when the button is pressed).

5

If it is, increment the counter.

6

Print the text to the terminal.

7

Wait briefly, but let other programs have a chance to run by not hogging the processor’s time.

  1. Go back to LXTerminal and execute the script:

    $ python button.py
    
  2. Now press the button. If you’ve got everything right, you’ll see a few lines of “The button has been pressed” for each time you press the button.

The preceding code checks for the status of the button 100 times per second, which is why you’ll see more than one sentence printed (unless you have incredibly fast fingers). The Python statement time.sleep(.01) is what controls how often the button is checked.

But why not continually check the button? If you were to remove the time.sleep(.01) statement from the program, the loop would indeed run incredibly fast, so you’d know much more quickly when the button was pressed. This comes with a few drawbacks: you’d be using the processor on the board constantly, which will make it difficult for other programs to function, and it would increase the Raspberry Pi’s power consumption. Because button.py has to share resources with other programs, you have to be careful that it doesn’t hog them all up.

Now add a few lines to the code to make it a little bit better at registering a single button press:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(24, GPIO.IN)

count = 0

while True:
   inputValue = GPIO.input(24)
   if (inputValue == True):
      count = count + 1
      print("Button pressed " + str(count) + " times.")
      time.sleep(.3) 1
   time.sleep(.01)
1

Helps a button press register only once.

This additional line of code will help to ensure that each button press is registered only once. But it’s not a perfect solution. Try holding down the button. Another count will be registered and displayed three times a second, even though you’re holding the button down. Try pushing the button repeatedly very quickly. It doesn’t register every button press because it won’t recognize distinct button presses more frequently than three times a second.

These are challenges that you’ll face when you’re using polling to check the status of a digital input. One way to get around these challenges is to use an interrupt, which is a way of setting a specified block of code to run when the hardware senses a change in the state of the pin. RPi.GPIO supports interrupts and you can read about how to use this feature in the library’s documentation.

Project: Simple Soundboard

Now that you know how to read the inputs on the Raspberry Pi, you can use the Python module Pygame’s sound functions to make a soundboard. A soundboard lets you play small sound recordings when you push its buttons. To make your own soundboard, you’ll need the following in addition to your Raspberry Pi:

  • Three pushbutton switches

  • Female-to-male jumper wires

  • Standard jumper wires or hookup wire, cut to size

  • Solderless breadboard

  • Three resistors, 10K ohm

  • Computer speakers, or an HDMI monitor that has built-in speakers

You’ll also need a few uncompressed sound files, in .wav format. For purposes of testing, there are a few sound files preloaded on the Raspberry Pi that you can use. Once you get the soundboard working, it’s easy to replace those files with any sounds you want, though you may have to convert them to .wav from other formats. Start off by building the circuit:

  1. Using a female-to-male jumper wire, connect the Raspberry Pi’s ground pin to the negative rail on the breadboard.

  2. Using a female-to-male jumper wire, connect the Raspberry Pi’s 3.3V pin to the positive rail on the breadboard.

  3. Insert the three pushbutton switches in the breadboard, all straddling the center trench.

  4. Using standard jumper wires or small pieces of hookup wire, connect the positive rail of the breadboard to the top pin of each button.

  5. Now add the pull-down resistors. Connect the bottom pin of each button to ground with a 10K resistor.

  6. Using female-to-male jumper wires, connect each button’s bottom pin (the one with the 10K resistor) to the Raspberry Pi’s GPIO pins. For this project, we used pins 23, 24, and 25.

Figure 7-2 shows the completed circuit. We created this diagram with Fritzing, an open source tool for creating hardware designs.

gsrp 0902
Figure 7-2. Completed circuit for the soundboard project

Now that you have the circuit breadboarded, it’s time to work on the code:

  1. Create a new directory in your home directory called soundboard.

  2. Open that folder and create a file there called soundboard.py.

  3. Open soundboard.py and type in the following code:

import pygame.mixer
from time import sleep
import RPi.GPIO as GPIO
from sys import exit

GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN)
GPIO.setup(24, GPIO.IN)
GPIO.setup(25, GPIO.IN)

pygame.mixer.init(48000, -16, 1, 1024) 1

soundA = pygame.mixer.Sound(
    "/usr/share/sounds/alsa/Front_Center.wav") 2
soundB = pygame.mixer.Sound(
    "/usr/share/sounds/alsa/Front_Left.wav")
soundC = pygame.mixer.Sound(
    "/usr/share/sounds/alsa/Front_Right.wav")

soundChannelA = pygame.mixer.Channel(1) 3
soundChannelB = pygame.mixer.Channel(2)
soundChannelC = pygame.mixer.Channel(3)

print "Soundboard Ready." 4

while True:
   try:
      if (GPIO.input(23) == True): 5
         soundChannelA.play(soundA) 6
      if (GPIO.input(24) == True):
         soundChannelB.play(soundB)
      if (GPIO.input(25) == True):
         soundChannelC.play(soundC)
      sleep(.01) 7
   except KeyboardInterrupt: 8
      exit()
1

Initialize Pygame’s mixer.

2

Load the sounds.

3

Set up three channels (one for each sound) so that we can play different sounds concurrently.

4

Let the user know the soundboard is ready (using Python 2 syntax).

5

If the pin is high, execute the following line.

6

Play the sound.

7

Don’t “peg” the processor by checking the buttons faster than we need to.

8

This will let us exit the script cleanly when the user hits Ctrl-C, without showing the traceback message.

  1. Go to the command line and navigate to the folder where you’ve saved soundboard.py and execute the script with Python 2:

    pi@raspberrypi ~/soundboard $ python soundboard.py
    
  2. After you see “Soundboard Ready,” start pushing the buttons to play the sound samples.

Note
While Pygame is available for Python 3, on the Raspberry Pi’s default installation, it’s only installed for Python 2.

Depending on how your Raspberry Pi is set up, your sound might be sent via HDMI to your display, or it may be sent to the 3.5mm analog audio output jack on the board. To change that, exit out of the script by pressing Ctrl-C and executing the following command to use the analog audio output:

pi@raspberrypi ~/soundboard $ sudo amixer cset numid=3 1

To send the audio through HDMI to the monitor, use:

pi@raspberrypi ~/soundboard $ sudo amixer cset numid=3 2

Of course, the stock sounds aren’t very interesting, but you can replace them with any of your own sounds: applause, laughter, buzzers, and dings. Add them to the soundboard directory and update the code to point to those files. If you want to use more sounds on your soundboard, add additional buttons and update the code as necessary.

Going Further

RPi.GPIO

Because the RPi.GPIO library is still under active development, you may want to check the homepage for the project to find the latest updates.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset