Pi IoT In Python Using GPIO Zero - On/Off Devices
Written by Harry Fairhead & Mike James   
Monday, 14 December 2020
Article Index
Pi IoT In Python Using GPIO Zero - On/Off Devices
Buzzer & Custom Device

Simple on/off devices are, obviously, the simplest of IoT devices you can work with. In this extract from a new book on using GPIO Zero on the Pi in Python we look at how to get started.

Raspberry Pi IoT In Python Using GPIO Zero
Second Edition

By Harry Fairhead & Mike James


Buy from Amazon.


  1. Why Pi for IoT?
  2. Getting Started With Python And GPIO Zero
  3. Introduction to the GPIO
  4. Python - Class and Object
  5. Simple On/Off Devices
      Extract 1: On/Off Devices *
  6. Pins And Pin Factories
      Extract 1: Pins 
  7. Some Electronics
  8. Simple Input
      Extract 1:Getting Input ***NEW!!
  9. Complex Input Devices
      Extract 1: Complex Input *
  10. Pulse Width Modulation
      Extract 1:  PWM*
  11. Controlling Motors And Servos
      Extract 1: DC Motors *
  12. Working With Compound Devices
      Extract 1: Compound Devices*
  13. The SPI Bus
  14. Custom SPI Devices
  15. Using The Lgpio Library
  16. Appendix Visual Studio Code Remote Python
    *Extracts from first edition - will be updated.


There are only two simple on/off devices – the LED and the Buzzer. In this chapter we look at each in turn and learn how to create our own new custom on/off devices.


The inheritance hierarchy for the simple output devices is:

If you don’t know about inheritance then see the previous chapter.

Knowledge of the inheritance hierarchy is mostly useful in creating your own custom classes to extend GPIO Zero. Device is the most general and then we have GPIODevice which corresponds to a single GPIO line used as input or output. OutputDevice is a general output line, DigitalOutputDevice only has two states and finally LED and Buzzer correspond to real devices.

LED In Detail

The LED class is the archetypal on/off device. You have already seen how to create an LED object associated with a particular GPIO pin:

led = LED(4)

creates an LED object associated with GPIO4.

Other things you can specify when creating an LED object are:

LED(pin, active_high=True, initial_value=False, pin_factory=None): 


the GPIO pin you want to user


if True the on method sets the line high if false the off method sets the line high.


if false the device is initially off if true device is initially on


the underlying pin factory to use – let GPIO Zero set this.

So for example:

led=LED(4, active_high=True, initial_value=True)

creates an LED associated with GPIO4 that is high when switched on and hence initially on.

There are only four methods associated with LED. The most commonly used are on and off which switch the LED on and off.

If you want to make the LED flash then you can use:

blink(on_time, off_time,n, background)

which will blink the LED n times, on for on_time and off for off_time specified in seconds. The background parameter defaults to true and this allows the blinking to be performed on another thread in the background. That is, if background is false the blink method blocks and does not return until the n blinks have been completed, which brings your program to a halt. If you want to do other things while the LED is flashing then set background to True or accept the default. The LED will then flash n times after blink has returned.

For example, our original Blinky LED program given in Chapter 3:

from gpiozero import LED
from time import sleep
led = LED(4)
while True:

can be written as:

from gpiozero import LED
from signal import pause
led = LED(4)
print("Program Complete")

If you try this out you will discover that the LED keeps flashing for almost 200 seconds after the program has printed Program Complete. Notice that you need the pause at the end of the program because if your program comes to a halt so do any threads that the program has created. In short, without the pause() you wouldn’t see the LED flash at all. The point is that usually when you give a Python instruction you only move on to the next instruction when the current instruction has completed.

This is generally called “blocking” because the current instruction stops the next instruction executing before it is complete. The call to blink is non-blocking because it returns before it has finished everything you told it to do and the next instruction is executed while it is unfinished. Instructions that are non-blocking are very useful when working with hardware because it allows your program to get on with something else while the hardware is doing something.

Compare the behavior of the background non-blocking program with a blocking version:

from gpiozero import LED
led = LED(4)
print("Program Complete")

In this case you don’t need the pause() because the program waits for the LED to have completed 100 flashes. You will only see the Program Complete message after 200 seconds.

It is interesting that in either case the blink method makes use of a new thread to run LED in the background, the only difference is that when background is false the main thread waits for the blink thread to complete.

The toggle method simply changes the LED from on to off or off to on depending on its current state. You can use it to write the Blinky program in yet another way:

from gpiozero import LED
from time import sleep
led = LED(4)
while True:

There are also some useful properties. The is_lit property is true if the LED is currently active and value sets and gets the state of the LED as a 1 or a 0.

Finally we have the pin property which returns the pin object that the LED is connected to. The Pin object provides lower-level access to the GPIO line.

Last Updated ( Monday, 14 December 2020 )