Reader small image

You're reading from  Practical Python Programming for IoT

Product typeBook
Published inNov 2020
Reading LevelIntermediate
PublisherPackt
ISBN-139781838982461
Edition1st Edition
Languages
Right arrow
Movement with Servos, Motors, and Steppers

In the previous chapter, we covered how to measure temperature, humidity, light, and moisture. In this chapter, we will turn our attention to the control of motors and servos, which are common devices for creating physical movement and motion. The core concepts, circuits, and code you will learn in this chapter will open up a world of physical automation and robotics using your Raspberry Pi.

We will be learning how Pulse Width Modulation (PWM) is used to set the angle of a servo, and how we use an H-Bridge IC to control the direction and speed of a DC motor. We will look at stepper motors and how they can be controlled for precise movement.

Here is what we will cover in this chapter:

  • Using PWM to rotate a servo
  • Using an H-Bridge IC to control a motor
  • Introduction to stepper motor control

Technical requirements

To perform the exercises in this chapter, you will need the following:

  • Raspberry Pi 4 Model B
  • Raspbian OS Buster (with desktop and recommended software)
  • Minimum Python version 3.5

These requirements are what the code examples in this book are based on. It's reasonable to expect that the code examples should work without modification on Raspberry Pi 3 Model B or a different version of Raspbian OS as long as your Python version is 3.5 or higher.

You will find this chapter's source code in the chapter10 folder in the GitHub repository available at https://github.com/PacktPublishing/Practical-Python-Programming-for-IoT.

You will need to execute the following commands in a terminal to set up a virtual environment and install the Python libraries required for the code in this chapter:

$ cd chapter10              # Change into this chapter's folder
$ python3 -m venv venv # Create Python Virtual Environment
$ source venv/bin/activate...

Using PWM to rotate a servo

Common servomotors, or servos, are internally geared motors that allow you to rotate its shaft to a precise angle within a 180-degree arc. They are a core component of industrial robots, and toys alike, and we're all familiar with hobby servos found in toys such as radio-controlled cars, planes, and drones.

Pictured in Figure 10.1 are a full-size hobby-style servo, a micro servo, and a set of header pins, which are useful to help connect a servo to a breadboard, which we will need to do later in this section as we build our circuit:

Figure 10.1 – Servos

The great feature of servos is that they are essentially a Plug'n'Play style device – after we connect them to the power supply, we just need to send them a PWM signal that encodes the angle we want the servo to rotate to, and presto! We're done. No ICs, no transistors, or any other external circuitry. What's even better is that servo control is so common that...

Connecting a servo to your Raspberry Pi

Our first task for our servo example is to wire it up to a power source and our Raspberry Pi. A schematic representing this wiring is shown here:

Figure 10.2 – Servo wiring schematic

Let's get started wiring our servo using a breadboard, as shown:

Figure 10.3 – Servo breadboard layout

Before we step through the wiring procedure, first I want to briefly discuss the wire colors coming out of a servo. While servo wire colors are somewhat standard, they can vary between different manufacturers and servos. Use the following pointers when connecting your servo at steps 4, 5, and 6. If your servo has colored wires that I do not list in the following list, you will need to consult the datasheet for your servo. 

Common servo wire colors are as follows:

  • The brown or black wire connects to GND
  • The red wire connects to +5-volts
  • The orange, yellow, white, or blue wire is the signal/PWM input wire that connects to a GPIO pin...

How a servo is controlled using PWM

Servos typically require around a 50 Hz PWM signal (some variation around 50 Hz is okay, but we'll stick with 50 Hz as this is the common reference point), and a pulse width between 1.0 milliseconds and 2.0 milliseconds that determines the angle of rotation. The relation between pulse widths, duty cycles, and angle is illustrated in Figure 10.4. Don't worry if all this does not sink in just yet. It should become more clear as we see our servo in action and review our servo-related code in the next section:

Figure 10.4 – Servo's pulse width, duty cycle, and angles

We have not covered pulse width in relation to our earlier coverage of PWM; however, it's just another way of describing the duty cycle.

Here is an example:

  • If we have a PWM signal at 50 Hz (that is, 50 cycles per second), then this means that 1 PWM cycle takes 1 / 50 = 0.02 seconds, or 20 ms.
  • Thus, a pulse width of 1.5 ms expressed as a duty cycle is 1.5 ms...

Running and exploring the servo code

The code we are about to run can be found in the chapter10/servo.py file. I recommend reviewing the source code before proceeding so that you have an overall idea about what the file contains.

When you run the code found in the chapter10/servo.py file, your servo should rotate left and then right several times.

Let's look at the code, starting with some pulse width variables defined at line 1:

LEFT_PULSE  = 1000   # Nano seconds          # (1)
RIGHT_PULSE = 2000
CENTER_PULSE = ((LEFT_PULSE - RIGHT_PULSE) // 2) + RIGHT_PULSE # Eg 1500

These pulse widths represent our servo's extreme left and right rotation.

Note that the LEFT_PULSE and RIGHT_PULSE values are in nanoseconds, as this is the unit used by the PiGPIO servo functions.

These values of LEFT_PULSE = 1000 and  RIGHT_PULSE = 2000 are the perfect world values that you will see sighted often. In reality, you may need to make...

Different types of servos

Our example used a common 3-wire, 180-degree angular servo. While this is a very common type of servo, there are other variations as well, including continuous rotation servos, servos with more than three wires, and special purpose servos:

  • Continuous rotation servos: Have 3 wires and work on the same PWM principles as a 3-wire angular servo, except the PWM pulse width determines the rotational direction (clockwise/counter-clockwise) and speed of the servo.
Due to their internal control circuitry and gearing, continuous rotation servos are a convenient low-speed/high-torque alternative to a DC motor and H-Bridge controller (which we will be covering in the next section).
  • 4-wire servos: These come with one set of three wires and a fourth loose wire. This fourth wire is an analog output of the servo that can be used to detect the angle. It's useful if you need to know your servo's resting angle when you start your program.
...

Using an H-Bridge IC to control a motor

In Chapter 7, Turning Things On and Off, we learned how to use a transistor to turn a DC motor on and off, and we also saw how to control the motor's speed using PWM. One limitation of our single transistor circuit was that the motor only rotated in one direction. In this section, we will explore a way to let us spin our motor in both the forward and backward directions – using what is known as an H-Bridge circuit.

The H in H-Bridge comes from the perception that a basic H-Bridge circuit schematic (created from four individual transistors) make a letter H.

If you search around sites such as eBay for an H-Bridge module, you will identify many ready-made modules for the same purpose that we will cover in this section. What we will do is build a replica module on our breadboard. Once you have your breadboard replica working and understand how it works, you will be in a position to understand the construction of...

Building the motor driver circuit

In this section, we will build our H-Bridge circuit that we will use to control two DC motors. The following schematic describes the circuit we will create. While this circuit looks busy, most of our work will be simply connecting the legs of the L293D IC to our Raspberry Pi, power source, and motors:

Figure 10.5 – L293D and motor schematic diagram

As there are a lot of wire connections to get through, we will build this circuit on our breadboard in four parts.

We will be using an IC in our circuit build. Many ICs (including the L293D) are sensitive to static electricity discharge (ESD), and if exposed to static discharge, they can be damaged. As a general rule, you should avoid touching the pins/legs of an IC with your fingers so that any static charge you have in your body does not get discharged to the IC.

Let's get started with the first part, as illustrated in the following diagram:

Figure 10.6 – L293D breadboard layout...

Running the example H-Bridge code to control a motor

Now that you have created your H-Bridge driver circuit and connected your motors, let's run the code that will make the motors spin.

There are two files for this section, and they can be found in chapter10/motor_class.py and chapter10/motor.py. Run the code found in chapter10/motor.py and your motors will turn on, change speeds, and change direction.

Place a piece of tape on the shaft of your motors to make it easier to see when they rotate and in what direction.

When you have confirmed that your circuit works with the example code, we will next proceed and discuss the code. Since the L293D can drive two motors, the common code has been abstracted out into motor_class.py, which is imported and used by motor.py to drive our two individual motors.

We'll start by looking at motor.py.

motor.py

Starting at line 1, we import PiGPIO and the Motor class defined in the motor_class.py file, before defining several variables describing how we are connecting the L293D to our Raspberry Pi's GPIO pins:

import pigpio                    # (1)
from time import sleep
from motor_class import Motor

# Motor A
CHANNEL_1_ENABLE_GPIO = 18 # (2)
INPUT_1Y_GPIO = 23
INPUT_2Y_GPIO = 24

# Motor B
CHANNEL_2_ENABLE_GPIO = 16 # (3)
INPUT_3Y_GPIO = 20
INPUT_4Y_GPIO = 21

Referring back to Figure 10.3 and Figure 10.4, if we consider the Motor A (channel 1) side of the circuits, we see that the logic pins are connected to GPIOs 23 and 24 at line 2 – INPUT_1Y_GPIO = 23 and INPUT_2Y_GPIO = 24. These logic pins (together with the enable pin that we will cover shortly) are used to set the state and rotational direction of the motor. The truth table for these states is shown as follows.

This table was sourced from the L293D datasheet and reformatted and supplemented to match...

motor_class.py

First, we see the Motor class definition and its constructor:

class Motor:

def __init__(self, pi, enable_gpio, logic_1_gpio, logic_2_gpio):

self.pi = pi
self.enable_gpio = enable_gpio
self.logic_1_gpio = logic_1_gpio
self.logic_2_gpio = logic_2_gpio

pi.set_PWM_range(self.enable_gpio, 100) # speed is 0..100 # (1)

# Set default state - motor not spinning and
# set for right direction.
self.set_speed(0) # Motor off # (2)
self.right()

At line 1, we are defining the PiGPIO PWM duty cycle range for the enable pin to be in the range 0..100. This defines the maximum range value (that is, 100) that we can use with the set_speed() function that we'll come to shortly.

The range 0..100 means we have 101 discrete integer PWM steps, which maps conveniently to a 0% to 100% duty cycle. If you specify a higher number, this does not mean more duty cycles (or more motor speed); it just changes the granularity...

Introduction to stepper motor control

Stepper motors are a unique type of motor in terms of their precision and torque. Similar to a DC motor, a stepper motor can rotate in both directions continuously, while they can be precisely controlled similar to a servo.

In the following diagram is a 28BYJ-48 stepper motor, together with headpins that can be used to connect the motor to a breadboard:

Figure 10.10 – 28BYJ-48 stepper motor

Stepper motor theory and practice can get complex quickly! There are different forms and types of stepper motors and many variables, such as stride angles and gearing, that all need to be accounted for, plus various ways to wire and control them. We can't possibly cover all these parameters here, nor can we go into the low-level details of how stepper motors work.

Instead, we will cover the practical operation of a common and readily available stepper motor, a 28BYJ-48. Once you understand the basic principles as they apply to a ...

Connecting the stepper motor to the L293D circuit

To connect our stepper motor to our Raspberry Pi, we are going to reuse our L293D circuit, as shown in Figure 10.8 in the previous section. Here is what we need to do:

Figure 10.11 – 28BYJ-48 stepper motor wiring connection

The following steps match the numbering shown in Figure 10.11. Remember that we are starting with the circuit you completed previously in the section entitled Building the motor driver circuit and shown in Figure 10.8:

In steps 2 through 5, we will connect the stepper motor in our breadboard circuit. A suggestion is to use header pins (as pictured in Figure 10.10) to connect your motor to a run of vacant rows on your breadboard, and then connect the output wires from the L293D to the appropriate row matching the wire colors mentioned in the steps.
  1. If you have not done so already, disconnect the two DC motors from the existing circuit.
  2. Connect the orange wire...

Running and exploring the stepper motor code

The code we are about to run can be found in the chapter10/stepper.py file. I recommend reviewing the source code before proceeding so that you have an overall idea of what the file contains.

When you run the code found in the chapter10/stepper.py file, your stepper motor should rotate a complete 360 degrees in one direction, and then back again.

Place a piece of tape on the shaft of your stepper motor to make it easier to see when it rotates and in what direction.

Starting at the top of the source file, we define all our GPIO variables, including our enable pins at line 1, plus variables starting at line 2 relating to our stepper motor coil wires. These wires must be identified and ordered correctly, as coil wire order matters!

CHANNEL_1_ENABLE_GPIO = 18                                # (1)
CHANNEL_2_ENABLE_GPIO = 16

INPUT_1A_GPIO = 23 # Blue Coil 1 Connected to 1Y # (2)
INPUT_2A_GPIO = 24 # Pink Coil 2 Connected...

Summary

In this chapter, you learned how to use three common types of motors to create complex movement with your Raspberry Pi – a servo motor for creating an angular moment, a DC motor with an H-Bridge driver to create direction movement and speed control, and a stepper motor for precision movement. If you have grasped the general concepts of each of these types of motors, then you deserve a pat on the back! This is an achievement. While motors are simple in principle and their movement is something we take for granted daily in everyday appliances and toys, as you have discovered, there is a lot going on behind the scenes to make that movement occur.

What you have learned in this chapter, together with the example circuits and code, provides you with a foundation that you can use to start building your own applications where movement and motion are required. A simple and fun project could be to create a program to control a robotic car or robotic arm – you'll find...

Questions

As we conclude, here is a list of questions for you to test your knowledge of this chapter's material. You will find the answers in the Assessments section of the book:

  1. Your servo does not rotate fully to the left or right. Why is this and how can you fix this?
  2. Your servo is groaning at one or both of its extreme left/right positions. Why?
  3. What advantage does an H-Bridge provide over a single transistor when controlling DC motors?
  1. You are using an L293D H-Bridge IC. You follow the instructions as per the datasheet but cannot get your motor to brake. Why?
  2. Why do your 5-volt motors spin slower when connected to an H-Bridge using an L293D compared to connecting the motor directly to a 5-volt source?
  3. You have a stepper motor that will not work – it vibrates, but will not turn. What could be the problem?
  4. Can you drive a stepper motor directly from four Raspberry Pis' GPIO pins?
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Practical Python Programming for IoT
Published in: Nov 2020Publisher: PacktISBN-13: 9781838982461
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime