Guide to…Embracing GPIOZero
The new kid on the GPIO block…
A newest way to interface with hardware on the Raspberry Pi is on the prowl called GPIOZero, a new Python library.
The brainchild of Ben Nuttall from the Raspberry Pi foundation, this is intended to replace the original RPi.GPIO created by Ben Croston way back in 2012!
Since the foundation is supporting this replacement, GPIOZero is destined to become the de-facto-standard for hardware interfacing.
If you want a little more information about the what, why and wherefore take a trip to RasPi.TV for a GPIOZero introduction with Ben Nuttall himself.
Well there are few which most people may consider…the first being…
The clear reason for this is to make the coding process more natural and easier to understand without forcing unfamiliar concepts and ideas onto beginners before they are ready. The library provides an additional abstraction layer on top of the existing RPi.GPIO base.
As Alex (RasPi.TV) shows this translates very well:
# RPi.GPIO #GPIO Zero
, GPIO.OUT) led
The aim of less code to get things started and less nonsensical code “magic” is clear. This makes a far easier to read and understand result. I’ve had to overcome similar issues in my workshops, so I can see the point here.
BCM Pin Numbering? Only BCM number and nothing but…
Humm, yes BCM pin numbering… BCM numbering is where the GPIO pins are numbered according to their GPIO reference on the actual SoC (System-on-Chip) package.
The BCM numbering bears no relation to their actual position on the Raspberry Pi GPIO header!
As an engineer, the BCM numbering makes real sense to me, as this is the reference you have to use when referring to the GPIO within any low level language.
HOWEVER… this (in my personal opinion) is at odds with making things as simple and easy to understand as possible.
This is further complicated because older versions of the Raspberry Pi actually have different wiring between the GPIO header and the SoC so there are different BCM numbers for on the same physical pins.
Numbering pins based on their physical position seemed like a far easier concept to teach those unfamiliar with the inner workings of computers and microchips.
This was asked in the RasPi.TV interview, so you can make your own mind up, I can see advantages of both approaches.
The RPi.GPIO module supports both modes, so the user was free to use whichever made most sense to them.
It would take very little so allow the GPIOZero library to support BCM number as default (with no explicit configuration) and allow for this to be overridden if desired.
I’ve also asked the same, via Twitter and via Email but unfortunately it became a sore topic and not something that was open to discussions. I did try and I hoped that in private discussions some headway could have been made, but I wasn’t given a response (I’ll assume purely because it is always busy busy at the foundation…they just don’t stop!).
The most compelling reason for this, that I can see, is to force a standard so that things become consistent (well if you do not have different versions of the Raspberry Pi). I may not agree on the standard or see the logic, but I’ll survive.
As RasPi.TV (again…purely by chance here, but Alex does seem to have this one sussed) has worked out, there is one saving grace…the BCM GPIO pins on the newest Raspberry Pi models now number GPIO02 to GPIO27. Which is put to excellent use by his RasPiO Pro Hat:
How has using buttons and inputs changed?
The GPIOZero getting started guide covers some of the details.
from gpiozero import Button
button = Button(2)
button.wait_for_press() print('You pushed me')
This is just one method supported for button detection, another is shown below:
from gpiozero import LED, Button
led = LED(17) button = Button(2) button.when_pressed = led.on button.when_released = led.off
3rd Party Hat/Hardware Support?
The library already has built in support for a number of 3rd party hardware add-ons. I am hopeful that this will be open for anyone to submit code for, so that everyone is able to provide GPIOZero style support for a particular Pi peripheral.
Should we use it?
That is up to you, but I would say a 100% yes.
ANYTHING which makes coding easier to do is a positive in my view.
The easier you make it the easier it is for the programmer to put their ideas into action (which is the primary reason for coding!).
At the end of the day, GPIOZero is likely to be the standard library for GPIO control and hopefully will grow to include features which the original RPi.GPIO did not.
Check out the GPIOZero site for full documentation on how to use it.
The seamless GPIO.BOARD solution for GPIOZero
Since it makes sense to give people a choice to use the GPIO in the way they find works for them, I’ve created a little solution so you can choose to use GPIO.BOARD (Physical Pin) numbering. If you don’t set a mode, it’ll just use GPIO.BCM by default (so there is no impact either way).
The files needed are available from here:
To set this up you will need to do the following:
- Locate the devices.py files for PiZero on your Raspberry Pi, these are located in the following places:
- Replace the line which has “GPIO.setmode(GPIO.BCM)” with the following (see devices.py as an example):
#######Added CODE replacing "GPIO.setmode(GPIO.BCM)"######## def setmode(): try: from os import environ if "GPIOZERO_BOARD" in environ: print(environ["GPIOZERO_BOARD"]) GPIO.setmode(GPIO.BOARD) else: #Using BCM pin numbers GPIO.setmode(GPIO.BCM) except NameError: #Using BCM pin numbers GPIO.setmode(GPIO.BCM) setmode() #Set GPIO mode BCM/BOARD ############################################################
- Ensure you have this version of gpiopins.py in the same directory as your script (or it is added to the Python library path).
- Use the following code when requiring GPIO.BOARD with GPIOZero!
#!/usr/bin/python3 # testzero.py # # Example using GPIOZero with GPIO.BOARD numbering # PiStop in Location C (BOARD pins 8,10,12) # # Note: 1. gpiopins.py must be located in python path or same directory. # 2. /usr/lib/python3/dist-packages/gpiozero/devices.py should be updated as shown in devices.py file. import gpiopins as GPIO GPIO.setmode(GPIO.BOARD) from gpiozero import LED from time import sleep green=LED(8) yellow=LED(10) red=LED(12) green.blink() sleep(0.1) yellow.blink() sleep(0.1) red.blink()
I shall ask if this could be added to GPIOZero (as it has ZERO impact on other users – BCM stays as the default). But I may script it as a recipe so I have it available in my Pi-Kitchen anyway.