PROJECT - CONTROLLING A MOTOR - FORWARD AND REVERSE SWITCHING
Objective: drive a small motor in forward and reverse directions without relays
You will need: Raspberry Pi with WiringPi libraries installed, a suitable DC motor, Texas Instruments L293D H-bridge IC, logic level shifter, breadboard and male-female and male-male breadboard patch cables.
This project will show you how to control the rotational direction of a small motor without using any mechanical relays. The Texas Instruments L293D dual H-bridge IC has two separate control circuits and can control two conventional DC motors or one stepper motor. In this project we use one half of the IC to drive a single DC motor.
The Raspberry Pi controls the motor by setting the voltage on two of its GPIO output pins. These in turn connect through a logic level converter to the inputs of the L293D, which controls the motor. With the two output signals from the Pi there are four possible values:
- 00 and 11 both mean stop - no output voltage
- 01 means supply current to the motor in one direction
- 10 means supply current to the motor in the opposite direction
I have tried to avoid the temptation to use forwards and reverse because these words are too prescriptive and the direction of the motor clearly depends on how you have connected it up and how you define true forward and reverse for your application. The connections between the Pi, breadboard, ICs and motor are shown here. You can find the specification for the L293D IC on the Texas Instruments website. For a more precise diagram on exactly how to connect the L293D, please have a look at here.
The colour-coding for connections is:
- black - 0V or GND
- yellow - 3.3V for the logic level converter
- red - +5V for logic
- purple - +5V for motor supply - in this instance, fed from the Pi's 5V supply, though if you were driving a 12V motor this is where you would connect an external power supply
- blue - Enable/Disable signal
- green - 2-bit control signals
In some circuits you will see the +5V logic and Enable pins connected together. This is not recommended because the output is always enabled and there could be circumstances when the IC shorts out the +5V motor supply and 0V when it switches the output polarity. It is good practice to keep the Enable pin separate so that the sequence is: disable output; switch polarity; enable output. Another reason to keep the Enable pin separate is that it operates on logic voltages of typically +5V while the supply voltage for the motor can be up to 36V.
There is an additional complication when using the Pi to control the L293D and that is that the GPIO pins output 3.3V while the L293D logic operates on 5V and requires a minimum of perhaps 3.7V. If you connect the GPIO pins to the L293D inputs directly the circuit will not work. To raise the 3V3 GPIO voltage to 5V logic levels you will need to use a logic level converter on all three inputs: enable/disable and control bits 0 and 1. These converters are purchased more easily as a single ready-to-use PCB. Prices start from about ¬£1.50 excluding P&P and are available from Adafruit, Proto-Pic and other similar suppliers. Not all boards have the same connections and so are not immediately interchangeable though the PCB labelling does seem to be reasonably consistent. The table shows a typical labelling scheme and how to connect the Pi and L293D for 3V3 to 5V conversion.
|From Raspberry Pi||Converter Board In||Converter Board Out||To L293D|
|0V GND||GND||GND||0V GND|
|Enable GPIO||LV1 or A1||HV1 or B1||Enable|
|Control bit 0||LV2 or A2||HV2 or B2||Control signal input 1|
|Control bit 1||LV3 or A3||HV3 or B3||Control signal input 2|
If you are driving a motor with significant inertia, you may find that you need to switch off the motor and allow it to stop before reversing its direction, otherwise it can act as a generator and possibly damage the IC.
You can download the C program from here. The program also includes a trap for <CTRL>C so that if the program is interrupted, the motor is switched off. Otherwise, the motor would just continue in its current state. Likewise, a trap for kill is also included so that if the program is stopped by another process, it tidies up before exiting. Strictly speaking, for portability reasons, the signal function should no longer be used and sigaction used instead.
The Raspberry Pi's pins can be referred to in several ways and you need to understand which convention you are going to use. Pins have a physical pin number that corresponds to their position on the J8 header, they also have a GPIO designation that maps to the processor and there is a WiringPi designation that creates a consistent mapping across different Raspberry Pi boards. This program uses the WiringPi numbering scheme. The rationale behind using WiringPi and conversion between the three schemes can be found at wiringpi.com/pins/.
Once you have installed the WiringPi library, use the following commands to download and compile the program:
sudo gcc rp-motor-control.c -o rp-motor-control -lwiringPi
You need to run the program as root:
By taking a copy of the program and modifying it, you can create a more useful program that controls one or more motors in response to a variety of input conditions.