GPIO Zero:
Developing a friendly Python API
for physical computing
Ben Nuttall
Raspberry Pi Foundation
UK Charity 1129409
Slide 2
Slide 2 text
Ben Nuttall
●
Education Developer Advocate at the
Raspberry Pi Foundation
– Runs www.raspberrypi.org
– Software & project development
– Learning resources & teacher
training
– Outreach
●
Hobbyist turned employee
●
@ben_nuttall on Twitter
Slide 3
Slide 3 text
RPi.GPIO
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(17, GPIO.OUT)
while True:
GPIO.output(17, True)
sleep(1)
GPIO.output(17, False)
sleep(1)
Slide 4
Slide 4 text
Current state of affairs with RPi.GPIO
●
Broad use of RPi.GPIO
– Used in Raspberry Pi learning resources
– 132k code search results on github.com
●
Lots of typing required for basic examples
●
Lots of copy/paste code when using more complicated devices
like sensors
●
Requires fundamental understanding of electronics
●
Lots of use of polling
●
Implementation in C – exposes a non-Pythonic API
Slide 5
Slide 5 text
sudo
●
In Raspbian Wheezy, root access was needed to access the
GPIO pins
●
This meant running Python files with sudo
●
This also meant opening IDLE from the menu did not allow
GPIO access, must be opened with sudo idle &
●
The pi user was given access to GPIO pins in Raspbian Jessie
(released during development of GPIO Zero)
Slide 6
Slide 6 text
Motivation
●
CamJam talk 12/9/15 - How to build Python APIs for
Raspberry Pi Hardware
●
Teachers saying it's too hard to use Python
●
Too much code to write to flash an LED (what is this, Java?)
●
Too much boilerplate code needed to get started
●
Too many electronics concepts required to understand (or
ignore) e.g. pull-up vs. pull-down, and falling/rising edge
●
Lots of bad code out there – all being copied
Slide 7
Slide 7 text
Inspiration
●
Python libraries for Pimoroni add-on boards
●
Community users like Martin O'Hanlon commonly using LED
class, etc.
●
Picamera Python library
●
Flotilla
●
PyGame Zero – zero boilerplate wrapper for Pygame
Slide 8
Slide 8 text
Intended audience
●
Teachers
●
Children
●
Beginners
●
Hobbyists
Slide 9
Slide 9 text
GitHub
Slide 10
Slide 10 text
GitHub Issues
Slide 11
Slide 11 text
Google Doc
Slide 12
Slide 12 text
GPIO Zero
from gpiozero import LED
from time import sleep
led = LED(17)
while True:
led.on()
sleep(1)
led.off()
sleep(1)
Slide 13
Slide 13 text
GPIO Zero
from gpiozero import LED
led = LED(17)
led.blink()
Slide 14
Slide 14 text
What do you think?
Slide 15
Slide 15 text
A few minor observations...
Slide 16
Slide 16 text
Hooked
Slide 17
Slide 17 text
#4 Name?
Slide 18
Slide 18 text
#4 Name?
Slide 19
Slide 19 text
Eben, what do you think?
Slide 20
Slide 20 text
Some initial comments
●
“You're making it too easy”
●
“Part of the fun is learning how it works”
●
“It shouldn't be this easy to blink an LED”
●
“You're dumbing down the flexibility of RPi.GPIO”
●
“It's nice but I'll still use RPi.GPIO for the complex stuff”
Slide 21
Slide 21 text
More initial comments
●
“I'll have one of those. Can you get it ready for the next
Raspbian release?” - Eben Upton
●
“It's great! I never meant for RPi.GPIO to be an end-user library
anyway!” - Ben Croston
LED
from gpiozero import LED
from time import sleep
led = LED(17)
led.on() # on
led.off() # off
led.toggle() # on>off or off>on
led.blink() # flash on/off continuously
Slide 25
Slide 25 text
Buzzer
from gpiozero import Buzzer
from time import sleep
buzzer = Buzzer(18)
buzzer.on() # on
buzzer.off() # off
buzzer.toggle() # on>off or off>on
buzzer.beep() # beep on/off continuously
Slide 26
Slide 26 text
Button polling (pull-up) – RPi.GPIO
GPIO.setup(4, GPIO.IN, GPIO.PUD_UP)
while True:
if not GPIO.input(4):
print(“Pressed”)
Slide 27
Slide 27 text
Button polling (pull-down) – RPi.GPIO
GPIO.setup(4, GPIO.IN, GPIO.PUD_DOWN)
while True:
if GPIO.input(4):
print(“Pressed”)
Slide 28
Slide 28 text
Button polling (pull-up) – GPIO Zero
button = Button(4)
while True:
if button.is_pressed:
print(“Pressed”)
Slide 29
Slide 29 text
Button polling (pull-down) – GPIO Zero
button = Button(4, pull_up=False)
while True:
if button.is_pressed:
print(“Pressed”)
Button + LED
from gpiozero import LED, Button
led = LED(17)
button = Button(4)
button.when_pressed = led.on
button.when_released = led.off
Slide 39
Slide 39 text
GPIO Music Box
from gpiozero import Button
import pygame.mixer
from pygame.mixer import Sound
pygame.mixer.init()
sound_pins = {
2: Sound("samples/drum_tom_mid_hard.wav"),
3: Sound("samples/drum_cymbal_open.wav"),
}
buttons = [Button(pin) for pin in sound_pins]
for button in buttons:
sound = sound_pins[button.pin]
button.when_pressed = sound.play
Slide 40
Slide 40 text
LED – PWM – RPi.GPIO
GPIO.setup(17, GPIO.OUT) # pin 17
p = GPIO.PWM(17, 100) # pin 17, frequency 100Hz
p.start(0) # initial duty cycle
for i in range(101):
p.ChangeDutyCycle(i)
sleep(0.01)
Slide 41
Slide 41 text
LED – PWM – GPIO Zero
from gpiozero import PWMLED
led = PWMLED(17)
led.on() # on
led.off() # off
led.value = 0.5 # half brightness
Slide 42
Slide 42 text
Full colour LED
from gpiozero import RGBLED
led = RGBLED(red=2, green=3, blue=4)
led.red.on() # full red
led.color = (1, 0, 1) # purple
led.blue = 0.3 # dim the blue value to 0.3
# now (1, 0, 0.3)
Slide 43
Slide 43 text
Traffic Lights
from gpiozero import TrafficLights
lights = TrafficLights(9, 10, 11)
lights.on() # all on
lights.off() # all off
lights.red.on() # red on
lights.toggle() # swap state of all lights
Motion sensor
from gpiozero import LED, MotionSensor
led = LED(2)
sensor = MotionSensor(3)
sensor.when_motion = led.on
sensor.when_no_motion = led.off
Slide 49
Slide 49 text
Light sensor
from gpiozero import LED, LightSensor
led = LED(2)
sensor = LightSensor(3)
while True:
sensor.wait_for_light()
print("It's light!")
sensor.wait_for_dark()
print("It's dark")
Slide 50
Slide 50 text
Temperature sensor
●
w1thermsensor library exists
●
Yet to be implemented in GPIO Zero compatible style
Slide 51
Slide 51 text
CamJam Kit 3 - robot
●
Components:
– Motor Controller Board
– Motors
– Ultrasonic Sensor
– Line Sensor
●
Recipes:
– Driving and turning
– Line follower
– Obstacle avoidance
– Add a camera
Slide 52
Slide 52 text
Motor
from gpiozero import Motor
from time import sleep
motor = Motor(forward=17, backward=18)
while True:
motor.forward()
sleep(5)
motor.backward()
sleep(5)
Slide 53
Slide 53 text
Robot
from gpiozero import Robot
from time import sleep
robot = Robot(left=(17, 18), right=(22, 23))
while True:
robot.forward()
sleep(10)
robot.left()
sleep(1)
Custom value generators
blue = PWMLED(16)
blue.source = [i / 10000.0 for i in range(10000)]
red = PWMLED(12)
red.source = blue.values
blue.source = [i / 10000.0 for i in range(10000)]
sensor = LightSensor(18)
blue.source = sensor.values
Slide 67
Slide 67 text
Custom value generators
def read_slowly(iterable):
for i in iterable:
yield i
sleep(0.1)
red.source = read_slowly(blue.values)
blue.source = read_slowly(sensor.values)
GPIO Zero Timeline
●
12 Sept – CamJam talk sparked idea
●
14 Sept – Initial commit on GitHub
●
15 Sept – Named GPIO Zero, first PR, first alpha released on PyPi
●
23 Sept – Mentioned in talk at PyConUK
●
28 Sept – v0.6 public beta 1
●
09 Oct – v0.7 public beta 2
●
16 Oct – v0.8 public beta 3
●
25 Oct – v0.9 public beta 4
●
29 Oct – Featured in The MagPi
●
16 Nov – v1.0 released
●
21 Nov – Released in Raspbian Jessie
Slide 70
Slide 70 text
v1.0
●
~200 commits
●
2 contributors (+4 minor contributions)
●
103 GitHub issues (53 issues, 50 PRs)
●
4 alpha releases
●
4 beta releases
●
68 days between initial commit and major release
Slide 71
Slide 71 text
Future development
●
Add more components
●
Integrate more add-ons
●
Add test suite
●
Replace RPi.GPIO dependency
●
Promote use of “gpiozero standard” to allow other modules to
provide objects which plug-in to gpiozero objects easily (e.g.
source/values)
Slide 72
Slide 72 text
What have I learned?
●
Issue-driven development works really well
●
Dave Jones is awesome (ok I already knew that)
●
User-focused API design is important
●
Getting feedback from teachers is hard
●
Getting code contributions is hard
●
Getting documentation contributions is easier
Slide 73
Slide 73 text
Install GPIO Zero
●
Pre-installed in Raspbian Jessie since November
●
Update with:
sudo aptget update
●
Install with:
sudo aptget install python3gpiozero
or:
sudo aptget install pythongpiozero
Slide 74
Slide 74 text
GPIO Zero
●
www.pythonhosted.org/gpiozero
– Installation instructions
– Documentation
– Examples
●
GitHub Issues
– Suggestions
– Feedback
●
Contact me
– [email protected]
– @ben_nuttall on Twitter
●
#gpiozero on Twitter
Slide 75
Slide 75 text
Zero all the things!
●
Raspberry Pi Zero
●
PyGame Zero
●
GPIO Zero
Slide 76
Slide 76 text
GPIO Zero:
Developing a friendly Python API
for physical computing
Ben Nuttall
Raspberry Pi Foundation
UK Charity 1129409