Python Exemplary - RPi Tutorial
deutsch     english    

DC MOTORS

The source code of all examples can be downloaded from here.

 

DC motor control using a H-bridge

 

 

 

A DC motor represents a wonderful application of one of the most fundamental law of physics expressing that a moving charge, here the electrons of a current in a wire, experiences a force when a magnetic field is applied. In other word, if a current flows through a wire that near a magnet, the wire experiences a force. By the special motor construction this force is converted to a torque that turns the rotor shaft. If the current is reversed the shaft turns in the opposite direction.

To reverse the direction of the current flow, an arrangement that resembles to the letter 'H' is used, called a H-bridge is used. Its functional diagram looks like this:

 

motor1

By acting the switches, the motor input voltage at X, Y can be zero or have X+, Y- or X-, Y+ polarity.

Switches Motor
S1,S4 closed (S2, S3 open) Forward rotation
S2, S3 closed (S1, S4 open) Backward rotation
S2, S4 closed (S1, S3 open) Stop
S1, S3 closed (S2, S4 open) Stop
S1, S2, S3, S4 open Stop

Not all switch combinations are allowed, because by closing S1 and S2 or S3 and S4, you cause a short-circuit.

In electronics each side of the H-bridge is built by a current driver that pulls the output Q to either GND or VCC or let it open (3 states). The circuit has two inputs A and En (Enable) and an output Q. It is called "Half H-Bridge".

Half H-Bridge:

motor3

Truth table:

 A  En  Q
 L  H  L
 H  H  H
 L  L  open
 H  L  open

L: low, GND, Logic 0
H: high, VCC, Logic 1

The equivalent of the H-Bridge to drive the motor looks like this:

motor2

 

But since the motor is powered by the voltage between Q1 und Q2, it also stops when Q1 equals Q2. As consequence the enable inputs En1 and En2 can be constantly set to high (enable) and the motor is controlled by the two inputs A1 and A2:

Truth table:

 A1 A2 Motor
 H  L  forward
 L  H  backward
 L  L  stop
 H  H  stop

 

 

Experiment 1: Forward/backward control of two motors

 
Aim:
Attach one or two DC motors to a L293D H-Bridge and execute a motion sequence of you choice. If you do not have a motor at hand, you can simulate it by two LEDs reversely connected in parallel.

motor2

Caution: Do never connect a DC motor directly to the GPIO ports because voltage spikes occur caused by induction when the motor is switched off.

Wiring:

motor7

Program:[►]

# Motor1.py
# Motor forward & backward

import RPi.GPIO as GPIO
import time

P_MOTA1 = 18
P_MOTA2 = 22

def forward():
    GPIO.output(P_MOTA1, GPIO.HIGH)
    GPIO.output(P_MOTA2, GPIO.LOW)

def backward():        
    GPIO.output(P_MOTA1, GPIO.LOW)
    GPIO.output(P_MOTA2, GPIO.HIGH)
    
def stop():
    GPIO.output(P_MOTA1, GPIO.LOW)
    GPIO.output(P_MOTA2, GPIO.LOW)

def setup():
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(P_MOTA1, GPIO.OUT)
    GPIO.setup(P_MOTA2, GPIO.OUT)
    
print "starting"
setup()
while True:
    print "forward"
    forward()
    time.sleep(2)
    print "backward"
    backward()
    time.sleep(2)
    print "stop"
    stop()
    time.sleep(2)
Highlight program code (Ctrl+C copy, Ctrl+V paste)

Remarks:
The L293D H-Bridge has internal diodes to protect the circuit from voltage spikes caused by induction. So DC motors and solenoids (relays) can be connected without further protection.

If you use small 5-6 V motors like the Micro Metal Gear motors (from Pololu, PIROMONI and others), they may be powered by the Raspberry Pi 5V DC output (pin #2).



 

Experiment 2: Speed control with PWM

 

Aim:
Attach one or two DC motors to a LM293D motor driver and increase the forward speed in steps of 10 % duty cycle to maximum. Then do the same for a backward motion.

Consult the tutorial about LED dimming to learn how to handle PWM.

Circuitry:
Same as above.

Program:[►]

# Motor2.py
# Motor speed & direction 

import RPi.GPIO as GPIO
import time

P_MOTA1 = 18
P_MOTA2 = 22
fPWM = 50  # Hz (not higher with software PWM)

def forward(speed):
    pwm1.ChangeDutyCycle(speed)
    pwm2.ChangeDutyCycle(0)

def backward(speed):        
    pwm1.ChangeDutyCycle(0)
    pwm2.ChangeDutyCycle(speed)
    
def stop():
    pwm1.ChangeDutyCycle(0)
    pwm2.ChangeDutyCycle(0)

def setup():
    global pwm1, pwm2
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(P_MOTA1, GPIO.OUT)
    pwm1 = GPIO.PWM(P_MOTA1, fPWM)
    pwm1.start(0)
    GPIO.setup(P_MOTA2, GPIO.OUT)
    pwm2 = GPIO.PWM(P_MOTA2, fPWM)
    pwm2.start(0)
    
print "starting"
setup()
for speed in range(10, 101, 10):
    print "forward with speed", speed
    forward(speed)
    time.sleep(2)
for speed in range(10, 101, 10):
    print "backward with speed", speed
    backward(speed)
    time.sleep(2)
print "stopping"
stop()
GPIO.cleanup()    
print "done"
Highlight program code (Ctrl+C copy, Ctrl+V paste)

Remarks:
Duty cycle 0 % applies continuously GND and duty cycle 100 % VCC voltage levels.


 

Experiment 3: Motor control with rotation encoders

 

 

(to be done)