Lab: DC Motor Control Using an H-Bridge

Introduction

In this tutorial, you’ll learn how to control a DC motor’s direction using a DC Motor Driver.

To reverse a DC motor, you need to be able to reverse the direction of the current in the motor. The classic way to do this is using an H-bridge circuit. Though most motor driver chips these days are not in fact H-bridge circuits, the term still persists. This tutorial uses a Toshiba motor driver, the TB6612FNG, which can actually drive two DC motors. Both Sparkfun, Adafruit, and Pololu make breakout boards for thie motor driver, though the Sparkfun one is shown in the examples below.

If you simply want to turn a motor on and off, and don’t need to reverse it, for example if you’re controlling a fan, try the tutorial on controlling high current loads with transistors.

What You’ll Need to Know

To get the most out of this lab, you should be familiar with the following concepts. You can check how to do so in the links below:

Things You’ll Need

Figures 1-9 below are the parts you’ll need for this exercise. Click on any image for a larger view.

Photo of an Arduino Nano 33 IoT module. The USB connector is at the top of the image, and the physical pins are numbered in a U-shape from top left to bottom left, then from bottom right to top right.
Figure 1. Microcontroller. Shown here is an Arduino Nano 33 IoT
Photo of flexible jumper wires
Figure 2. Jumper wires.  You can also use pre-cut solid-core jumper wires.
Photo of a solderless breadboard
Figure 3. A solderless breadboard
Photo of a Motor Driver (H-bridge), model TB6612FNG
Figure 4. Motor Driver (H-bridge), model TB6612FNG.
Photo of a toggle switch. This is a panel-mount switch, meant to be mounted in an instrument panel. It is about 0.5 in (2cm) long and has two wires protruding from it.
Figure 5. A toggle switch. You could use a pushbutton as well, but for the example below, a toggle switch is a better user interface.
Photo of a DC Gearmotor
Figure 6. DC Gearmotor. Any DC motor in the 3-15V DC range will work in with this circuit, though 4-6V is an ideal range.
Photo of a handful of 10-kilohm resistors
Figure 7. 10-kilohm resistors. These ones are 5-band resistors
A DC power jack. It pairs with a plug with a 2.1mm inside diameter, 5.5mm outside diameter plug, and has screw terminals on the back so that you can attach wires to it.
Figure 8. A DC Power Jack. This will provide the motor power input.
DC Power Supply. Shown here is a +12 Volt 1 Amp Center Positive DC power supply with a 2.1mm male jack. This size fits the Arduino Uno's female jack.
Figure 9. DC Power Supply to match your motor. If your motor is a 4-6V motor, you should use a 4-6V DC power supply.

Prepare the breadboard

Connect power and ground on the breadboard to power and ground from the microcontroller. On the Arduino module, use the 5V or 3.3V (depending on your model) and any of the ground connections, as shown in Figures 10 and 11.

An Arduino Uno on the right connected to a solderless breadboard, left. The Uno's 5V output hole is connected to the red column of holes on the far right side of the breadboard. The Uno's ground hole is connected to the blue column on the right of the board. The red and blue columns on the left of the breadboard are connected to the red and blue columns on the right side of the breadboard with red and black wires, respectively. These columns on the side of a breadboard are commonly called the buses. The red line is the voltage bus, and the black or blue line is the ground bus.

Figure 10. An Arduino Uno on the right connected to a solderless breadboard, left. The Uno’s 5V output hole is connected to the red column of holes on the far right side of the breadboard. The Uno’s ground hole is connected to the blue column on the right of the board. The red and blue columns on the right of the breadboard are connected to the red and blue columns on the left side of the breadboard with red and black wires, respectively. These columns on the side of a breadboard are commonly called the buses. The red line is the voltage bus, and the black or blue line is the ground bus.

Arduino Nano on a breadboard.

Figure 11. An Arduino Nano mounted on a solderless breadboard. The Nano is mounted at the top of the breadboard, straddling the center divide, with its USB connector facing up. The top pins of the Nano are in row 1 of the breadboard.

The Nano, like all Dual-Inline Package (DIP) modules, has its physical pins numbered in a U shape, from top left to bottom left, to bottom right to top right. The Nano’s 3.3V pin (physical pin 2) is connected to the left side red column of the breadboard. The Nano’s GND pin (physical pin 14) is connected to the left side black column. These columns on the side of a breadboard are commonly called the buses. The red line is the voltage bus, and the black or blue line is the ground bus. The blue columns (ground buses) are connected together at the bottom of the breadboard with a black wire. The red columns (voltage buses) are connected together at the bottom of the breadboard with a red wire.

Images made with Fritzing

Add a Digital Input (a switch)

Connect a switch to digital input 2 on the Arduino. Figure 12 shows the schematic, Figure 13 shows the breadboard view for the Uno, and Figure 14 the breadboard view for the Nano.

Figure 12. Schematic Diagram of a switch attached to an Arduino as a digital input. A 10-kilohm resistor connects from the switch to ground.
Breadboard view of a switch attached to an Arduino.
Figure 13. Breadboard view of a switch attached to an Arduino Uno. The Arduino is connected to a breadboard as described in the image above. A switch is mounted in three rows of the the left center section of the breadboard. A red wire connects from the left side voltage bus to the center pin of the switch. A blue wire connects either one of the side pins to digital pin 2 on the Arduino. a 10-kilohm resistor connects that same side pin to the ground bus on the left side of the board.

Breadboard view of a switch attached to an Arduino Nano.Figure 14. Breadboard view of a switch attached to an Arduino Nano. The Arduino is connected to a breadboard as described in the image above. A switch is mounted in three rows of the the right center section of the breadboard. A red wire connects from the right side voltage bus to the center pin of the switch. A blue wire connects either one of the side pins to digital pin 2 on the Arduino. a 10-kilohm resistor connects that same side pin to the ground bus on the right side of the board.

Find a motor

Find yourself a DC motor that runs on low DC voltage within the range of 3 – 15V.  The one in the Intro Physical Computing kit works well for this. Discarded toys and printers can be good sources of these also. The ITP free store is almost always a goldmine for discarded motors and fans. Asking classmates and second years is another good approach.

Solder leads to the motor’s terminals. The motor’s direction depends on the polarity, so it’s helpful to use different colors so you know which way the motor will turn when you hook it up.

Optional: Consider testing your motor with a bench power supply from the equipment room. Ask a teacher or resident if you need help setting one up. Begin by adjusting the voltage on the bench power supply and observe its effects. Take note of its speed at different voltages without dipping to low or too high.

Safety Warning: Running a motor at a voltage much lower or much higher than what it’s rated for could potentially damage or permanently destroy your motor. When the motor doesn’t spin, the voltage is too low. When the motor runs hot, or sounds like it’s straining, the voltage is too high.

Powering Your Motor

If your motor can run on 5V (if you’re using an Uno) or 3.3V (if using a Nano 33 IoT or a MKR series board) and less than 500mA, you can use the Arduino’s USB voltage. Most motors require a higher voltage and higher current draw than this, however, so you will need an external power supply. You can use any DC power supply or battery up to 15V with this motor driver as long as your motor can run at that voltage, and as long as the supply can supply as much current as your motor needs. However you choose to power this circuit, make sure the power source is compatible with your motor. For example, don’t use a 9V battery for a 3V motor.

Set up the Motor Driver

This example uses a motor driver, the This tutorial uses a Toshiba motor driver, the TB6612FNG, which can actually drive two motors.There’s a  Sparkfun breakout board, an Adafruit breakout board, and a Pololu breakout board for this part as well.

Connect the motor to the H-bridge

Connect the motor to the H-bridge as shown in Figures 18 – 20. Figure 18 shows the schematic, Figure 19 shows the breadboard view for an Uno, and Figure 20 shows the breadboard view for a Nano.

Schematic diagram of an Arduino connected to a motor driver to control a DC motor.
Figure 18. Schematic diagram of an Arduino connected to a motor driver to control a DC motor. The Arduino and switch are connected as described in the drawing above. A motor driver has been added, and is connected as follows: PWMA is connected to the Arduino’s digital pin 9. AIN1 is connected to digital pin 4. AIN2 is connected to digital pin 3 on the Arduino. AO1 and AO2 are connected to the DC motor’s two connections. The ground pins are connected to ground. VM is connected to the positive terminal of a DC power source for the motor. The power source’s negative terminal is connected to ground. The motor driver’s Vcc pin is connected to the Arduino’s voltage output (5V or 3.3V depending on your model). The Standby pin is connected to voltage through a 10-kilohm resistor. The rest of the H-bridge pins are unconnected.
Breadboard view of an Arduino connected to a motor driver to control a DC motor.
Figure 19. Breadboard drawing of an Arduino connected to a motor driver to control a DC motor. The Arduino and switch are connected as described in the breadboard drawing above. A motor driver has been added, straddling the center of the breadboard. PWMA is connected to the Arduino’s digital pin 9. AIN1 is connected to digital pin 4. AIN2 is connected to digital pin 3 on the Arduino. AO1 and AO2 are connected to the DC motor’s two connections. The ground pins are connected to ground. VM is connected to the positive terminal of a DC power source for the motor. The power source’s negative terminal is connected to ground. The motor driver’s Vcc pin is connected to the Arduino’s voltage output (5V or 3.3V depending on your model). The Standby pin is connected to voltage through a 10-kilohm resistor. The rest of the H-bridge pins are unconnected. A 100-microfarad capacitor has been added connecting the voltage and ground buses close to the motor driver, to act as a decoupling capacitor.

Breadboard view of an Arduino Nano connected to an H-bridge to control a DC motor.
Figure 20. Breadboard drawing of an Arduino Nano connected to a motor driver to control a DC motor. The Arduino and switch are connected as described in the breadboard drawing above. A motor driver has been added, straddling the center of the breadboard. PWMA is connected to the Arduino’s digital pin 9. AIN1 is connected to digital pin 4. AIN2 is connected to digital pin 3 on the Arduino. AO1 and AO2 are connected to the DC motor’s two connections. The ground pins are connected to ground. VM is connected to the positive terminal of a DC power source for the motor. The power source’s negative terminal is connected to ground. The motor driver’s Vcc pin is connected to the Arduino’s voltage output (5V or 3.3V depending on your model). The Standby pin is connected to voltage through a 10-kilohm resistor. The rest of the H-bridge pins are unconnected. A 100-microfarad capacitor has been added connecting the voltage and ground buses close to the motor driver, to act as a decoupling capacitor.

Note on decoupling capacitors

If you find that your microcontroller is resetting whenever the motor turns on, add a capacitor across power and ground close to the motor. The capacitor will smooth out the voltage dips that occur when the motor turns on. This use of a capacitor is called a decoupling capacitor. Usually a 10 – 100uF capacitor will work. The larger the cap, the more charge it can hold, but the longer it will take to release its charge.

Program the microcontroller

Program the microcontroller to run the motor through the H-bridge. First set up constants for the switch pin, the two motor driver pins, and the PWM enable pin of the motor driver. Use pin 9, one of the pins that can produce a PWM signal using analogWrite(),  for the PWM enable pin.

const int switchPin = 2;    // switch input
const int motor1Pin = 3;    // Motor driver leg 1 (pin 3, AIN1)
const int motor2Pin = 4;    // Motor driver leg 2 (pin 4, AIN2)
const int pwmPin = 9;       // Motor driver PWM pin

In the setup(), set all the pins for the motor driver as outputs, and the pin for the switch as an input. Then set the PWM enable pin high so the H-bridge can turn the motor on.

void setup() {
    // set the switch as an input:
    pinMode(switchPin, INPUT); 

    // set all the other pins you're using as outputs:
    pinMode(motor1Pin, OUTPUT);
    pinMode(motor2Pin, OUTPUT);
    pinMode(pwmPin, OUTPUT);

    // set PWM enable pin high so that motor can turn on:
    digitalWrite(pwmPin, HIGH);
  }

In the main loop() read the switch. If it’s high, turn the motor one way by taking one motor driver pin high and the other low. If the switch is low, reverse the direction by reversing the states of the two pins.

void loop() {
    // if the switch is high, motor will turn on one direction:
    if (digitalRead(switchPin) == HIGH) {
      digitalWrite(motor1Pin, LOW);   // set leg 1 of the motor driver low
      digitalWrite(motor2Pin, HIGH);  // set leg 2 of the motor driver high
    }
    // if the switch is low, motor will turn in the other direction:
    else {
      digitalWrite(motor1Pin, HIGH);  // set leg 1 of the motor driver high
      digitalWrite(motor2Pin, LOW);   // set leg 2 of the motor driver low
    }
  }

Once you’ve seen this code working, try modifying the speed of the motor using the analogWrite() function, as explained in the Analog Lab. Use analogWrite() on the PWM enable pin of the motor, and see what happens as you change the value of the analogWrite().

Get creative

This is a suggestion for a possible project. It’s not a requirement for the class homework.

Use your motor to make something move, vibrate, rise, fall, roll, creep, or whatever you can think of, in response to user input from a digital input device (switch, floor sensor, tripwire, etc). Look inside moving toys, you’ll find a number of excellent motors and gears you can re-purpose. See the innards of a cymbal monkey below as an example. Perhaps you can re-design the user interface to a toy, using the microcontroller to mediate between new sensors on the toy and the motors of the toy. Whatever you build, make sure it reacts in some way to human action.

Photo of a toy monkey. The back has been removed to reveal the inner gear mechanism that plays the cymbals. At the center of a mechanism is a DC motor. Wires have been attached to it to run the motor from an H-bridge.
The guts of a Charley Chimp™ cymbal-playing monkey.

 

Originally written on July 1, 2014 by Matt Richardson
Last modified on November 5, 2019 by Yeseul Song