Lab 2: Interfacing with the Pi

The questions below are due on Sunday July 15, 2018; 11:59:00 PM.


You are not logged in.

If you are a current student, please Log In for full access to this page.

Goals:

Goals: In today's lab we're going to start programming on the Pi, using Python to control inputs and outputs and interface with some electrical components we worked with last time. Ultimately this will culminate in Lab 03 where you build a music player with a limited set of functionality.

1) Big Picture

What we'll be doing today (and really in all of your work and projects going forward) is adding the "logic" aspect to our system. We got some experience messing with wiring/building circuits in Lab 01 and that will be invaluable, but the next step is to interface a computational device with that equipment and that requires programming.

For many years, we (humans) built stuff without programming. Everything can be done using electronics without programming, but the flexibility obtained through integrating programming and a computational device really has its benefits!

Flow of Information. Inputs feed data into our system. We process that information and then act upon it using Outputs.

Open up Python3 on your Raspberry Pi (Idle 3) by going to the Raspberry Symbol >Programming > Python3 (IDLE). This will open up Python. Immediately (before you forget) open up a new file (do not work directly in the Python console). Do this by going to File >New.

Please get in the habit of working in files in Python, and not within the Python shell. We'll use the Python shell for analyzing our code, but for writing the code, it isn't very good and doesn't really let us save stuff. Files are much better!

The Raspberry Pi has a number of external interfaces that we can use to generate inputs and outputs. Inputs on a computer can be specific things keyboards, but they can also be more "bare-bones." Among these inputs, the Raspberry Pi has a number of General Purpose Input Output (GPIO) Pins that we can use to obtain simple inputs and outputs. By "simple" we mean digital, which means they can either measure or produce On/Off voltages, depending on if they are an input or a output, respectively. (A pin cannot do both however!)
Many of the circuit components we've worked with so far can respond in an ON/OFF sort of way (think buttons, or LEDs being on or off), so these Genearl Purpose inputs and outputs from the Pi, allow us to interface with these components.

1.0.1) Breakout Board

We learned about the breadboard and used the blue "breakout" board to get power for our audio amplifier in Lab 01. The Raspberry Pi can do a lot more than just this, though, and today we'll start using all those other pins. The Pi is connected to the outside world through a ribbon cable that then connects to a board known as a "Breakout". The Breakout, shown in the image below, gives us nice, clean, readable access to all the Pi's pins.

A reminder of the breakout board. We have direct access to these pins from Python.

when we draw out the breakoutboard in this lab (and even the Pi) and later labs we'll often just represent it as a gray box.

2) The LED as an Output

OK so now let's grab a LED and hook up the LED to the output of GPIO4. You may remember from Lab 01 that we should never hook up an LED to power without some resistor in series like shown below:

A reminder about how to use LEDs (not what we're building here)

It turns out that our Raspberry Pi boards have an built-in resistor (shown in figure below) that let's us not need to add one ourselves when interfacing with the GPIO pins.

This is only because we've included an extra protection shield on the board. A Raspberry Pi off of the streets, will not have this, so if you're using your own hardware you'll need to include your own resistors.

This in-built protection resistor is only for the GPIO pins...not the 3.3V pins (3V3) or other pins) Try to hook the LED up to GPIO 4 in the correct direction and to the right pins such that if GPIO4 had a High voltage on it, the LED would glow. (Long leg to GPIO Pin 4 which is represented by the #4 label and the short leg of the LED to ground!

Connecting an LED to the Pi.

When you think you've added the part correctly, open a new file in Python (File>New) if you haven't already, and then copy-paste the code below into that file. Save it as led1.py and then run it by either going to Run>Run Code or pressing F5 on the keyboard (cool kids press F5, and you want to be cool, right? You should probably press F5).

#Simple LED Flasher
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)

led_pin = 4 #pin we'll use for the LED

GPIO.setup(led_pin,GPIO.OUT)
GPIO.output(led_pin,0)

time_pause = 0.25 #how long a standard pause is in this program

GPIO.output(led_pin,1)
time.sleep(time_pause)
GPIO.output(led_pin,0)
time.sleep(time_pause)
GPIO.output(led_pin,1)
time.sleep(time_pause)
GPIO.output(led_pin,0)
time.sleep(time_pause)
GPIO.cleanup()

When you run the code how many times does the LED flash?

Let's go through line-by-line what this code is doing.

In Python any line or part of a line that begins with a # is a comment, meaning it is meant for human reading.

The two lines below grant us access to other pieces of pre-written Python code. The first one gives us access to some Python "libraries" that let us interact with the actual Raspberry Pi hardware1 and what we're doing here is importing the RPi.GPIO library and just calling it GPIO for short. When we want to use a part from this library we'll access it by doing GPIO.thing. The second line imports the time library which gives us access to the sleep function which we'll use to add pauses in our program.

import RPi.GPIO as GPIO
import time

The next two lines configure the GPIO library so we can use it. That's about all you need to know for now:

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

To make life easy it is better to use variables wherever possible. What we do next is create a variable called led_pin and assign a value of 4 to it. Then we can use that anywhere we want to refer to the LED. In the future if we want to change what pin we use for the LED we only need to change that number in one spot as a result.

Here we do our first pin-specific action for the LED. We set up Pin 4 to be an output (pins can be either inputs or outputs...to control an LED that means we need it to be an output).

led_pin = 4
GPIO.setup(led_pin,GPIO.OUT)

We then have a bunch of lines that look like the following. The first type of line tells the corresponding pin (dictates by the variable led_pin which has a value of 4 in this case) to be ON (1 or True == High OUTPUT which makes the LED go on), (0 or False == Low OUTPUT which makes the LED go off) The second line (time.sleep(time_pause)) has the program pause for 0.25 seconds because it is saying to sleep the computer time_pause amount where time_pause is another variable we specified in our code!

GPIO.output(led_pin,1)
time.sleep(time_pause)
GPIO.output(led_pin,0)
time.sleep(time_pause)
GPIO.output(led_pin,1)
time.sleep(time_pause)
GPIO.output(led_pin,0)
time.sleep(time_pause)

Finally the following line makes sure we shut down our hardware access ok. Just like you don't want to just unplug a running computer, sometimes you don't want to just stop controlling the outputs of the Raspberry Pi. This function call will make sure we end our time in Python gracefully.

GPIO.cleanup()

3) LED Tasks

We're now going to build on this code we started with by doing some exercises. Obtain a red, a white, and a blue LED from the parts supply (or any other colors if you want), and using the previous starter code as a starting point, do the following:

3.1) Assignment 1

Create a system that turns on each LED in sequence, then turns them off, and repeats this pattern three times. Use GPIO (#) pins 4, 17, and 27 ONLY!

Building a Red, White, and Blue Circuit

When you feel confident that you've built the circuit correctly and have code working properly, save the code since you'll need to include it in your Lab 2 video submission.

3.2) Assignment 2

We'd now like you to make two LEDs turn on together for 0.5 seconds, while the other LED is off, and then flip it (two LEDs off and the other on for 0.5 seconds). Have this repeat ten times. Your code needs to be less than twenty lines total. Think about how to do this. Ask Joe or your classmates for help!

When you feel confident that you've built the circuit correctly and have code working properly, save the code since you'll need to include it in your Lab 2 video submission.

3.3) Assignment 3

Now make one LED (pick one...it is up to you) flash at 10 Hertz using a for loop. Don't know what "Hertz" means? Too bad. Look it up.

When you feel confident that you've built the circuit correctly and have code working properly, save the code since you'll need to include it in your Lab 2 video submission.


4) Inputs

We just saw that we can control electrical signals with our Pi (and make LEDs go on and off). We can also have our Pi be sensitive to externally generated electrical signals. We'll start investigating this ability by looking at switches which we used in Lab 01. As a refresher, a switch is represented schematically as shown below:

A switch

Our switch looks like the following:

The switch we'll be using today

You can plug your switch into the breadboard as shown above. You've already gotten experience with these, but just keep in mind that their direction really matters. You all experienced that in Lab 01.

These types of switches have only two electrical nodes inside them, but four electrical contacts and legs. This means there is some redundancy in them. Pay attention/use that as you wire up circuits below.

The four legs of the switch mapped into two electrical connections.

Include your switch in the circuit/schematic below:

Switch as Input

Create a new file, call it switch_demo.py and paste the code into it below:

import RPi.GPIO as GPIO  #import library to use input/output pins
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
input_pin = 5
GPIO.setup(input_pin,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
while True:
    if GPIO.input(input_pin)==1:
        print("Pushed")
    time.sleep(0.05)

Some of these pieces should start looking familiar, but others are new...let's go over the chunks again:

The first four lines are like from earlier...import libraries and set some basic utility things up. You'll usually always use these four lines in a lot of what we do:

import RPi.GPIO as GPIO  #import library to use input/output pins
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

The next two lines set up a GPIO pin as an input. We create a variable input_pin and set it to 5 and then use that second line to establish that the pin is an input.

input_pin = 5
GPIO.setup(input_pin,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

The last part takes some explaining:

When we generated outputs, our code was what was in charge of what happened. It could run and be done and could be very deterministic/pre-planned. If we instead want our code to react to inputs, we now need restructure how our code is designed and operates. Events are no longer triggered by code, but rather by an outsider, so we need a way to have our code wait.

A while True loop is a way to get a block of code to run forever. Normally a while loop runs as long as the condition it is checking is True. Since True is always True this loop will run forever (until we stop it with a Control-C).

To make sure the loop doesn't run 1000's of times per second we put a time.sleep command to pause the code for 0.05 seconds each time through, keeping our loop running no faster than 20 times per second.

We now have this ability to run and wait forever. This is exactly what we need in order to interact with our switch. Each time through the loop we check to see if our switch is pushed. We do that by checking the value of the switch with the command GPIO.input(input_pin). Calling this function will return a value that could be stored in a variable if we wanted, but in this case we check if it is 1 in value and if it is, we print "Pushed".

while True:
    if GPIO.input(input_pin)==1:
        print("Pushed")
    time.sleep(0.05)

We could further clean up our code by packaging that input check we're doing into a function like so:

def input_check(input):
    if input==1:
        print("Pushed")

We can then modify our main loop to look like the following:

while True:
    input_check(GPIO.input(input_pin))
    time.sleep(0.05)

Building on this code, add a second button to your system (you choose the GPIO pin) and develop a script that will do the following:

  • Run continuously
  • Print "Pushed 1" if the first button is pushed
  • Print "Pushed 2" if the second button is pushed
  • Print "Both Pushed" if both buttons are simultaneously pushed
  • Do nothing if neither button is pushed. (no printing).

5) Final Deliverable (Lab 2)

When you're all done, create a short video and upload to Youtube/Google Drive, showing the following behaviors:

  • All Three LED flashing patterns
  • Your system responding to two different switch inputs as described above!
Problem Status:
A Python Error Occurred:

Error on line 2 of Python tag (line 316 of source):
    kerberos = cs_user_info['username']

KeyError: 'username'

Enter the url for the video

Place all of yoru and server code as a zip file here:

 No file selected

Enter any comments you may want me to know about. For example, you can list non-obvious things you got working, things you're proud of, outstanding issues, etc.. Please hit submit on this question even if you don't have any comments.


 
Footnotes

1GPIO stands for "General Purpose Input-Output" (click to return to text)