© Jeff Cicolani 2021
J. CicolaniBeginning Robotics with Raspberry Pi and Arduinohttps://doi.org/10.1007/978-1-4842-6891-9_6

6. Driving Motors

Jeff Cicolani1  
(1)
Pflugerville, TX, USA
 

In Chapter 4, we used the Raspberry Pi’s GPIO pins to control an LED and to receive information from an ultrasonic sensor. In Chapter 5, we looked at the Arduino and discussed why it is a better option for general GPIO functions. We connected the ultrasonic rangefinder and an LED to the Arduino and learned how to pass data between the two boards.

But that doesn’t mean we’re done with the Raspberry Pi’s GPIO header. In this chapter, we’ll use the GPIO pins to connect to a board called a motor driver, which is designed to interact with DC motors and steppers. I’ll cover some of the different types of motors and discuss what a motor driver is and why it’s important in what we do.

We will connect DC motors to the motor controller and write a small program to make them turn. As part of the sample program, we’ll look at how to control the speed and direction of the motors. We will also look at some of the properties of the specific motor controller selected for the workshop.

You may choose not to go with the suggested motor controller, so we’ll also look at a common alternative: the L298N motor driver. The driver board, which is available from many manufacturers, is designed to connect to the L298N H-bridge controller chip at its heart. But because these boards rely on PWM signals for setting speed, we’ll have to connect it through the Arduino. I’ll go over all of that toward the end of the chapter.

By the end of this workshop, you will have the final component needed to start building robots: motion. In Chapter 7, we’ll bring everything together with the chassis kit to get your robot moving.

Motors and Drivers

Before moving on to the motor controllers, let’s take a moment to look at what we are controlling. The drivers we use are designed for a simple DC motor, although they could also be used to drive steppers. Let’s take a look at drivers and motors in this section.

Types of Motors

Motors convert electrical energy into rotational energy. They come in many different types, and they power virtually everything that moves. The most common type of motor is the simple DC motor, which is even used in many of the other types of motors. For example, a servomotor is a device that incorporates a DC motor with a potentiometer, or other feedback device, and gearing to control precise motion, be it angular or directional. Other types of motors include the stepper, which uses electrical impulses to control very precise movement, and coreless motors, which rearrange the typical parts of a DC motor to improve efficiency.

DC Motors

DC motors consist of a series of coils within a magnetic field. When an electrical charge is placed on the coils, it causes the coils to spin on their shared axis. Simple motors have the coils arranged and attached around a central shaft. As the shaft and coils spin, electrical connectivity is maintained with brushes that make contact with the shaft. The shaft, in turn, protrudes from the assembly to use the rotational force to perform work. Figure 6-1 shows a typical DC motor.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig1_HTML.jpg
Figure 6-1

DC motor operation

You usually find these motors attached to gearboxes, belts, or chains that serve to amplify the torque of the motor at the cost of rotational speed. This is done because a bare DC motor can produce a lot of speed, but raw speed is rarely useful.

The motors that we are using are of this type. They are simple DC motors attached to gearboxes.

Brushless Motors

Another type of motor moves the mechanical connection to the magnets. The coils remain static. When an electrical charge is applied, the magnets spin around the coils on a common axis (see Figure 6-2). This eliminates the need for brushes, so they are called brushless motors.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig2_HTML.jpg
Figure 6-2

Brushless motor operation

In the hobby world, brushless motors are most commonly associated with multirotor aircraft. They are also used extensively in other areas where high speed and efficiency are required, such as in CNC (computer numerically controlled) spindles. You are probably familiar with Dremel tools or routers; both of these devices are types of spindles and use brushless motors.

Stepper Motors

All the motors that I discussed so far have one or more coils working off a single electrical charge. That charge can be positive or negative, changing the direction of the motor.

Stepper motors are different. Steppers use multiple coils with distinct charges (see Figure 6-3), which breaks a full rotation into multiple steps. By manipulating these charges, we can cause the motor to move to and hold position at one of the steps. This makes these motors extremely useful for finite control in applications such as CNC machines, 3D printers, and robotics.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig3_HTML.jpg
Figure 6-3

Stepper motor operation

Servos

A servo is a motor that moves to a specific angle and holds that position. They generally have a maximum rotation of 45–90 degrees in either direction. They do this by connecting a potentiometer to the final output gear. The potentiometer provides feedback to the internal control board. When the servo receives a signal, usually in the form of PWM, the motor rotates until the potentiometer and the signal balance .

Figure 6-4 shows a typical hobby servo.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig4_HTML.jpg
Figure 6-4

Common servomotor

Servos with the limiters and potentiometers removed are called continuous rotation servos. They are used in applications where torque is required. Many robots are driven by continuous rotation servos.

This is an example where one hobby greatly benefited another. The common hobby servo was originally used for hobby RC aircraft. Since most hobbyists could not afford expensive devices to control their crafts, they figured out how to bring the price down significantly. This, of course, helps us hobby roboticists .

Motor Properties

There are a few things to keep in mind about motors in our projects. The most important is the motor’s electrical properties—specifically, voltage and current.

Voltage

You’re already somewhat familiar with voltage, which is a measure of the electricity needed to operate a device. The Pi is powered by 5 volts but runs on 3.3 volts. The Arduino runs on 5 volts, supplied by the USB port of the Pi. The motors we are using run on 6 volts. It is important to keep these voltages straight. If you were to put 5 volts on a device that runs on 3.3 volts, you could damage your device.

There are devices specifically designed to help manage the voltages in your project. Voltage regulators (step-up or step-down) maintain a constant voltage. The common 7805 5 V regulator takes 6–12 volts and converts it to 5 volts. The excess energy is dissipated as heat, and they can get quite hot.

Voltage regulators are great for voltage supplies, but are of little use for translating 5 volts and 3.3 volts in devices. For this, we use a logic-level converter, which requires a reference voltage from both devices, but safely translates the voltage between devices.

So now you are aware of the differences in the voltage needs of your devices. Next, we look at amperage.

Amperage

Amperage is a measure of current, or the electrical pressure that our devices require to operate. The most common analogy is water through a pipe, where voltage is the size of the pipe and amperage is the amount of water flowing through it. I actually like to change the analogy to use rubber tubing. If you try to push too much water through a rubber tube, bad things happen.

In the electronics world, this is frequently measured in the smaller unit of milliamps, usually noted as mA. For instance, the USB port of most devices is limited to 800 mA of power. This happens to be the same amount of power used by the motors we selected; however, it does not take power spikes into account.

Voltage on a device is somewhat passive. The device uses the voltage that you provide it, never trying to draw more. Amperage is quite the opposite. A device is hungry for amperage and continues to draw what it needs until it is satisfied to do its work or exceeds the available supply.

Components and devices have a certain amount of power that they need to work. They also have a maximum amount of power that they can withstand. Since extra electrical power is converted to heat, if you exceed the maximum tolerable amperage of a device, it gets hot and dies—sometimes spectacularly.

The moral of the story is to “always pay attention to the current you are drawing.” And this does not only apply to motors. LEDs are notorious for drawing a lot of current .

Motors and Amps

Motors are notoriously power-hungry devices. They are constantly trying to fulfil their purpose: to spin. When there is no load, weight, or resistance on a motor, it spins happily at its minimum current draw. Start to add resistance, however, and the motor draws more and more current until it reaches the maximum it can draw, which is called the stall current. The stall current is essentially the amperage of a motor when the shaft is physically restrained from moving.

When a motor starts, rapidly changes direction, or encounters too much resistance to spin, the power that it consumes increases drastically. If this sudden draw is too much for the supply, something is damaged. Let’s take an 800 mA source, such as a USB jack; if the motor suddenly draws 1 amp or greater, the USB jack will probably be damaged .

Motor Drivers

Most microcontrollers, microprocessors, and electronics can only handle a small amount of current. If one pulls too much current, it starts to burn out. Because motors usually easily exceed this maximum current, you generally don’t want to connect a motor of any significant size directly to your processor. So we will use a device called a motor driver or a motor controller.

A motor controller is designed for this specific purpose. It uses the low power signal from your microcontroller to control a much larger current and/or voltage. In our case, we are using a motor controller to control 6 volts with 3.3 volts from the GPIO pins. We are doing this through a series of components that have a much larger 1.2 A (1,200 mA) current tolerance and can handle brief spikes up to 3.0 A (3,000 mA) .

Working with Motor Controllers

Let’s look at two motor controllers. The first is the DC & Stepper Motor HAT by Adafruit. This controller board is designed specifically to mount onto the Raspberry Pi. The combination of utility and convenience makes it my preferred choice for projects like ours.

The other motor controller is the L298N, which is an H-bridge IC. Although the L298N is actually a discreet component—a chip—there are many manufacturers that have built it onto a convenient breakout board. This type of board is typically being referred to when someone mentions an L298N motor controller. The one used in this book is a generic version that I found on Amazon for $5. Some of my friends said that I paid too much for it.

Adafruit DC & Stepper Motor HAT

The motor driver in this project is one from Adafruit available at www.adafruit.com/products/2348. Information on how to use it is at https://learn.adafruit.com/adafruit-dc-and-stepper-motor-hat-for-raspberry-pi. In fact, much of what we’ll be going over came from this Adafruit website.

There are several reasons why this device was selected for our robot, not the least of which is that it mounts directly to the Raspberry Pi, thus limiting the area needed for mounting electronics on the robot. As you’ll quickly learn, mounting space is at a premium on most robots, especially if you’re trying to keep it rather compact. The following are some of the other reasons to use this board:
  • It can control up to four DC motors or two stepper motors.

  • Communication is handled via the I2C serial channel, which allows multiple devices to be stacked (this is why we used the longer pins on the header).

  • Because it is using I2C, it has its own dedicated PWM module for controlling the motors, so we don’t have to rely on the PWM on the Pi proper.

  • It has four H-bridge motor control circuits with 1.2 A current, 3.0 A peak current, thermal shutdown, and internal protection diodes to protect your board.

  • There are four bidirectional motor controls with 8-bit speed control (0–255).

  • There is an easy connection with the use of terminal blocks.

  • There are ready-made Python libraries.

Some Assembly Required

The board comes in a kit and requires soldering. If you haven’t already done so, you need to assemble it before proceeding with the project. Remember, we specified longer pins for the header, so don’t use the one that came with the kit.

It’s time for soldering practice.

There are a lot of small pins (40 of them) that need to be soldered. If you’re not familiar with soldering, you need to take a moment to learn how. Although it is remarkably easy, soldering instruction is beyond the scope of this book. There are many helpful videos available on the Internet. I also strongly suggest that you find your local makerspace. There is certainly someone there who can give you a quick lesson. Figure 6-5 shows my simple soldering setup.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig5_HTML.jpg
Figure 6-5

Preparing to assemble the Motor HAT

Assembling the Motor HAT is very easy, although there is soldering involved. You can find detailed instructions for assembly on the Adafruit website at https://learn.adafruit.com/adafruit-dc-and-stepper-motor-hat-for-raspberry-pi/assembly.

For this exercise, you need a soldering iron and solder. I recommend having some flux handy, as well as something to keep the soldering tip clean. Back in school, we used a wet sponge to clean the tip, but there are better things made for the job now. Your Raspberry Pi will help too.
  1. 1.

    Mount the extended header onto the Raspberry Pi’s 40-pin header (see Figure 6-6). This helps stabilize things as you solder.

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig6_HTML.jpg
Figure 6-6

Extended stacking header on the Pi’s 40-pin GPIO

  1. 2.

    Mount the Motor HAT circuit board onto the headers (see Figure 6-7). To help hold the board at a better angle for soldering, you may want to put something to support the other side. One of the terminal blocks works well for this.

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig7_HTML.jpg
Figure 6-7

Circuit board mounted on the header

  1. 3.

    Solder the first pin.

     
  2. 4.

    Once the first pin is soldered, heat it up again and adjust the board so that it sits properly (see Figure 6-8). When the solder for the pin cools, it will hold the board at the right angle while you solder the rest of the pins. If you supported the board with a terminal block or something else so that the board is sitting straight, you may be able to skip this step.

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig8_HTML.jpg
Figure 6-8

Adjusting the placement and angle of the board

  1. 5.

    Solder the rest of the first row (see Figure 6-9). You want a nice, clean, shiny joint.

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig9_HTML.jpg
Figure 6-9

Solder the first row of pins

  1. 6.

    Rotate the board 180 degrees and solder the second row (see Figure 6-10).

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig10_HTML.jpg
Figure 6-10

Rotate the Pi and solder the remaining pins

  1. 7.

    Remove the HAT from the Pi.

     
  2. 8.

    Mount the screw terminals onto the board (see Figure 6-11).

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig11_HTML.jpg
Figure 6-11

Adding the terminal blocks to the circuit board

  1. 9.

    Use tape to hold the terminals in place while you flip the board over (see Figure 6-12).

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig12_HTML.jpg
Figure 6-12

Tape helps hold the terminal blocks on the board while you turn it over to solder them into place

  1. 10.

    Solder the terminals in place (see Figure 6-13).

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig13_HTML.jpg
Figure 6-13

Soldering the terminal pins

Once you’ve removed the tape, you are done. The Motor HAT is ready for use. Mount the HAT onto the Pi. You want to support the side with the terminals so that it doesn’t short across the HDMI housing (see Figure 6-14).
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig14_HTML.jpg
Figure 6-14

The completed board mounted on the Raspberry Pi. The orange support piece is 3D printed

Hooking Up the Motor Controller

Connecting the Motor HAT is pretty straightforward. Simply mount the board on the GPIO header of the Pi. There are a couple of things to note, however. First, be careful not to bend any of the pins on either the Raspberry Pi or the HAT. It is remarkably easy to do. The header pins on the Motor HAT are particularly susceptible to bending.

You also want to be careful not to short the terminal blocks. You’ll notice that when mounted, the solder joints are precariously close to the metal housing of the HDMI connection (see Figure 6-15). There are two easy solutions for this. The first fix (and this is what we’ll do in the workshop until you can apply the second solution) is to simply place a piece of electrical tape over the metal housings of the micro USB and HDMI connectors of the Pi. The second fix (recommended) is to get some offsets to support that side of the HAT. Spacers and screws will also do the job. The point is that you don’t want the board to sag and make contact with the housing, which would probably result in a brief light show and the destruction of both the Motor HAT and the Pi.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig15_HTML.jpg
Figure 6-15

Adafruit Motor HAT mounted on a Raspberry Pi

Once the board is mounted and safely insulated from shorting, it’s time to connect the motors. For the first tutorial, we’re only going to use one motor. The second piece of code controls two, so we might as well get them connected now.

But before we can do that, we have to prep our motors. Now, if your motors came with the leads attached, then you’re ahead of the game. If not, you’ll need to solder leads to your motor, as shown in Figure 6-16. I tend to use black and red wires of appropriate size for the motors in question. I also like to make sure that the leads on each of the motors match (the black wire goes to the same pole on each of the motors and the red to the same pole on each motor). This way I don’t have to second-guess how things are connected later.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig16_HTML.jpg
Figure 6-16

Leads soldered to motor terminals

In this case, I’m using 26 AWG-stranded wire. There are generally two types of lead wire: stranded and solid. Solid is more rigid and excellent for jumpers or situations where there isn’t going to be a lot of movement. Stranded wire consists of multiple thinner wires housed in a single sheathing. It is more flexible and ideal for applications where there will likely be movement. Stranded wire is a little harder to work with, and the ends going into the terminal blocks should be tinned or coated in solder (see Figure 6-17). This makes that end rigid, and it connects better in the terminal block.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig17_HTML.jpg
Figure 6-17

Tinned lead

The next steps connect the motors to the terminal block.
  1. 1.

    Make sure that the terminal blocks are open with the screw inside the block all the way to the top. Be sure not to remove the screw. You’ll need to use a pretty fine Phillips head screwdriver.

     
  2. 2.

    Insert one of the tinned leads into the hole on the side of the terminal block marked M1 (see Figure 6-18). It doesn’t matter which wire goes to which port, as long as both wires go to different ports for the same driver (in this case, M1).

     
  3. 3.

    Tighten the screw corresponding to the hole you inserted the wire into.

     
  4. 4.

    Repeat the procedure for the second lead from the motor.

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig18_HTML.jpg
Figure 6-18

Motor connected to the Motor HAT

At this point, if you are so inclined, you can connect the second motor as well. I tend to reverse the order of the leads since they are destined for opposite sides of the robot. You want a forward command to turn the left motor in one direction and the right motor in the other direction. If they both turn in the same direction electrically, then the robot just spins in place.

You’ll repeat the procedure for the four–AA battery pack to the power terminals. Make sure that the red lead goes to the positive (+) side and the black goes to the negative (–) side (see Figure 6-19).
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig19_HTML.jpg
Figure 6-19

External battery pack connected to the Motor HAT

Your board and motors should look similar to Figure 6-20. With both motors and the battery pack connected, you are ready to start coding!
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig20_HTML.jpg
Figure 6-20

Completed connections to the Motor HAT

Using the Motor HAT

With the Motor HAT mounted and your motors and motor power supply connected, it’s time to boot up the Pi and log on.

The Adafruit Motor HAT uses a protocol called I2C to communicate with your Raspberry Pi. I2C is a serial protocol designed to use a minimum number of pins for sending and receiving data. Generally the protocol uses a total of four pins to connect with other devices: SCL, SDA, VCC, and GND. The particulars of I2C are beyond the scope of this book, but if you want to learn more about it, check out https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/i2c-sensors-and-devices.

There are a couple of steps to get the Motor HAT working on your Pi. First, we will need to enable I2C. This and most other communications protocols are disabled by default on the Pi. Once this is done, we will install the necessary library.

Enabling I2C
To enable I2C on your Raspberry Pi, we will be using Raspberry Pi Configuration.
  1. 1.

    In the upper-left corner of the Raspberry Pi OS screen, click the raspberry logo.

     
  2. 2.

    Click Preferences and then Raspberry Pi Configuration. This will open the Raspberry Pi Configuration panel.

     
  3. 3.

    Select the Interfaces tab.

     
  4. 4.

    Click Enable for I2C.

     
  5. 5.

    Click OK.

     
Installing the Library
Once you’ve started up and connected to your Pi, you need to install the Python libraries for the Motor HAT. The Motor HAT Library has a dependency on the Adafruit_Blinka library. These are available from Adafruit, and the Adafruit_Blinka library will be installed when the HAT library is installed. For this, we’ll be using Python’s PIP function.
  1. 1.

    Open a terminal window.

     
  2. 2.

    Type sudo pip3 install adafruit-circuitpython-motorkit and press Enter.

     

At this point, your Pi is updated with the necessary libraries, and it’s time to get started with the code.

The Code

We will start with simply turning a single motor. The speed of the motor is denoted as a decimal value between 0 and 1. Zero is a dead stop, one is full speed, and half speed would be 0.5.

Turning multiple motors is a simple expansion of this, as you will see in the second sample.

Turning a Single Motor
  1. 1.

    In the Thonny IDE, create a new file and save it as motors.py.

     
  2. 2.
    Enter the following code:
    import time
    from adafruit_motorkit import MotorKit
    # create motor object
    kit = MotorKit()
    # run motor forward 1 second
    kit.motor1.throttle = 1.0
    time.sleep(1.0)
    # stop motor
    kit.motor1.throttle = 0.0
    time.sleep(0.25)
    # run motor reverse 1 second
    kit.motor1.throttle = -1.0
    time.sleep(1.0)
    # stop motor
    kit.motor1.throttle = 0.0
     
  3. 3.

    Save the file.

     
  4. 4.

    Press F5 to run the program.

     

Let’s go through the code.

We start by importing the objects we need from the Adafruit_MotorKit library and assign them aliases so we don’t have to write the whole name each time we use them. We also import the time library for our delays later in the code:
import time
from adafruit_motorkit import MotorKit
Next, we create an instance of the motor object. This lets us access the MotorKit’s methods and properties:
kit = MotorKit()
Now we wrap the remainder of the motor drive code in a while loop. As long as the value is true, this code will keep executing:
while True:
The code to drive the motor is very simple. We drive the motor forward for 1 second, stop the motor for 250 milliseconds, drive the motor backward for 1 second, and then stop the motor, again, for 250 milliseconds. The program keeps doing this until we stop it:
# run motor forward 1 second
kit.motor1.throttle = 1.0
time.sleep(1.0)
# stop motor
kit.motor1.throttle = 0.0
time.sleep(0.25)
# run motor reverse 1 second
kit.motor1.throttle = -1.0
time.sleep(1.0)
# stop motor
kit.motor1.throttle = 0.0
time.sleep(0.25)

To stop the program, press Ctrl-C on the keyboard.

Note that the program ended, but the motor continues to turn. That’s because the Motor HAT is freely running. This means that the controller continues with the last command received from the Pi. If we don’t tell it to stop, it won’t.

Now we are going to do something interesting, something we haven’t done before. We’ll wrap the motor drive code into a try/except block. It is a piece of code that allows us to capture any errors that occur and then gracefully handle them.

In this particular case, we are going to use the try/except block to capture the KeyboardInterrupt event. This event is triggered when we use Ctrl-C to exit a program.
  1. 1.
    Change the code for the while loop to read as follows:
    try:
        while True:
          # run motor forward 1 second
          kit.motor1.throttle = 1.0
          time.sleep(1.0)
          # stop motor
          kit.motor1.throttle = 0.0
          time.sleep(0.25)
          # run motor reverse 1 second
          kit.motor1.throttle = -1.0
          time.sleep(1.0)
          # stop motor
          kit.motor1.throttle = 0.0
          time.sleep(0.25)
    except KeyboardInterrupt:
        kit.motor1.throttle = 0.0
     
  2. 2.

    Run the program.

     
  3. 3.

    Let it run for a moment, and then press Ctrl-C.

     

The motor will now stop when the program exits.

Python captures the KeyboardInterrupt event and executes that last line of code before exiting. The code releases the motor and simply turns it off.

Turning Two Motors

Turning a single motor is great and dandy, but our robot is going to have two motors, and we want them to operate independently. We also want them to be able to change speed and direction.

To operate multiple motors, you simply need to create a different instance of the motor object for each motor. Assuming that you connected both of your motors earlier, we are creating two motors and giving commands to each. We are also changing both the speed and direction of the motors.
  1. 1.

    Create a new Python file from Thonny.

     
  2. 2.

    Save the file as two_motors.py.

     
  3. 3.
    Enter the following code:
    import time
    from adafruit_motorkit import MotorKit
    # create motor object
    kit = MotorKit()
    try:
        while True:
          # ramp up speed from 1 to 255
          for i in range(100):
              j = 100-i
              # run motors forward 1 second
              kit.motor1.throttle = i/100
              kit.motor2.throttle = j/100
          # stop motor
          kit.motor1.throttle = 0.0
          kit.motor2.throttle = 0.0
          time.sleep(0.25)
          for i in reversed(range(100)):
              j = 100-i
              # run motors reverse 1 second
              kit.motor1.throttle = i/100
              kit.motor2.throttle = j/100
          # stop motor
          kit.motor1.throttle = 0.0
          kit.motor2.throttle = 0.0
          time.sleep(0.25)
    except KeyboardInterrupt:
        kit.motor1.throttle = 0.0
        kit.motor2.throttle = 0.0
     
  4. 4.

    Save the file.

     
  5. 5.

    Press F5 to run the program.

     

For the most part, the code is the same. We added a few for loops to count up to 100 and back down again. We created two variables to hold this value; the second one inverts the value by subtracting it from 100. Since the throttle is a decimal value between 0 and 1, we divide the speed variable by 100. Once both motors have sped up and down again, we change direction and do it again. We use the same exit code as we did before.

L298N Generic Motor Driver

The L298N is a common H-bridge motor controller chip. Several manufacturers have mounted the chip on a board and added all the necessary support electronics. The end result is a popular, generic motor controller.

H-Bridge Motor Controller

The H-bridge motor controller is the most common motor controller that you will encounter. It gets its name from the distinctive H shape seen in the schematic. An H-bridge essentially consists of four gates that control current flow through the motor. Depending on how the gates are opened and closed, you can control the direction in which the motor spins.

On the L298N, there are two enable pins (one for each motor) and four input pins. The in1 and in2 pins control motor 1, while in3 and in4 control motor 2. Figure 6-21 shows how the gates are arranged; in1 controls S1 and S4, and in2 controls S3 and S2. When in1 or in2 is high, their respective gates are closed. When they are low, the gates are open.

When in1 is high and in2 is low, the current flows so that the motor spins clockwise. If in1 is low and in2 is high, the motor spins counterclockwise. If both pins are high, the motor does not spin, essentially putting on a brake. If both pins are low, no current is flowing through the motor, and it is spinning freely.
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig21_HTML.jpg
Figure 6-21

H-bridge motor controller operation

That leaves the enable pins, enA and enB, which are used for setting the speeds of the motors. This is why we use PWM on these pins. PWM allows us to vary the speed of each motor. If we used a standard digital pin, we could start and stop the motor, but it would be either full power or no power. PWM allows us to have more control over our motors.

Using the L298N

There are a few ways to use the L298N; each has its benefits and faults. One method is to connect the pins to the Raspberry Pi, which has the virtue of being directly controlled by the Pi. The drawbacks are that you may have to use a logic-level converter since the Pi’s pins are 3.3 volts and the controller is 5 volts. Also, you lose the ability to control the speed. Speed control requires PWM, and as I discussed in earlier chapters, that is one area where the Pi is wanting.

My preferred method for connecting to the L298N is through the Arduino. In this way, you have speed control through PWM. Also, since the Arduino and the controller are both 5 volts, there is no need to use a logic-level converter. Of course, the drawback here is that you have to pass the motor instructions via Serial to the Arduino.

Arduino Code
For this exercise, the Arduino is simply going to act as a pass-through for the motor controller. We will read the instructions from the serial stream and pass those values onto the motor controller. The Arduino will perform no logic. If you implement this in a real-world scenario, you may want the sensors to act as an interrupt. By allowing the sensors to interrupt the normal operation, you can build some safeties into the project.
  1. 1.

    Open a new sketch in the Arduino IDE.

     
  2. 2.

    Save the sketch as L298N_passthrough.

     
  3. 3.
    Enter the following code:
    int enA = 9;
    int in1 = 8;
    int in2 = 7;
    int in3 = 5;
    int in4 = 4;
    int enB = 3;
    int enAVal, in1Val, in2Val, in3Val, in4Val, enBVal;
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(enA, OUTPUT);
      pinMode(in1, OUTPUT);
      pinMode(in2, OUTPUT);
      pinMode(in3, OUTPUT);
      pinMode(in4, OUTPUT);
      pinMode(enB, OUTPUT);
    }
    void loop() {
      // Only work if there is data in the serial buffer
      while(Serial.available() > 0){
        // Read the ints from the serial port
        enAVal = Serial.parseInt();
        in1Val = Serial.parseInt();
        in2Val = Serial.parseInt();
        // Only read the next three if there is data
        if(Serial.available() > 0){
          in3Val = Serial.parseInt();
          in4Val = Serial.parseInt();
          enBVal = Serial.parseInt();
        }
        // Write the values to the L298N
        analogWrite(enA, enAVal);
        digitalWrite(in1, in1Val);
        digitalWrite(in2, in2Val);
        digitalWrite(in3, in3Val);
        digitalWrite(in4, in4Val);
        analogWrite(enB, enBVal);
        // Purge any remaining data because we don't need it
        while(Serial.available() > 0){
          char x = Serial.read();
        }
      }
    }
     
  4. 4.

    Save the sketch and upload it to the Arduino.

     

You won’t see anything happening on the Arduino. What we’ve done is load the Arduino with code that simply reads the serial port and passes the values read to the L298N.

We did a few things in this code that you want to take note of.
if(Serial.available() > 2){
The first thing to note is the if statement after we read in the value for in2Val. This code is used in both of the upcoming exercises. The first exercise will only pass three values. The second will pass six values. We only read the second three values if they exist; otherwise, we’ll get an error. To assure that we avoid the error, we only want to read the next three values if there are three or more values to read.
while(Serial.available() > 0){
  char x = Serial.read();
}

At the end of the sketch, we added a small while loop. If we have anything left in the serial buffer after reading all six values, we need to clear it out so that there is no straggling data in the buffer for the next cycle. This block simply reads all the remaining bytes and removes them from the buffer.

Hooking Up the L298N

Hooking up the motor controller is a little more complicated than just plugging it into the header. We’ll connect through the Arduino to take advantage of the PWM pins. As with the Motor HAT, we’ll provide the motor controller with external power from the four–AA battery pack. This provides the 6 volts that the motors want, without frying the Arduino.

Turning One Motor
In the first exercise with L298N, you learn how to turn a single motor. We set the motor’s speed and direction, change the direction, and vary the speed. Figure 6-22 shows the circuit for this exercise.
  1. 1.

    Connect enA on the motor controller to pin 9 on the Arduino. You may need to remove a jumper.

     
  2. 2.

    Connect in1 to pin 8.

     
  3. 3.

    Connect in2 to pin 7.

     
  4. 4.

    Connect a ground pin on the Arduino to the ground post on the screw terminal. This is likely the middle post.

     
  5. 5.

    Connect a motor to the motor controller by connecting one lead to out1 and the other to out2.

     
At the moment, it doesn’t matter which lead goes to which output post.
  1. 6.

    Connect the black lead from the battery pack to the ground terminal on the L298N.

     
  2. 7.
    Connect the red lead from the battery pack to the positive terminal. It is usually labeled + or VCC.
    ../images/457480_2_En_6_Chapter/457480_2_En_6_Fig22_HTML.jpg
    Figure 6-22

    L298N single-motor wiring

     
  1. 8.

    Open a new file in Thonny.

     
  2. 9.

    Save the file as L298N_1_motor_example.py.

     
  3. 10.
    Enter the following code:
    import serial
    import time
    direction = 1
    ser = serial.Serial("/dev/ttyACM0",9600,timeout=1)
    def driveMotor(int speed, int drct):
        enA = speed
        # determine direction
        if drct == 1:
            in1 = 1
            in2 = 0
        else if drct == -1:
            in1 = 0
            in2 = 1
        else:
            in1 = 0
            in2 = 0
        valList = str(enA) + ',' + str(in1) + ',' + str(in2)
        serString = ','.join(valList)
        ser.write(serString)
        time.sleep(0.1)
    while 1:
        # ramp up speed
        while motSpeed < 256:
            driveMotor(motSpeed, direction)
            motSpeed = motSpeed + 1
        # ramp down speed
        while motSpeed > 0:
            driveMotor(motSpeed, direction)
            motSpeed = motSpeed – 1
        # reverse direction
        direction = -direction
     
  4. 11.

    Save and run the file

     

The motor should begin spinning, getting faster until it reaches its top speed. At that time, it slows to a stop, reverses direction, and repeats. This continues until you press Ctrl-C to stop the program.

Turning Two Motors
Next, we spin two motors. The setup and code are very similar to what we just did, with an additional motor. You should already have the first motor connected. If not, complete steps 1–7 from the previous exercise. Let’s pick up with the addition of the second motor (see Figure 6-23).
  1. 1.

    Connect a lead from pin 5 on the Arduino to in3 on the motor controller.

     
  2. 2.

    Connect a lead from pin 4 to in4.

     
  3. 3.

    Connect a lead from pin 3 to enB.

     
  4. 4.

    Connect the leads from the second motor to the out2 terminals. Again, it matters very little in this exercise which lead goes to which terminal. Later, when you are mounting the motors onto the robot, you want to make sure that the motors are connected so that they turn opposite to each other. For now, however, we only care that they actually turn.

     
../images/457480_2_En_6_Chapter/457480_2_En_6_Fig23_HTML.jpg
Figure 6-23

L298N two-motor wiring

  1. 5.

    Open a new file in Thonny.

     
  2. 6.

    Save the file as L298N_2_motor_example.py.

     
  3. 7.

    Enter the following code:

     
import serial
import time
directon = 1
ser = serial.Serial("/dev/ttyACM0",9600,timeout=1)
def driveMotor(int motor, int speed, int drct):
  enA = speed
    # determine direction
    if drct == 1:
        in1 = 1
        in2 = 0
        in3 = 1
        in4 = 0
    else if drct == -1:
        in1 = 0
        in2 = 1
        in3 = 0
        in4 = 1
    else:
        in1 = 0
        in2 = 0
        in3 = 0
        in4 = 0
    valList = str(enA) + ',' + str(in1) + ',' + str(in2) + ',' + str(in3) + ',' + str(in4) + ',' + str(enB)
    serString = ','.join(valList)
    ser.write(serString)
    time.sleep(0.1)
while 1:
    # ramp up speed
    while motSpeed < 256:
        driveMotor(motSpeed, direction)
        motSpeed = motSpeed + 1
    # ramp down speed
    while motSpeed > 0:
        driveMotor(motSpeed, direction)
        motSpeed = motSpeed - 1
    # reverse direction
    direction = -direction

This code was not much different from the previous exercise. All that we did was add the enable and input variables for the second motor. Both motors should be spinning at the same speed. They speed up, slow down, and then reverse direction. Take a look at the code and determine how to get the motors to spin independently of each other.

Summary

In this chapter, we looked at the common types of motors: DC, coreless, stepper, and servo. We assembled the Adafruit DC & Stepper Motor HAT. (You should now be pretty comfortable with the soldering iron.) Then, you learned how to connect your motors to it and made them spin.

We also looked at a common, generic motor controller. The L298N works a little differently in that the direction is set by altering the state of two pins. We connected the L298N through the Arduino to take advantage of the PWM pins to control the speed of the motors, as well as the direction. We could have just as easily connected the enable pins to digital out pins on the Raspberry Pi GPIO header. However, having discrete control of the motors’ speed is important. In an upcoming chapter, you see why this is important.

At this point, you have all the information that you need to build a simple little robot. You’ve learned about programming in both Python and Arduino. You’ve worked with sensors to allow your robot to detect its surroundings. And finally, you got your motors to spin, so you have motion. Logic, sensing, and movement are the essence of every robot. Everything else is a more advanced version of these elements.

Now that you know everything you need to know about robots, we’re going to assemble the chassis kit and build a robot. After that, we jump into making our robot more capable and smarter. We will start with IR sensors, move on to control algorithms, and then give the robot eyes—well, an eye.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.63.236