Published on

Controlling DC Motor With Raspberry Pi

Authors
  • avatar
    Name
    UjjwalBgn
    Twitter

Understanding the signals sent by Raspberry Pi to the Motor Driver

The Enable Pins (ENA and ENB) allow us to control the speed of the motor. This is done by using PWM (Pulse Width Modulation), we will use GPIO.PWM([pin_number], [frequency])function to control the speed of the motor and pwm.start([duty cycle]) to start the PWM.

In the example below we will use python to set the frequency to 100Hz, and the duty cycle is set to 50. This will make the motor run at 50% speed.

en_a = 4    # Assign the GPIO pin number to the Enable A pin
pwm = GPIO.PWM(en_a, 100)
pwm.start(50)

We achieve 50% speed by sending 100 signals in 1 second to the motor driver, out of which 50 of the signals will be ON, and 50 will be OFF.

Duty Cycle Examples

Input pins (IN1, IN2, IN3, IN4) control the direction in which the motor will spin. Their values are assigned as high and low. Lets say IN1 is high and IN2 is low ,motor will spin one direction. Now if we switch their value the motors will spin the opposite direction.

Suppose the following code spins the motor clockwise.

GPIO.output(in1,GPIO.HIGH)
GPIO.output(in2,GPIO.LOW)

Now switching the LOW and HIGH would spin the motor anticlockwise.

GPIO.output(in1,GPIO.LOW)
GPIO.output(in2,GPIO.HIGH)

Having both values as LOW would stop the motor.

GPIO.output(in1,GPIO.LOW)
GPIO.output(in2,GPIO.LOW)

Wiring the Motor Driver, Motor and Pi

We start by connecting the motor driver, motor, and Raspberry Pi as shown in the picture below.

  • Pi Ground to Motor Driver Ground and Battery Ground
  • PI GPIO 4 to ENA
  • PI GPIO 17 to IN1
  • PI GPIO 27 to IN2
  • PI GPIO 5 to IN3
  • PI GPIO 6 to IN6
  • PI GPIO 13 to ENB
  • The Positive terminal of the battery to 12V or 5V input of the motor driver. (Depending on the battery voltage)
Controlling DC Motor With Raspberry Pi Wire Diagram

Code for controlling the Motor

Here is a sample code to control the motor. If the motor spins in the opposite direction, change the HIGH and LOW values or switch the position of the output wire between the motor controller and motor.

import RPi.GPIO as GPIO
from time import sleep

GPIO.setwarnings(False)

# Right Motor
in1 = 17
in2 = 27
en_a = 4
# Left Motor
in3 = 5
in4 = 6
en_b = 13


GPIO.setmode(GPIO.BCM)
GPIO.setup(in1,GPIO.OUT)
GPIO.setup(in2,GPIO.OUT)
GPIO.setup(en_a,GPIO.OUT)

GPIO.setup(in3,GPIO.OUT)
GPIO.setup(in4,GPIO.OUT)
GPIO.setup(en_b,GPIO.OUT)

q=GPIO.PWM(en_a,100)
p=GPIO.PWM(en_b,100)
p.start(75)
q.start(75)

GPIO.output(in1,GPIO.LOW)
GPIO.output(in2,GPIO.LOW)
GPIO.output(in4,GPIO.LOW)
GPIO.output(in3,GPIO.LOW)

# Wrap main content in a try block so we can  catch the user pressing CTRL-C and run the
# GPIO cleanup function. This will also prevent the user seeing lots of unnecessary error messages.
try:
# Create Infinite loop to read user input
   while(True):
      # Get user Input
      user_input = input()

      # To see users input
      # print(user_input)

      if user_input == 'w':
         GPIO.output(in1,GPIO.HIGH)
         GPIO.output(in2,GPIO.LOW)

         GPIO.output(in4,GPIO.HIGH)
         GPIO.output(in3,GPIO.LOW)

         print("Forward")

      elif user_input == 's':
         GPIO.output(in1,GPIO.LOW)
         GPIO.output(in2,GPIO.HIGH)

         GPIO.output(in4,GPIO.LOW)
         GPIO.output(in3,GPIO.HIGH)
         print('Back')

      elif user_input == 'd':
         GPIO.output(in1,GPIO.LOW)
         GPIO.output(in2,GPIO.HIGH)

         GPIO.output(in4,GPIO.LOW)
         GPIO.output(in3,GPIO.LOW)
         print('Right')

      elif user_input == 'a':
         GPIO.output(in1,GPIO.HIGH)
         GPIO.output(in2,GPIO.LOW)

         GPIO.output(in4,GPIO.LOW)
         GPIO.output(in3,GPIO.LOW)
         print('Left')

      # Press 'c' to exit the script
      elif user_input == 'c':
         GPIO.output(in1,GPIO.LOW)
         GPIO.output(in2,GPIO.LOW)

         GPIO.output(in4,GPIO.LOW)
         GPIO.output(in3,GPIO.LOW)
         print('Stop')

# If user press CTRL-C
except KeyboardInterrupt:
  # Reset GPIO settings
  GPIO.cleanup()
  print("GPIO Clean up")