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:
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:
On this tutorial, we will explore as input devices ("sensors"):
- Motion Detector Sensor
and as output ("actuators"):
- Generic Digital Output (Stepper Motor)
Step 1: Bill of Material
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
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
- 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:
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)/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: