A simple way to learn electronics is using Raspberry Pi and its GPIO Zero Library. With a very few lines of code in Python you will be able to control actuators, read sensors, etc. It was created by Ben Nuttall of the Raspberry Pi Foundation, Dave Jones, and other contributors.
Here in this quick tutorial, I will give you the basis for creating simple circuits controlled by the Raspberry Pi. For full details, please see this link: GPIO Zero V 1.3.1 Documentation. Also you can download it from magPi magazine a full free book that will guide you step by step on several projects using the GPIO Zero library: Simple Electronics with GPIO Zero.
On this tutorial, we will explore as input devices ("sensors
"):
- Button
- Motion Detector Sensor
And as output ("actuators
"):
- LED
- Buzzer
- Generic Digital Output (Stepper Motor)
Let's go!
Bill of Material- Raspberry Pi (V2 or 3)
- Breadboard
- Push-Button
- LED
- Resistor 330 ohms
- Jumper Wire Dupont Cable (Female/Male and Male/Male)
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.
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 Python 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 the RPi 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 1 second 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 below:
from gpiozero import LED
from signal import pause
red = LED(17)
red.blink()
pause()
Reading a digital signal from a buttonThe 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 below:
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.
Motion DetectionLet'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 below 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)
Below, a movie showing the alarm working:
Controlling a Stepper MotorA 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
Digital inputs (4):
- IN1 ==> GPIO12
- IN2 ==> GPIO16
- IN3 ==> GPIO20
- IN4 ==> GPIO21
The link below will give you more details about how to work with a Stepper Motor using a Raspberry Pi and Python: 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
Below video shows the Stepper Motor controlled by RPi:
ConclusionAs 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 tutorial! Thank you!
Marcelo
Comments