How to Use GPIO ZERO on Your Raspberry Pi

By Sean McManus, Mike Cook

There’s a new kid on the block when it comes to accessing the GPIO pins in Python on your Raspberry Pi: the GPIO Zero library. Don’t confuse this with the Pi Zero — the two are not related. The GPIO Zero library takes the class method approach to control, as opposed to the function method approach of RPi.GPIO and other, similar libraries. Pins become Python objects, which must be set up before use. Despite this complication, using this system is easy. For example, for an LED blink example, you can use this code

#!/usr/bin/python3

import time, os

import gpiozero as io # using LED zero

 

led = io.LED(4) # make pin 4 into an output

 

print("LED blinker using gpiozero - By Mike Cook")

print("Ctrl C to quit")

while True:

led.on()

time.sleep(0.30)

led.off()

time.sleep(0.30)

The library uses only the BCM method of pin numbering, so there’s no need to tell the library what system to use. An output pin is known as an LED, irrespective of whether that pin controls an LED, a motor, or a chip. So, the line that makes the pin an output is io.LED(4). This code segment returns a reference to the class object. Classes and objects are a way to get the same piece of code to handle different specific objects — in this particular case, different GPIO pins.

In order to know what it has to do, each thing/pin must be declared separately, and when it is, the program gets a code number to use to identify which specific thing it has to handle. That code number is placed into a variable called led in code above, but could be called anything. (This variable is known as the instance reference.) The class has methods associated with it — things it can do, in other words — and these are called up by writing the instance reference variable name, followed by a period or dot, followed by the method name.

So, turning an LED on or off is a simple process — you just write led.on() or led.off(). However, in a way, this is a bit limiting. For example, you cannot send a number in a variable that’s used to turn the LED on or off — it has to be specifically spelt out as a method name. This is a limitation of how GPIO Zero is written, not a limitation of using classes. There are ways round this, but at this point, the simple system gets rather complex.

In fact, the code above is written in a way that it looks a lot like the earlier listings. The same thing could simply be written as shown.

import gpiozeroled = LED(4)

led.blink()

And that’s all you need. That last statement can have some parameters in it to control the blink rate — so, for example, to exactly match our other examples that last line could be:

led.blink(on_time = 0.3, off_time = 0.3)

This library has even more tricks up its sleeve. If you want to fade that LED up and down instead of just blinking, that last line could say

led.blink(on_time = 2.0, off_time = 2.0, fade_in_time = 1.0, fade_out_time = 1.0 )

This is great if you only want to do that, and for a very young beginner, that’s exactly what you want to do.

The blinking speed controlled by a push button can be written like this.

#!/usr/bin/python3

import time, os

import gpiozero as io # using GPIO Zero

 

led = io.LED(4) # make pin 4 into an output

push = io.Button(24) # make pin 24 into an input

 

print("LED blinker switch using gpiozero - By Mike Cook")

print("Ctrl C to quit")

while True:

led.on()

if push.is_pressed:

time.sleep(0.30)

else :

time.sleep(1.00)

led.off()

if push.is_pressed:

time.sleep(0.30)

else :

time.sleep(1.00)

The input works in a similar way to the output. In this case, you make an instance of the Button class and put its reference in the variable push. Then you use the is_pressed method of this class to determine the time delay in the blinking. By default, the input pull-up resistor is enabled when you create the class reference.

There are other options contained in this input class. It can specify whether a press is to be auto-repeated or specify a debounce time — the time after a change to ignore further changes. As well as the is.pressed method, other class methods include is_held, wait_for_press, wait_for_release, is_held, when_held, when_pressed, and when_released.

Rather than return any information about the input, these last two cause a function to run when the button is pressed or released. This other function runs in a separate thread — in effect, another separate program — with this thread and the main code being swapped in and out alternately until the function is complete. This gives a beginner access to complex concepts that they need to understand only when something goes wrong. So, our controlled blink-rate program could be written as shown.

#!/usr/bin/python3

import gpiozero as io # using LED zero

from signal import pause

led = io.LED(4) # make pin 4 into an output

push = io.Button(24) # make pin 24 into an input

 

def blinkFast():

led.blink(on_time = 0.3, off_time = 0.3)

 

def blinkSlow():

led.blink(on_time = 1.0, off_time = 1.0)

 

push.when_pressed = blinkFast

push.when_released = blinkSlow

 

pause()

The pause function, in effect, ends the program, and the only thing that happens is when the callback functions, as they are called, are invoked or triggered on the push or release of the button.

A lot of the programming work involved in using GIPO Zero involves leafing through the documentation to see what simple functions the authors have implemented for you. GPIO Zero enables you to get results quickly, and without needing to understand much of what is going on — which is helpful if a function does what you need. However, although some things can be done simply, the skills learned are not exactly transferable. As you develop more complex electronic projects, you might find GPIO Zero to be too limited for your needs.