Introduction: Playing With Electronics: Raspberry GPIO Zero Library Tutorial

About: Engineer, writer and forever student. Passionate to share knowledge of electronics with focus on IoT and robotics.

A simple way to learn electronics is using Raspberry Pi and its GPIO Zero Library. With a very few code in Python you will control actuators, read sensors, etc. It was created by Ben Nuttall of the Raspberry Pi Foundation, Dave Jones, and other contributors.

Here on this quick tutorial, I will give you the base for creating simple circuits controlled by the Raspeberry Pi. For full details, please see the bellow link:

GPIO Zero V 1.3.1 Documentation

Also you can download from magPi magazine a full free book that will guide you step by step on several projects using the Gpiozero library:

SIMPLE ELECTRONICS WITH GPIO ZERO

On this tutorial, we will explore as input devices ("sensors"):

  1. Button
  2. Motion Detector Sensor

and as output ("actuators"):

  1. LED
  2. Buzzer
  3. Generic Digital Output (Stepper Motor)

Let's go!

Step 1: Bill of Material

  1. Raspberry Pi (V2 or 3)
  2. Stepper Motor (5V) + ULN2003 Driver Board
  3. PIR Motion Sensor
  4. Breadboard
  5. Push-Button
  6. LED
  7. Resistor 330 ohms
  8. Jumper Wire Dupont Cable (Female/Male and Male/Male)

Step 2: Installing the GPIO Zero Library

The first thing to do it is to update your repositories list:

sudo apt-get update

Then install the package of your choice. Both Python 3 and Python 2 are supported. Python 3 is recommended:

sudo apt-get install python3-gpiozero

Pin Numbering

Important to mention that GPIO Zero Library uses Broadcom (BCM) pin numbering for the GPIO pins, as opposed to physical (BOARD) numbering. Any pin marked “GPIO” in the above diagram can be used as a pin number. For example, if an LED was attached to “GPIO18” you would specify the pin number as 18 rather than 12.

Step 3: "Hello World": Blinking a LED

To connect our RPi to the world let's first connect:

  • Physical Pin 6 (GND) to GND Breadboard Power Grid (Blue -), using a black jumper
  • Physical Pin 1 (3.3V) to +VCC Breadboard Power Grid (Red +), using a red jumper

Now, let's connect a LED, using the physical pin 12 (GPIO18) connected to LED cathode (longer LED leg). Connect the LED anode to breadboard GND using a 330 ohms resistor to reduce the current that will be drained from the RPi as shown in the above picture.

Once the HW is connected, let's create a Phyton program to turn-on the LED:

from gpiozero import LED
led = LED(18)
led.on()

To create and run the program, you can use the Python3 application that appears in your RPi OS menu or use any text editor by saving the file, for example as "MyPgmName.py" and then executing it using a Command line on the monitor, for example:

Sudo Python MyPgmName.py

As you can see, it is very simple to code using GPIO Zero Library.

Now, let's Blink the LED (the real "Hello world", when we are talking about HW.

To do that, we must also import another library that is "time". We will need it to define the the amount of time that the LED will be ON and OFF. In our case bellow, the LED will blink with a 1second time.

from gpiozero import LED
from time import sleep
led = LED(18)
while True:
    led.on()
    sleep(1)
    led.off()
    sleep(1)

The video bellow shows our code in action:

Alternatively, you can reduce the Blink code as bellow:

from gpiozero import LED
from signal import pause
red = LED(17)
red.blink()
pause()

Step 4: Reading a Digital Signal From a Button

The simple way to get an external commend is using a push-button and the GPIO Library provide a easy way to include it on your project. You do not need to think about Pull-up or Pull-down resistors, etc. In terms of HW, the only thing to do is to connect one leg of your push-button to any one of RPi GPIOs and the other one to GND as shown in the above picture:

  • Push-Button leg1 to GPIO2
  • Push-Button leg2 to GND

A simple code for reading the button can be:

from gpiozero import Button
button = Button(2)
while True: 
    if button.is_pressed: 
        print("Button is pressed") 
    else:
        print("Button is not pressed")

Another idea can be to add a button to previous code on a way that the LED will turn-on when the button is pressed and off when released. The Python code is shown bellow:

from gpiozero import LED, Button
from signal import pause
led = LED(18)
button = Button(2)
button.when_pressed = led.on
button.when_released = led.off
pause()

Below, the video shows how the program works:

Now that you learned the basics, go to: GPIO Zero: Button and explore more options to play with buttons.

Step 5: Motion Detection

Let's explore other common devices included at library. We will take advantage of a buzzer and a motion detector sensor (PIR) that together with a LED will work as a simple alarm.

As we explored on my last tutorial, IoT Motion Detector With NodeMCU and BLYNK, the PIR sensor will generate a Hight level pulse anytime that a movement happens on its sight. This motion sensor module uses the LHI778 Passive Infrared Sensor and the BISS0001 IC to control how motion is detected. The module features adjustable sensitivity that allows for a motion detection range from 3 meters to 7 meters.The module also includes time delay adjustments and trigger selection that allow for fine tuning within your application.

The PIR device has a small circuit board with three pins: VCC, OUT, and GND. VCC should be connected to a 5V pin, GND to one of the ground pins, and finally OUT to one of GPIOs, in our case: GPIO23.

Spite that the PIR is sourced with 5V, its output has a maximum of 3.3V, so it is safe to connect it directly to RPi pin.

The bellow simple Python code shows how to use it:

from gpiozero import MotionSensor
pir = MotionSensor(23)
pir.wait_for_motion()
print("Motion detected!")

In order to built a more nice alarm, let's also include the LED (connected on GPIO18) and a buzzer (connected on GPIO24). For that we will need to also import those devices from the library:

from gpiozero import MotionSensor, Buzzer, LED
import time
pir = MotionSensor(23)
bz = Buzzer(24)
led = LED(18)
print("Waiting for PIR to settle")
pir.wait_for_no_motion()
while True:
    led.off()
    print("Ready")
    pir.wait_for_motion()
    led.on()
    print("Motion detected!")
    bz.beep(0.5, 0.25, 8)
    time.sleep(3)

Bellow, a movie showing the alarm working:

Step 6: Controlling a Stepper Motor

A Stepper motor has 4 coins that should be properly energized to make it rotate over its axis. In other words, to rotate the stepper motor you provide a sequence of “high” and “low” levels to each of the 4 inputs in sequence. By setting the correct sequence of high and low levels the motor spindle will rotate. The direction can be reversed by reversing the sequence.

We will use 4 GPIOs as Digital outputs to drive the Step motor.

The motor connects to the controller board with a pre-supplied connector. The controller board has 4+2 pins that need to be connected to the RPi header:

  • Source (2):
    • (Pin 1) ==> 5V
    • (Pin 2) ==> GND

and

  • Digital inputs (4):
    • IN1 ==> GPIO12
    • IN2 ==> GPIO16
    • IN3 ==> GPIO20
    • IN4 ==> GPIO21

The bellow link will give you more details about how to work with a Stepper Motor using a Raspberry Pi and Phyton:

Stepper Motor Control In Python

Based on the above link, we can recreate the code, simplifying it in order to use with the GPIO zero library. Also, you should decide if you want "speed" or "torque". this is a compromise that you can chose depending on the step sequence (4 or 8 steps). I create a variable "mode", so you can test both sequences.

You can run this program as the previous ones, for example using the Python 3 shell available on Raspbian OS or directly on monitor using the command:

sudo Python StepMotorCtrl.py 2

where the parameter "2" means that the delay provide on turning the step will be 2ms . If no parameter is used, the code assume 4ms (waitTime = 0.004).

import time
import sys
from gpiozero import OutputDevice as stepper
IN1 = stepper(12)
IN2 = stepper(16)
IN3 = stepper(20)
IN4 = stepper(21)
stepPins = [IN1,IN2,IN3,IN4] # Motor GPIO pins</p><p>
stepDir = -1        # Set to 1 for clockwise
                           # Set to -1 for anti-clockwise
mode = 1            # mode = 1: Low Speed ==> Higher Power
                           # mode = 0: High Speed ==> Lower Power
if mode:              # Low Speed ==> High Power
  seq = [[1,0,0,1], # Define step sequence as shown in manufacturers datasheet
             [1,0,0,0], 
             [1,1,0,0],
             [0,1,0,0],
             [0,1,1,0],
             [0,0,1,0],
             [0,0,1,1],
             [0,0,0,1]]
else:                    # High Speed ==> Low Power 
  seq = [[1,0,0,0], # Define step sequence as shown in manufacturers datasheet
             [0,1,0,0],
             [0,0,1,0],
             [0,0,0,1]]
stepCount = len(seq)
if len(sys.argv)>1: # Read wait time from command line
  waitTime = int(sys.argv[1])/float(1000)
else:
  waitTime = 0.004    # 2 miliseconds was the maximun speed got on my tests

stepCounter = 0

while True:                          # Start main loop
  for pin in range(0,4):
    xPin=stepPins[pin]          # Get GPIO
    if seq[stepCounter][pin]!=0:
      xPin.on()
    else:
      xPin.off()
  stepCounter += stepDir
  if (stepCounter >= stepCount):
    stepCounter = 0
  if (stepCounter < 0):
    stepCounter = stepCount+stepDir
  time.sleep(waitTime)     # Wait before moving on

Bellow video shows the Stepper Motor controlled by RPi:

Step 7: Conclusion

As always, I hope this project can help others find their way in the exciting world of electronics!

For more projects, please visit my blog:

MJRoBot.org

Saludos from the south of the world!

See you at my next instructable!

Thank you

Marcelo

Epilog Contest 8

Participated in the
Epilog Contest 8