Blog

What’s new in GPIO Zero v1.3?

One year ago today, I started the GPIO Zero project. We now have a core team of three (Dave Jones, Andrew Scheller and me). There have been 587 commits, we’ve released four major versions, and published a book. The library has great coverage of GPIO devices, and contains features I never even dreamed of. In the last year I’ve delivered workshops and given talks about it at conferences and events around the UK, the US and even in Russia. It’s being used in Raspberry Pi’s learning resources, and teacher training and by hobbyists around the world. Read on to find out what’s new in the latest release.

GPIO Zero v1.3 is out now! Install it (or upgrade) with:

sudo apt-get update
sudo apt-get install python3-gpiozero python-gpiozero

What does this release bring?

  • New ButtonBoard class
  • New Servo and AngularServo classes
  • New CPUTemperature class
  • Improved remote GPIO support
  • Plenty of behind-the-scenes changes
  • Lots of new recipes

ButtonBoard

The new ButtonBoard class is a composite device representing multiple buttons. The idea being you can pass the value set from a collection of buttons into another collection of the same size: e.g. matching buttons to LEDs. You can also process the value set to get the information you want, for example the number of buttons pressed; any pressed, all pressed, proportion pressed or more. We’re currently discussion options for documenting these examples and possibly extending the features of this class in Issue #425.

Servo

The long-discussed Servo classes have now arrived! Servo allows you to move a servo between its minimum, maximum and mid-point positions:

from gpiozero import Servo
from time import sleep

servo = Servo(17)
while True:
    servo.min()
    sleep(1)
    servo.mid()
    sleep(1)
    servo.max()
    sleep(1)

AngularServo allows you to move a servo to specific angles:

from gpiozero import Servo
from time import sleep

s = AngularServo(17, min_angle=-45, max_angle=45)

s.angle = 0.0
sleep(1)
s.angle = 15
sleep(1)
s.angle = 45
sleep(1)
s.angle = -45

We’re currently discussing what else should be added to the servo classes for different use cases.

CPUTemperature

We introduced some internal devices which act like regular GPIO Zero classes. CPUTemperature allows you to access the Pi’s CPU temperature, and use it to control other devices:

from gpiozero import LEDBarGraph, CPUTemperature

temp = CPUTemperature(min_temp=50, max_temp=90)
graph = LEDBarGraph(5, 6, 13, 19, 25, pwm=True)
graph.source = temp.values

Now the LEDs will light up according to the temperature: at 50 degrees all the LEDs will be off; at 90 degrees they’ll all be on; at 70 degrees half will be on; and anything in-between. There’s also a TimeOfDay class provided but it’s not working properly at the moment so I’ll cover that in the next release post.

Remote GPIO support

I talked about this last time. It’s really exciting. It was amazing to see this working in v1.2 but support wasn’t really very good, so its use was limited. However, significant work has gone into remote GPIO support since then and it’s going to be really powerful. Thanks to a pigpio, a C library from GitHub user joan2937, we can set up GPIO Zero devices connected to pins on Pis over a network. Easily.

Usually, you’d set up an LED like so:

from gpiozero import LED

led = LED(17)

led.blink()

Where the 17 refers to pin 17 on the Pi you’re executing the code. You can also do this:

from gpiozero import LED
from gpiozero.pins import PiGPIOPin

pin = PiGPIOPin(17, host='192.168.1.4')
led = LED(pin)

led.blink()

Here, rather than simply specifying the number 17, we’ve provided a reference to a pin on another Pi on the network. This means you can remotely control the LED connected to that other Pi.

However, an easier method is to supply the Pi’s IP address in an environment variable. Before running the python shell, IPython, IDLE or whatever you’re using, simply set the PIGPIO_ADDR environment variable:

$ PIGPIO_ADDR=192.168.1.4 python my_script.py

to run a file, or:

$ PIGPIO_ADDR=192.168.1.4 ipython3

to run the IPython shell, for example. Each of these will be set up so that when you type led = LED(17), it uses pin 17 on that remote Pi. Note: you’ll need to enable Remote GPIO, start the pigpio daemon, and install the pigpio python client on your host machine. See full instructions in this gist.

Of course, you can mix these methods and use a default pin factory but also specify pins on other Pis.

To set this up, you need the pigpio Python library installed on the device you’re running the code, and the pigpio daemon running on the remote Pi (and remote GPIO enabled in raspi-config). Read the pins documentation for more info.

Did I mention you can run this on any PC, not just on a Pi? That’s right. You can install GPIO Zero on your laptop and run GPIO Zero code which communicates with a Pi on the network. The Python code is running on your laptop, which communicates with the pigpio daemon using sockets. The daemon does all the GPIO stuff. I’ve seen this working on Linux, Mac and Windows. Admittedly, we need to provide much more solid instructions for getting this working if we want it to be seen as a viable solution for schools, Code Clubs and such. But it’s a start. Please give feedback if you’re using it (if you have any issues or not – we’d love to know). There’s also some interesting stuff around. If you know your way around installing with pip on Windows and Mac, we could use your help! See Issue #434.

What’s next?

We didn’t complete all the things we had on the list for this release, but we decided to push it out anyway, and leave the rest to the next release. As well as lots of minor improvements, we intend to add I2C support, including I2C expander chips (and probably SPI expander chips while we’re at it), which will be really handy. You’ll be able to set up an expander chip, and index it to refer to each pin, and create regular device objects on those pins, something like this:

from gpiozero import IOExtender, LED

ext = IOExtender()
led = LED(ext[0])

led.on()

Then there’s temperature sensors, different types of motors, servos and more. Feature requests welcome on GitHub! We’re also aiming to establish a release schedule for future releases.

Thanks

Again, thanks to Dave Jones and Andrew Scheller for all their hard work in the last release, and to everyone who provided useful feedback on GitHub. Keep it coming!

PyConUK

Dave and I will be giving a talk together on GPIO Zero at PyConUK this week. The video will be available shortly after the conference. We’re also running a sprint on GPIO Zero, welcoming new developers to the library. Come and have a go if you’re available, and we’ll show you where to start.

Simple Electronics with GPIO Zero book

Today the MagPi team released a new publication: Simple Electronics with GPIO Zero.

Essentials-07-GPIO-ZERO_Flat_Cover

This 100-page book takes you from the basics, like lighting an LED, all the way to building projects like an Internet radio using the GPIO Zero Python library.

This book is available as a free PDF, but you can also pay to get it for your iPad or Android device with the MagPi app. Soon it will also be released in print. It’s now available in print. All proceeds go towards the Raspberry Pi Foundation’s education programmes.

GPIOZeroSpread

I’ve been amazed with how the GPIO Zero project has grown. There have been three major releases (a fourth due later this year), and it has been featured in The MagPi many times, and in three Kickstarter projects: the RasPiO Pro HAT; Analog Zero; and GPIO Zero Ruler.

Also check out the GPIO Zero documentation, the Physical Computing with Python resource, and GPIO Zero on GitHub.

What’s new in GPIO Zero v1.2?

GPIO Zero is a Python library I created to make physical computing on the Raspberry Pi more accessible, particularly for use in education. Read more about it on raspberrypi.org, or about how it was created in an article on this blog, GPIO Zero: Developing a new friendly API for Physical Computing.

Background

GPIO Zero is a module providing simple interfaces to GPIO components and devices (LED, Button, Buzzer, LightSensor, TrafficLights, etc). It provides classes representing these devices, for the user to create instances to control each of them. Each device has all the features you’d expect the component to have (e.g. LED has on/off/toggle/blink methods), providing a simple way to perform common tasks with the device. More complex devices (sensors and such) usually require humongous amounts of code, when using the previous library RPi.GPIO, but with GPIO Zero, are generally as straightforward as the simple LED:

from gpiozero import LED, MotionSensor

led = LED(2)
sensor = MotionSensor(3)

sensor.when_motion = led.on
sensor.when_no_motion = led.off

One of the fancier features of the library is source/values. All devices have a value attribute, which when inspected, shows the current state (An LED shows 1 when on, 0 when off; a Button shows 1 when pressed, 0 when released), and a values attribute, which is an infinite iterator constantly yielding the current value. All output devices have a source attribute, which is initially None, but can be set to an infinite iterator. This means you can easily connect two components together:

led.source = button.values

Now the LED’s source comes directly from the Button’s values. In other words, when the button is pressed, the LED is lit.

Additionally, it’s worth noting that an output device’s source can come from an input device (like above), an output device (blue LED comes on when red LED comes on), or from a custom generator (blue LED goes off when red LED comes on, or even something unrelated to GPIO components!)

v1.2

Version 1.2 of GPIO Zero is out now! The next Raspbian release will include it, but you can upgrade now with:

sudo apt-get update
sudo apt-get install python3-gpiozero python-gpiozero

(Note: apt-get install will install a package if it’s not already installed, and will upgrade it if there’s a newer version available)

Dependencies

This version has zero dependencies, so you shouldn’t have any issues installing it even on an older Wheezy image. Previously, the library depended on RPi.GPIO, and spidev, but these are no longer requirements. Alternative pin implementations are available (more on that later), including a pure Python one built in to the library, so RPi.GPIO is no longer required. If it’s present (more than likely the case), then it will be used, but three alternatives are sought if it’s not! Also, a software implementation of the SPI protocol has been implemented, meaning it’s possible to interface with SPI devices without using hardware SPI at all (the spidev library doesn’t need to be installed, and SPI doesn’t even need to be enabled in raspi-config).

Test suite

Something I’ve wanted to have since the early days, but had no idea how to implement. Dave created a test suite, which does a decent job, but does not currently cover the full scope of the library. We have continuous integration set up with Travis, and people have even created GPIO Zero projects related to this – using the Travis CI API to show the test suite status on traffic lights.

trafficlights

What’s new?

See the changelog for full details. We’ve added the following:

Energenie

Energenie is a long-term favourite of mine and others, it’s an add-on board for the Pi which communicates wirelessly with a special power socket (or set of sockets). I previously maintained a Python module for controlling the Energenie, providing simple switch_on() and switch_off() functions which took a socket number to control. The GPIO Zero solution is just as simple, a little more elegant, and importantly comes bundled with the fancy features of a first-class GPIO Zero component (source/values)!

from gpiozero import Button, Energenie

button = Button(21)
light = Energenie(1)

light.source = button.values

Here a connection to Energenie’s socket #1 is created, referenced as light (an actual wall socket desk lamp rather than an LED) and the button set to trigger the light to come on. That’s right – a light switch!

energenie

LineSensor

The basic line sensor unit is a simple binary sensor, so its interface is similar to the Button. It just has aliases for is_active, when_active and wait_for_active.

from gpiozero import LED, LineSensor

led = LED(2)
sensor = LineSensor(3)

sensor.when_line = led.on
sensor.when_no_line = led.off

There’s one of these in the new CamJam Edu Kit 3 (robotics kit), so it will be handy for that!

DistanceSensor

The ultrasonic distance sensor is a little more complex in implementation, and requires two GPIO pins (echo and trigger). Its distance thresholds and such are configurable but basic usage looks like this:

from gpiozero import LED, DistanceSensor

led = LED(2)
sensor = DistanceSensor(echo=3, trigger=4, max_distance=1)

sensor.when_in_range = led.on
sensor.when_out_of_range = led.off

while True:
    print("Distance: %s" % sensor.distance * 100)
    sleep(1)

distancesensor

There’s also one of these in CamJam Kit 3 and they’re popular for various projects not limited to robotics.

SnowPi

An excellent Christmas themed add-on board made by Ryan Walmsley. It’s a snowman with LEDs for eyes, one for the nose, and three for each arm.

snowpi-the-gpio-snowman-for-raspberry-pi

Simple to program using nine individual LED objects but we crafted a neater interface:

from gpiozero import SnowPi

sp = SnowPi()

sp.on()  # all on
sp.blink()  # all blinking
sp.off() # all off

sp.nose.on()  # nose on

sp.arms.on()  # all arm leds on
sp.arms.left.off()  # all leds on left arm off
sp.arms.right.blink()  # right arm blinking

sp.arms.left.top.on()  # individually control top left arm led
sp.arms.right.middle.on()  # similarly
sp.arms.left.bottom.on()  # similarly
sp.arms.bottom.off()  # control bottom led of both arm

This one’s pretty fun to play with! A real stocking filler for next Christmas :)

Holdable Button

Martin O’Hanlon suggested we add a way to detect when a button is held for a given length of time, rather than just when it was pressed. He submitted a PR adding a new HoldableButton class, but Dave ended up adding the functionality into the standard Button class:

from gpiozero import Button

def hello():
    print("Hello")

button = Button(2, hold_time=2)

button.when_held = hello

Pulsing LED

We’ve had led.blink() from the very beginning, and we’ve had an interface for variable brightness LEDs (using PWM). Recently we added additional parameters to PWMLED‘s version of blink so you could configure fade in time and fade out time:

from gpiozero import PWMLED

led = PWMLED(2)

led.blink(on_time=1, off_time=1, fade_in_time=1, fade_out_time=1)

Andrew Scheller then added a PR for a pulse() method which defaulted on_time and off_time to 0. We liked the idea but it seemed rather pointless to create a new method merely aliasing some different default settings of an existing method. I ended up suggesting we actually remove the in_time and out_time parameters, so it’s more like regular blink() but with automatic fading, and the time of the fade configurable. So now:

from gpiozero import PWMLED

led = PWMLED(2)

led.pulse(fade_in_time=1, fade_out_time=1)

Named parameters are not necessary, so in this example you can just use led.pulse(1, 1) – or skip them altogether as those are the defaults:

led.pulse()

With PWM

Watch Ben Nuttall’s Vine “With PWM” taken on 8 February 2016. It has 0 likes. The entertainment network where videos and personalities get really big, really fast. Download Vine to watch videos, remixes and trends before they blow up.

Various ADC chips – and software SPI

We added to our initial support of a couple of ADC chips such as the MCP3008:

  • MCP3001
  • MCP3002
  • MCP3004
  • MCP3008
  • MCP3201
  • MCP3202
  • MCP3204
  • MCP3208

As I mentioned earlier, there’s now a software implementation of the SPI protocol which means you don’t need spidev installed or SPI enabled in raspi-config.

pi_info()

There’s now a function you can run that returns a whole bunch of information about the Pi you’re using: the revision, model, SoC, manufacturer, memory, storage type and more. As well as providing this information to the user on request, it is used internally to warn users when they, for example, try to use a pull-down circuit on a pin with a physical pull-up resistor built in. Also, developers could use this information to do similar things in their own projects or libraries. See the wealth of information provided in data.py

source/value tools

The source/value feature is more advanced than simply using loops, or even callbacks, but it can be really powerful. We found that although the basic examples were very simple to use, there were many alternative common uses that required much more code. For example, if you wanted one LED to mimic another, that’s just blue.source = red.values, but if you want one to be the inverse of the other (i.e. red at 40% brightness should make blue 60% brightness), you’d have to create your own generator function:

from gpiozero import PWMLED

blue = PWMLED(2)
red = PWMLED(3)

def invert(led):
    while True:
        yield 1 - led.value

blue.source = invert(red)

But now we have a set of tools exactly for these common use cases. We have absoluted, clamped, inverted, negated, post_delayed, pre-delayed, quantized, queued, scaled, cos, sin, random_values, all_values, any_values and averaged. The invert example becomes:

from gpiozero import PWMLED
from gpiozero.tools import inverted
blue = PWMLED(2)
red = PWMLED(3)

blue.source = inverted(red.values)

See the documentation on source tools for more information and examples.

Alternative pin implementations

Initially, when I created GPIO Zero, it was just an abstraction layer sitting on top of an existing GPIO library, RPi.GPIO. However, we now support four multiple back-ends: RPi.GPIO, RPIO, pigpiod and a native implementation. The priority is such that RPi.GPIO is preferred, being the most stable option we know of (and 99% of users will be using this implementation, as it’s pre-installed in Raspbian); secondly, RPIO, another Python library with better PWM support; thirdly a Python module which communicates with a C library (pigpio) running as a daemon (pigpiod), which is an interesting option I’ll explain next; finally, if none of those libraries are found to be available, the fallback is a pure Python pins implementation Dave wrote as part of GPIO Zero. It’s pretty basic at present, and is rather experimental, but for basic use it does just about work.

pigpio and pigpiod

pigpio is a C library which provides an interface to GPIO, PWM, SPI, I2C, Serial and more. Its feature set is brilliantly extensive, and its killer feature is the daemon. pigpiod runs as root, but takes commands via sockets from the regular Pi user, or anywhere else. It’s also got a comprehensive set of documentation. Unfortunately, despite its excellent quality and usefulness, it’s not packaged or distributed. It’s just sitting on GitHub. However, we (the Foundation) intend to do this packaging work and ship it with Raspbian in future. Watch this space. Or that space, maybe.

One amazing feature of pigpio is remote pin access. Because GPIO Zero has no dependencies, I can install and run it on my Ubuntu laptop (it would also run on Mac or Windows). I can open a shell, and type:

from gpiozero import LED
from gpiozero.pins.pigpiod import PiGPIOPin

pin = PiGPIOPin(2, host='192.168.0.2')
led = LED(pin)

led.blink()

So rather than creating an LED on pin 2, I create it on a reference to a remote pin elsewhere on the network. This is seriously cool and I look forward to this being used more broadly once pigpio is packaged. See the pins docs for more information on the various pin implementations.

Cheat sheet

We created a GPIO Zero cheat sheet for a special edition of The MagPi. You can download the poster for free from raspberrypi.org/education/downloads/

GPIO_Zero_Cheatsheet

What’s next?

Development of v1.3 is under way. We’re planning to add:

  • Servo
  • One-wire temperature sensor (in CamJam kit 2)
  • DOTS board
  • Composite robot interfaces (robots with sensors as a single object)
  • More – feel free to make suggestions

See the v1.3 milestone for more information – and feel free to chip in with ideas, suggestions and code!

Join the *Zero revolution

Daniel Pope created PyGame Zero, a zero-boilerplate module for making games with Python. I followed this philosophy with GPIO Zero (aptly named so, just before Pi Zero came out…)

The MicroPython API for the BBC micro:bit has been designed with a similar philosophy, and there’s now a NetworkZero library made by Tim Golden. You can read about it in his blog post. Nicholas Tollervey has created a Py-ZeroZero organisation on GitHub for discussion of this family of *Zero libraries and a description of our philosophies.

Thanks

Dave Jones has gone above and beyond and he’s responsible for the vast majority of the code base (and the feature set). I can’t thank him enough for the voluntary work he’s done on the library.

gpiozero-commits

Thanks also to Andrew Scheller, who’s made some great contributions to the code, and helped a lot by posting issues and commenting on commits and PRs. And to Martin O’Hanlon who helped create the holdable Button; to Schelto van Doorn, who added numerous ADC chips; and to everyone who’s used the library, given feedback, shared it with others or provided help with documentation, API design or usage suggestions. Finally thanks to Joan for pigpio.

Carrie Anne Philbin on Twitter

GPIOzero rocks! #pipartypic.twitter.com/tRFSxyqKBY

Fork Handles

I was sad to hear the news of the death of Ronnie Corbett. I’ve always been a huge fan of The Two Ronnies and much of the other work the duo had done both together and individually.

The Two Ronnies. Four Candles [HD]

Possibly one of their best comedy sketches ever, certainly the most popular and requested of all time. My photo tribute: http://bit.ly/1MlmfvZ

Within moments of the news breaking, tributes such as photographs of four candles and fork handles, and links to the clip on YouTube. As soon as I saw these tributes I thought of the phrase fork handles taking another alternative meaning: forking a project called handles on GitHub. So I created the repo, and encouraged others to fork it:

Ben Nuttall on Twitter

In tribute to Ronnie Corbett, I’ve made a new @github repository. You can fork handles:https://github.com/bennuttall/handles …

2015 Open Source Yearbook

I contributed to the 2015 Open Source Yearbook, created by opensource.com, which you can download as a PDF or view the individual articles online.

Open Source Yearbook 2015

The 2015 Open Source Yearbook is a community-contributed collection of the year’s top open source projects, people, tools, and stories. Download the 2015 Open Source Yearbook (PDF) now!

  1. 6 creative ways to use ownCloud – by Jos Poortvliet, ownCloud community manager
  2. 10 tools for visual effects in Linux with Kdenlive – by Seth Kenlon, independent multimedia artist, free culture advocate, and UNIX geek
  3. 6 useful LibreOffice extensions – by Italo Vignoli, founding member of The Document Foundation
  4. Top 5 open source community metrics to track – by Jesus M. Gonzalez-Barahona, co-founder of Bitergia
  5. 5 great Raspberry Pi projects for the classroom – by Ben Nuttall, education developer advocate for the Raspberry Pi Foundation
  6. 8 books to make you a more open leader – by Bryan Behrenshausen, for The Open Organization
  7. 5 handy Drupal modules – by Michael E. Meyers, the VP of Developer Relations at Acquia
  8. Best Couple of 2015: tar and ssh – by David Both, Linux expert and enthusiast
  9. 3 open hardware projects for beginners – by Alicia Gibb, CEO of Lunchbox Electronics
  10. 10 helpful tools for a sys admin’s toolbox – by Ben Cotton, support engineer group leader at Cycle Computing
  11. Top 10 open source projects of 2015 – by Jen Wike Huger, an editor for Opensource.com
  12. 5 favorite 3D printing projects of 2015 – by Harris Kenny, VP of Marketing at Aleph Objects
  13. Top 5 open source frameworks every application developer should know – by John Esposito, Editor-in-Chief at DZone
  14. Publisher’s picks: 29 open source books for 2015 – by Rikki Endsley, Community Manager at Opensource.com
  15. Diversity in open source highlights from 2015 – by Cindy Pallares-Quezada, an Outreachy alumni
  16. Adafruit’s best open source wearables of 2015 – by Becky Stern, director of wearables at Adafruit
  17. 2015 was a good year for creating the world’s ‘missing maps’ with OpenStreetMap – by Drishtie Patel, GIS Analyst and Missing Maps Project Coordinator at the American Red Cross
  18. 5 favorite open source Django packages – by Jeff Triplett, Frank Wiles, and Jacob Kaplan-Moss, Django contributors
  19. Facebook’s top 5 open source projects of 2015 – by Christine Abernathy, Developer Advocate on the Open Source team at Facebook
  20. 10 projects to fork in 2016 – by Jason Baker, Opensource.com
  21. 10 cool tools from the Docker community – by Mano Marks, director of developer relations at Docker, Inc.
  22. 5 best open source games of 2015 – by Robin Muilwijk, Internet and e-government advisor

contributor_horiz