In this user guide, we will learn how to control a DC motor with Raspberry Pi Pico in MicroPython by using an L298N motor driver. We will introduce you to the L298N motor driver module and then we will use it to learn some basic control of the dc motor including start, stop, backward and forward motion through our Raspberry Pi Pico board.
We have similar guides for ESP32, ESP8266, and Arduino using Arduino IDE:
- Interface L298N DC Motor Driver Module with ESP32
- Interfacing L298N DC Motor Driver Module with ESP8266 NodeMCU
- Interface L298N DC Motor Driver Module with Arduino
- MicroPython Control a DC Motor using L298N Driver with ESP32 and ESP8266
Before we start this lesson, make sure you are familiar with and have the latest version of Python3 installed in your system and set up MicroPython in your Raspberry Pi Pico. Additionally, you should have a running Integrated Development Environment(IDE) to do the programming. We will be using the same Thonny IDE as we have done previously when we learned how to blink and chase LEDs in MicroPython here:
If you are using uPyCraft IDE, you can check this getting started guide:
L298N Motor Driver Module
Dc motors can be controlled through several drivers which are widely available in the market. For this project, we will be using L298N motor driver module as it very easy and relatively inexpensive as well. It is widely used in controlling robots as we can connect up to four motors at once but if we want to control the speed and direction as well than it allows two motors to be connected. Thus, it is perfect for two wheeled robots. This module is mainly used in robotics and in controlling dc and stepping motors.
The L298N motor driver module consists of a L298N motor driver IC ,78M05 5V regulator, 5V jumper enable, power LED, heat sink, resistors and capacitors all combined in an integrated circuit. The diagram below shows all the components consisting inside the module.
The L298N Motor driver IC is powerfully built with a big heat sink. It is a dual channel H bridge motor driver which can be easily used to drive two motors.
The module also has a 78M05 5V regulator which is enabled through a jumper. Keeping the jumper intact, means the 5V regulator is enabled. If the motor power supply is less than 12V then we will power the module through the voltage regulator. The 5V pin in this case acts as an output to power the microcontroller. If the power supply is more than 12V, make sure the jumper is not intact and supply 5V power through the pin separately.
Note: If the jumper is connected, do not supply power to both the motor power supply input and the 5V power supply input.
The table shows some specifications of the L298N motor driver module:
|Driver Chip||Double H-bridge L298N|
|Maximum Motor Supply Voltage||46V|
|Maximum Motor Supply Current||2A|
Let us now look at the pinout of the module.
|VCC||This is the pin which supplies power to the motor. It is imprinted with +12V on board but can be powered between 6-12V.|
|Ground||This is the common ground pin.|
|5V||This pin supplies the power (5V) for the internal circuit (L298N IC). Will be used only if the 5V enable jumper is not intact. If jumper is intact, then it acts as an output pin.|
|ENA||This pin controls the speed of the motor A by enabling the PWM signal.|
|IN1 & IN2||These are the input pins for motor A. They control the spinning direction for that particular motor.|
|IN3 & IN4||These are the input pins for motor B. They control the spinning direction for that particular motor.|
|ENB||This pin controls the speed of the motor B by enabling the PWM signal.|
|OUT1 & OUT2||OUT1: Positive terminal.|
OUT2: Negative terminal
These are the output pins for motor A. Motor A having voltage between 5-35V, will be connected through these two terminals.
|OUT3 & OUT4||OUT3: Positive terminal|
OUT4: Negative terminal
These are the output pins for motor B.
Controlling DC motors through L298N module and MicroPython
Let us now see the details behind controlling the dc motor through the L298N module.
There are two types of control pins found at the bottom right side of the module. One type controls the speed and the other type controls the direction of the motor.
Speed Control (ENABLE) Pins
The speed control pins labelled ENA and ENB on the module, control the speed of the dc motor and turn it ON and OFF.
ENA controls the speed of motor A and ENB controls the speed of motor B. If both of the pins are in a logic HIGH (5V) state, then both the motors are ON and spinning at maximum speed. If both of the pins are in a logic LOW (ground) state, then both the motors are OFF. Through the PWM functionality we can also control the speed of the motor. By default, there is a jumper connected on these pins which keeps these pins in a HIGH state. In order to control the speed, we need to remove the jumper and connect these terminals with the PWM pins of Raspberry Pi Pico and program them in code. The table below demonstrates the logic signals required for controlling Motor A.
|ENA Pin State||Motor Action|
If ENA is in a HIGH state, the motor is enabled and if it is in a LOW state then the motor is off.
Direction Control (INPUT) Pins
The direction control pins are the four input pins (IN1, IN2, IN3, IN4) on the module.
Through these input pins we can determine whether to move the dc motor forward or backwards. IN1 and IN2 control motor A’s spinning direction whereas IN3 and IN4 control motor B’s spinning direction. The table below shows the logic signals required for the appropriate spinning action for motor A.
As seen from the table, whenever one of the inputs is in a HIGH state (5V) then the motor will spin. Otherwise, when both the inputs are LOW (ground) state or both are in HIGH state then the motor stops. In order for motor A to spin forward, IN1 should be LOW and IN2 should be HIGH. For backwards motion, IN1 should be HIGH and IN2 should be LOW. Motor B is also controlled in a similar way.
Interfacing DC Motor & L298N motor Driver with Raspberry Pi Pico
Now, as we have seen how to control the dc motor through the motor driver, let us do a demonstration by incorporating our Raspberry Pi Pico board. You will need the following equipment.
- Raspberry Pi Pico
- L289N Motor driver Module
- Mini DC Motor
- One 9V battery
- 0.1uF capacitor
- One Switch
- Connecting Wires
Assemble the circuit as shown in the connection diagram below.
We will be using motor A output pins to control this motor. Thus, ENA will set the speed and IN1 and IN2 will set the spinning direction of the motor. GP4 is connected with ENA. GP3 and GP2 are connected with IN1 and IN2 respectively. You can choose appropriate GPIO pins when connecting the Raspberry Pi Pico board and the driver module together.
The dc motor is rated at 6-12V, and requires a large amount of current to start. This is why we will be using an external power source for the dc motor. As we can use any power source ranging from 6-12V, we will incorporate a 9V battery in our case. You can use any other power source as you please. We are using a slider switch connected with the 9V battery supply which is very helpful in cutting the power supply. This way we can turn the driver on and off without connecting and disconnecting wires manually. We have also connected a capacitor with the two terminals of the dc motor so that there are no abrupt voltage spikes. You do not need to include the switch and the capacitor as they are optional but they increase the functionality of the project.
MicroPython Script: Control DC Motor
Copy and Save the following code in your main.py to your Raspberry Pi Pico board.
The dc motor will move forwards, stop then move backwards at increasing speed infinitely.
from machine import Pin, PWM from time import sleep IN1 = Pin(3, Pin.OUT) IN2 = Pin(2, Pin.OUT) speed = PWM(Pin(4)) speed.freq(1000) while True: speed.duty_u16(10000) IN1.low() #spin forward IN2.high() sleep(5) IN1.low() #stop IN2.low() sleep(2) speed.duty_u16(20000) IN1.high() #spin backward IN2.low() sleep(5) IN1.low() #stop IN2.low() sleep(2) speed.duty_u16(30000) IN1.low() #spin forward IN2.high() sleep(5) IN1.low() #stop IN2.low() sleep(2) speed.duty_u16(40000) IN1.high() #spin backward IN2.low() sleep(5)
How the Code Works?
Start off by we will import the pin and pwm classes from the machine module as we have to deal with both. Sleep class will help in causing delays between each transition.
from machine import Pin, PWM from time import sleep
Next, we will set IN1 and IN2 pins as outputs. The first argument in the Pin() class is the pin number on which we are configuring the output. The output is on GP3 which is connected to the IN1. The second argument shows the pin mode e.g. digital input or digital output mode. As we are configuring pin 3 as the digital output we gave, specifies it as ‘Pin.Out’. This is stored in the object ‘IN1’. Similarly, we will configure GP2 as output as well. This is the IN2 pin.
IN1 = Pin(3, Pin.OUT) IN2 = Pin(2, Pin.OUT)
Next we create a PWM pin object called ‘speed’ to pass the pwm pin as a parameter. The parameter shows where the pin is connected in our case GP4.
Then we will set up the frequency of the PWM signal.
speed = PWM(Pin(4)) speed.freq(1000)
Changing Speed and Direction of Motor
Inside the infinite loop we will start by spinning the motor in the forward direction for 5 seconds. This is done by setting the IN1 pin low and IN2 high. Additionally, we will monitor the speed of the motor by changing the duty cycle of the PWM signal applied at the PWM pin.
The range of duty cycle for Raspberry Pi Pico is between 0-65535. Incrementing the duty cycle will increase the speed of the motor. We pass the duty cycle inside speed.duty_u16() to change the speed of the motor. We have used increasing duty cycle to increase the speed of the motor after every transition.
speed.duty_u16(10000) IN1.low() #spin forward IN2.high() sleep(5)
Next, we will stop the motor for 2 seconds. This is done by setting the IN1 and IN2 pins to low.
IN1.low() #stop IN2.low() sleep(2)
Next, we will spin the motor in the backwards direction for 5 seconds. This is done by setting the IN1 pin to high and IN2 pin to low.
speed.duty_u16(20000) IN1.high() #spin backward IN2.low() sleep(5)
Similarly, we will first move the motor forwards for 5 seconds, then stop for 2 seconds and then move the motor backwards for 5 seconds while increasing the speed at each transition.
while True: speed.duty_u16(10000) IN1.low() #spin forward IN2.high() sleep(5) IN1.low() #stop IN2.low() sleep(2) speed.duty_u16(20000) IN1.high() #spin backward IN2.low() sleep(5) IN1.low() #stop IN2.low() sleep(2) speed.duty_u16(30000) IN1.low() #spin forward IN2.high() sleep(5) IN1.low() #stop IN2.low() sleep(2) speed.duty_u16(40000) IN1.high() #spin backward IN2.low() sleep(5)
To test the MicroPython script for DC motor with Raspberry Pi Pico, upload the main.py file to your board.
You may like to read servo and stepper motor interfacing with Raspberry Pi Pico:
- 28BYJ-48 Stepper Motor with Raspberry Pi Pico using MicroPython
- Servo Motor with Raspberry Pi Pico using MicroPython
You may also like to read:
- DS18B20 Temperature Sensor with Raspberry Pi Pico using MicroPython
- DHT11 DHT22 with Raspberry Pi Pico using MicroPython
- HC-SR04 Ultrasonic Sensor with Raspberry Pi Pico using MicroPython
- I2C LCD Interfacing with Raspberry Pi Pico Display Text and Custom Characters
- MPU6050 with Raspberry Pi Pico (Accelerometer, Gyroscope, and Temperature)
- BME280 with Raspberry Pi Pico using MicroPython
- OLED Display with Raspberry Pi Pico using MicroPython