Raspberry Pi - DC Motor

This tutorial instructs you how to use Raspberry Pi to control DC Motor. In detail, we will learn:

Hardware Preparation

1×Raspberry Pi 4 Model B
1×L298N Motor Driver Module
1×5V DC Motor
1×(Optional) 12V DC Motor
1×5V Power Adapter for 5V DC motor
1×DC Power Jack
1×Jumper Wires
1×(Optional) Screw Terminal Adapter for Raspberry Pi

Or you can buy the following sensor kit:

1×DIYables Sensor Kit 30 types, 69 units
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

Overview of DC Motor

DC Motor Pinout

DC Motor has two wires, the positive one being usually red and the negative one being usually black.

DC Motor pinout

How It Works

When purchasing a DC motor, it is essential to understand the voltage at which it operates. For instance, let us consider a 12V DC motor.

When you power the 12V DC motor by a 12V power source:

  • Connect 12V and GND to the positive wire and negative wire, respectively: the DC motor will rotate at maximum speed in the clockwise direction
  • Connect 12V and GND to the negative wire and positive wire, respectively: the DC motor will rotate at maximum speed in the anti-clockwise direction

As stated previously, exchanging the power pole between two wires of the DC motor will reverse its rotation. This is a way to control the direction of the DC motor, but not by manual alteration but rather through programming.

If the voltage of the power supply for a DC motor is less than 12V, it will still rotate, but not at its maximum speed. This means that by changing the voltage, we can alter the speed of the DC motor. However, this approach is not typically used due to the difficulty in controlling the voltage of the power source. Therefore, the voltage of the power source is kept constant and the speed of the DC motor is regulated by a PWM signal. The greater the duty cycle of the PWM, the faster the DC motor will rotate.

How to control DC motor

How to control DC motor using Raspberry Pi

Controlling a DC motor involves two factors: speed and direction. Raspberry Pi can produce a PWM signal, but this signal has low voltage and current, so it cannot be used to control the motor. We need to use a hardware driver between Raspberry Pi and the DC motor. The driver performs two tasks:

  • Amplifying the PWM signal from Raspberry Pi (in terms of current and voltage) for speed control
  • Receiving the control signal from Raspberry Pi to switch the polarity of the power supply for direction control.
Raspberry Pi control DC motor

※ NOTE THAT:

  • This tutorial can be used for any DC motor. We will use a 12V DC motor as an example.
  • When controlling a 5V DC motor, even though the Raspberry Pi pin outputs 5V (which is the same as the DC motor voltage), a driver is still required between the Raspberry Pi and the DC motor because the Raspberry Pi pin cannot provide enough current for the DC motor.

There are many types of chips and modules that can be used as drivers to control DC motors. In this tutorial, we will be using a module called L298N.

Overview of L298N Driver

The L298N Driver can be used to manipulate a DC motor and stepper motor. This tutorial instructs you how to utilize it to manage the DC motor.

L298N Driver Pinout

L298N Driver pinout

The L298N Driver is capable of controlling two DC motors independently simultaneously, referred to as motor A and motor B. This driver has 13 pins in total.

The common pins for both motors:

  • VCC pin: This pin provides power to the motor and can range from 5V to 35V.
  • GND pin: This pin is connected to ground (0V) and serves as a common ground.
  • 5V pin: This pin supplies power to the L298N module and can be sourced from the 5V output of a Raspberry Pi.

Motor A pins (Channel A):

  • ENA pins: These pins are used to regulate the speed of Motor A. By removing the jumper and connecting this pin to a PWM input, we can control the speed of Motor A.
  • IN1 & IN2 pins: These pins are responsible for controlling the spinning direction of Motor A. When one of them is set to HIGH and the other is set to LOW, the Motor A will spin. If both the inputs are either HIGH or LOW, the Motor A will cease to move.
  • OUT1 & OUT2 pins: These pins are connected to Motor A.

Motor B pins (Channel B):

  • When the inputs IN3 & IN4 are HIGH or LOW, the Motor B will spin and the OUT3 & OUT4 pins will provide the current to the motor.
  • ENB pins: can be used to manage the speed of Motor B. By taking out the jumper and connecting this pin to PWM input, we can control the speed of Motor B.
  • IN3 & IN4 pins: are responsible for controlling the spinning direction of Motor B. When one of them is HIGH and the other is LOW, Motor B will rotate. If both the inputs are either HIGH or LOW, the Motor B will cease to move.
  • OUT3 & OUT4 pins: are linked to Motor B. When the inputs IN3 & IN4 are HIGH or LOW, the Motor B will rotate and the OUT3 & OUT4 pins will supply the current to the motor.

The L298N driver has two input power sources:

  • One for the DC motor (VCC and GND pins) ranging from 5 to 35V.
  • One for the internal operation of the L298N module (5V and GND pins) with a voltage range of 5 to 7V.

Remove all jumpers from the L298N driver for simplicity. This is necessary as the jumpers are used for advanced uses or other purposes.

We can manage two DC motors independently simultaneously by using a Raspberry Pi and an L298N Driver. To manage each motor, we only need three pins from Raspberry Pi.

※ NOTE THAT:

The remainder of this tutorial will focus on controlling a DC motor using channel A. Similar steps can be taken to control the other DC motor.

How To Control the Speed of DC Motor via L298N Driver

It is easy to adjust the speed of a DC motor by producing a PWM signal to the ENA pin of L298N. This can be done by:

  • Connecting a Raspberry Pi pin to the ENA of L298N
  • Generating a PWM signal to the ENA pin by using the pwm.ChangeDutyCycle() function. The L298N Driver will amplify the PWM signal to the DC motor.
pwm.ChangeDutyCycle(speed) # speed is a value from 0 to 100

The speed is a range from 0 to 100. When the speed is 0, the motor will not move. When the speed is 100, the motor will rotate at its highest speed.

How To Control the Direction of DC Motor via L298N Driver

The rotation of a motor can be managed by giving a logic HIGH/LOW to IN1 and IN2 pins. The table below shows how to control the direction in both channels.

IN1 pin IN2 pin Direction
LOW LOW Motor A stops
HIGH HIGH Motor A stops
HIGH LOW Motor A spins Clockwise
LOW HIGH Motor A spins Anti-Clockwise

Accordingly:

  • Raspberry Pi for controlling motor A in a clockwise direction.
GPIO.output(IN1_PIN, GPIO.HIGH) GPIO.output(IN2_PIN, GPIO.LOW)
  • Raspberry Pi for controlling motor A in a counter-clockwise direction.
GPIO.output(IN1_PIN, GPIO.LOW) GPIO.output(IN2_PIN, GPIO.HIGH)

※ NOTE THAT:

The rotation of the motor can be reversed by connecting the OUT1 and OUT2 pins to two pins of the DC motor in an opposite manner. To do this, it is necessary to either switch the OUT1 and OUT2 pins or alter the control signal on the IN1 and IN2 pins in the code.

How To Stop DC Motor Spinning

Two methods of halting a DC motor are:

  • Reducing the speed to zero
pwm.ChangeDutyCycle(0)
  • Sets both IN1 and IN2 pins to the same value, either LOW or HIGH.
GPIO.output(IN1_PIN, GPIO.LOW) GPIO.output(IN2_PIN, GPIO.LOW)
  • Or
GPIO.output(IN1_PIN, GPIO.HIGH) GPIO.output(IN2_PIN, GPIO.HIGH)

How to control a DC motor using L298N driver.

Wiring Diagram

Take out all three jumpers from the L298N module before connecting it.

The wiring diagram between Raspberry Pi and DC Motor L298N Driver

This image is created using Fritzing. Click to enlarge image

Raspberry Pi Code

We will write Python code that runs on Raspberry Pi to do the following:

  • Increases the speed of a DC motor
  • Alters the direction
  • Decreases the speed of a DC motor
  • Halts the motor

Detailed Instructions

  • Take out all three jumpers from the L298N module.
  • Make sure you have Raspbian or any other Raspberry Pi compatible operating system installed on your Pi.
  • Make sure your Raspberry Pi is connected to the same local network as your PC.
  • Make sure your Raspberry Pi is connected to the internet if you need to install some libraries.
  • If this is the first time you use Raspberry Pi, See how to set up the Raspberry Pi
  • Connect your PC to the Raspberry Pi via SSH using the built-in SSH client on Linux and macOS or PuTTY on Windows. See to how connect your PC to Raspberry Pi via SSH.
  • Make sure you have the RPi.GPIO library installed. If not, install it using the following command:
sudo apt-get update sudo apt-get install python3-rpi.gpio
  • Create a Python script file dc_motor.py and add the following code:
# This Raspberry Pi code was developed by newbiely.com # This Raspberry Pi code is made available for public use without any restriction # For comprehensive instructions and wiring diagrams, please visit: # https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-dc-motor import RPi.GPIO as GPIO import time # Constants ENA_PIN = 25 # GPIO pin connected to the EN1 pin L298N IN1_PIN = 8 # GPIO pin connected to the IN1 pin L298N IN2_PIN = 7 # GPIO pin connected to the IN2 pin L298N # Setup GPIO.setmode(GPIO.BCM) GPIO.setup(ENA_PIN, GPIO.OUT) GPIO.setup(IN1_PIN, GPIO.OUT) GPIO.setup(IN2_PIN, GPIO.OUT) # Create PWM object pwm = GPIO.PWM(ENA_PIN, 100) # 100 Hz frequency # Main loop try: while True: # Motor A spins clockwise GPIO.output(IN1_PIN, GPIO.HIGH) GPIO.output(IN2_PIN, GPIO.LOW) # Increase speed gradually for speed in range(0, 101): pwm.ChangeDutyCycle(speed) time.sleep(0.01) time.sleep(1) # Rotate at maximum speed for 1 second in clockwise direction # Change direction to anti-clockwise GPIO.output(IN1_PIN, GPIO.LOW) GPIO.output(IN2_PIN, GPIO.HIGH) time.sleep(1) # Rotate at maximum speed for 1 second in anti-clockwise direction # Decrease speed gradually for speed in range(100, -1, -1): pwm.ChangeDutyCycle(speed) time.sleep(0.01) time.sleep(1) # Stop motor for 1 second except KeyboardInterrupt: pass finally: # Stop PWM and cleanup GPIO on program exit pwm.stop() GPIO.cleanup()
  • Save the file and run the Python script by executing the following command in the terminal:
python3 dc_motor.py

The script runs in an infinite loop continuously until you press Ctrl + C in the terminal.

You will observe:

  • The DC motor will accelerate, then rotate at its maximum speed for 1 second.
  • The direction of the DC motor will be changed.
  • The DC motor will rotate at its maximum speed in the opposite direction for 1 second.
  • The DC motor will decelerate.
  • The DC motor will remain stationary for 1 second.
  • This process will be repeated continuously.

※ NOTE THAT:

This tutorial instructs you how to adjust the speed of a DC motor in relation to its maximum speed. To control the absolute speed (rotations per second), we need to use a PID controller and an encoder. Controlling the absolute speed of the DC motor will be discussed in a different tutorial.

Video Tutorial