Thursday, May 25, 2017

Byte: Raspberry Picraft Weekend - Challenge 1



Last weekend I set myself a challenge. With one Raspberry Pi 3B, a breadboard, a GPIO breakout board, four push button switches, four LEDs, four 100 ohm resistors, a PiCamera module and a handful of jumper wires, how many different projects could I make?

The answer, as it turned out, was quite a few. The elegance of this challenge was that it would be fairly easy to evolve the code from one project to another, starting simply, and then getting increasingly more complicated and downright outlandish as the weekend wore on.  The starting place was obvious: I had four LEDs and four push button switches, after all. 

Challenge 1: Push button to light LED

Switches turn lights on. This one thing that we definitely know, as experienced users of high technology, that switches are designed to do. How hard can it be? Well, it’s all in the setup and the details. I chose to use Python to control my circuits, primarily because it would make it easier to integrate the outputs from the circuits into Minecraft later on. You could conceivably complete some of these challenges in Scratch instead, but for simplicity, I’m just going to assume you use Python scripts, using the Python 3 IDLE. 

After you’ve created a new .py script , the first thing we need to do is tell the Pi that we’re going to be using the GPIO interface, and that we’re going to need to be able to control push buttons and LEDs. We do that by importing the appropriate library and functions. Note that it’s good coding practice to give other users of your code hints to what it does (or what it ought to do!) using comments, which can be inserted by prefixing with the # symbol. They can be a great help in determining and solving problems while debugging errors. These lines of code are simply for human consumption, as they’re completely ignored by the computer. While some coders choose not to bother with comments, in my experience, the time spent illustrating the intended function of the code is more than made up for by the time saved during debugging unforeseen errors that could not have been anticipated at the design stage. 

Pro-Tip: Never, EVER forget to add detailed comments to your code. Don’t assume that you’re going to be the person fixing any bugs in it, as you might not find them! 

#import necessary libraries
from gpiozero import LED, Button 

So now that the Pi knows that it’s going to be interacting with the GPIO pins, we really ought to let it know where it should be receiving inputs and outputs...

#define variables
red = LED(17)
amber = LED(18)
green = LED(23)
blue = LED(24)
button1 = Button(5)
button2 = Button(6)
button3 = Button(12)
button4 = Button(13)

The numbers in the brackets should correspond to the GPIO pin you have used to connect to the component to the GPIO breakout board. Otherwise things won’t work, and that would be bad. We will use the same GPIO pin references for all the subsequent challenges, just to make our lives that bit easier while we evolve the code from one project to the next. 

Having set variables to recognise inputs and outputs for our push button switches and our LEDs, we can now add the code to make them interact with each other. We are going to use an infinite loop to detect inputs from the buttons and deal with them accordingly, so we need to alert the Pi to be ready to accept input signals:

while True:

All the code subsequently added to this execution block needs to be indented by one tab to ensure that it only gets called when it is needed. For clarity, I will post all the subsequent code statements from the beginning of the file so that the indent level needed to allow the code to run is obvious. Your code so far should look like this:

#import necessary libraries
from gpiozero import LED, Button
#define variables
red = LED(17)
amber = LED(18)
green = LED(23)
blue = LED(24)
button1 = Button(5)
button2 = Button(6)
button3 = Button(12)
button4 = Button(13)
while True:

Pro-Tip: It’s a good idea to save your progress after you add each line of code to your .py script. After all, you never know when you might have a power cut (or be abducted by aliens!)...

Now that our Pi knows that it is control of LEDs and buttons, now all we need to do is tell them how to interact with each other. To do this, we need to the tell the Pi what it should do while it’s waiting for input in the while True: loop. 

The first thing we need to do is make sure that the LEDs are turned off, so that there’s no chance of receiving false signals from previous times that the code has been run or tested (speaking of which, make sure you kill the Python shell after you’ve finished each test, otherwise your poor Pi might get confused by trying simultaneously process signals in multiple instances of running code – making it seem like your script isn’t working. When in doubt; kill everything and start from scratch... a valuable piece of philosophy in videogames as well as programming!!)

Your code at this point needs to look like this, incidentally:

#import necessary libraries
from gpiozero import LED, Button

#define variables
red = LED(17)
amber = LED(18)
green = LED(23)
blue = LED(24)
button1 = Button(5)
button2 = Button(6)
button3 = Button(12)
button4 = Button(13)
while True:
    #turn off the LEDs
    red.off()
    amber.off()
    green.off()
    blue.off()

Now that the LEDs are set to off by default when the script is run, we can use the Button API to check for any inputs. If there is a signal from one of the four buttons, we need to light the corresponding LED, but we also want to add in a short time delay, so that the script has time to register any changes in input. To do this, we need to import a new Python library, time, and use the sleep method to prevent simultaneous inputs from two or more of the push button switches. 

#import necessary libraries
from gpiozero import LED, Button
from time import sleep

#define variables
red = LED(17)
amber = LED(18)
green = LED(23)
blue = LED(24)
button1 = Button(5)
button2 = Button(6)
button3 = Button(12)
button4 = Button(13)
while True:
    #turn off the LEDs
    red.off()
    amber.off()
    green.off()
    blue.off()
    #poll for input from the buttons
    if button1.is_pressed:
        red.on()
        sleep(0.05)
    elif button2.is_pressed:
        amber.on()
        sleep(0.05)  
    elif button3.is_pressed:
        green.on()
        sleep(0.05)
    elif button4.is_pressed:
        blue.on()
        sleep(0.05)

If your code is working correctly, you should find that pressing each of the buttons makes one of the LEDs blink. You can alter the value in the sleep() lines to change the frequency of the flickering – the number in the brackets corresponds to the number of seconds the line of code executes for; the smaller the number, the faster the LED flickers.

Congratulations! You’ve just used physical interactions with push button switches to make electronic components bow to your will and control! But where will it end? <insert ominous, maniacal laughter here>
Post a Comment