This tutorial shows how to control the direction and speed of a DC motor using an ESP32 and the L298N Motor Driver. First, we’ll take a quick look at how the L298N motor driver works. Then, we’ll show you an example of how to control the speed and direction of a DC motor with the L298N motor driver using the ESP32 programmed with Arduino IDE.
Updated 11 June 2024
Note: there are many ways to control a DC motor. We’ll be using the L298N motor driver. This tutorial is also compatible with similar motor driver modules.
Table of Contents
This tutorial covers the following topics:
- Introducing the L298N Motor Driver
- L298N Motor Driver Pinout
- Control DC Motors with the L298N
- Control DC Motor with ESP32 – Speed and Direction
- Wiring a DC Motor to the ESP32 (L298N Motor Driver)
- Code: ESP32 with a DC Motor – Control Speed and Direction
Are you using an ESP8266? Follow this tutorial instead: ESP8266 NodeMCU with DC Motor and L298N Motor Driver – Control Speed and Direction (Arduino IDE)
Prerequisites
Before proceeding, make sure you check the following prerequisites:
ESP32 with Arduino IDE
We’ll program the ESP32 using Arduino IDE. So, make sure you have the ESP32 add-on installed. Follow the next tutorial if you haven’t already:
Alternatively, you may also want to program the ESP32 using VS Code and the platformIO extension:
Parts Required
To complete this tutorial you need the following parts:
- ESP32 DOIT DEVKIT V1 Board – read ESP32 Development Boards Review and Comparison
- Mini DC motor
- L298N motor driver
- Power source: 4x 1.5 AA batteries or Bench power supply
- 100nF ceramic capacitor (optional)
- 1x SPDT slide switch (optional)
- Jumper wires
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Introducing the L298N Motor Driver
There are several ways to control a DC motor. The method we’ll use here is suitable for most hobbyist motors, that require 6V or 12V to operate.
We’re going to use the L298N motor driver that can handle up to 3A at 35V. Additionally, it allows us to drive two DC motors simultaneously, which is perfect for building a robot.
The L298N motor driver is shown in the following figure:
L298N Motor Driver pinout
Let’s take a look at the L298N motor driver pinout and see how it works.
The motor driver has a two-terminal block on each side for each motor. OUT1 and OUT2 at the left and OUT3 and OUT4 at the right.
- OUT1: DC motor A + terminal
- OUT2: DC motor A – terminal
- OUT3: DC motor B + terminal
- OUT4: DC motor B – terminal
At the bottom, you have a three-terminal block with +12V, GND, and +5V. The +12V terminal block is used to power up the motors. The +5V terminal is used to power up the L298N chip. However, if the jumper is in place, the chip is powered using the motor’s power supply and you don’t need to supply 5V through the +5V terminal.
Important: despite the +12V terminal name, you can supply any voltage between 5V and 35V (but 6V to 12V is the recommended range).
Note: if you supply more than 12V, you need to remove the jumper and supply 5V to the +5V terminal.
In this tutorial, we’ll use 4 AA 1.5V batteries that combined output approximately 6V, but you can use any other suitable power supply. For example, you can use a bench power supply to test this tutorial.
In summary:
- +12V: The +12V terminal is where you should connect the motor’s power supply
- GND: power supply GND
- +5V: provide 5V if jumper is removed. Acts as a 5V output if jumper is in place
- Jumper: jumper in place – uses the motor power supply to power up the chip. Jumper removed: you need to provide 5V to the +5V terminal. If you supply more than 12V, you should remove the jumper
At the bottom right you have four input pins and two enable terminals. The input pins are used to control the direction of your DC motors, and the enable pins are used to control the speed of each motor.
- IN1: Input 1 for Motor A
- IN2: Input 2 for Motor A
- IN3: Input 1 for Motor B
- IN4: Input 2 for Motor B
- EN1: Enable pin for Motor A
- EN2: Enable pin for Motor B
There are jumper caps on the enable pins by default. You need to remove those jumper caps to control the speed of your motors. Otherwise, they will either be stopped or spinning at the maximum speed.
Control DC motors with the L298N Motor Driver
Now that you’re familiar with the L298N Motor Driver, let’s see how to use it to control your DC motors.
Enable pins
The enable pins are like an ON and OFF switch for your motors. For example:
- If you send a HIGH signal to the enable 1 pin, motor A is ready to be controlled and at the maximum speed;
- If you send a LOW signal to the enable 1 pin, motor A turns off;
- If you send a PWM signal, you can control the speed of the motor. The motor speed is proportional to the duty cycle. However, note that for small duty cycles, the motors might not spin, and make a continuous buzz sound.
SIGNAL ON THE ENABLE PIN | MOTOR STATE |
---|---|
HIGH | Motor enabled |
LOW | Motor not enabled |
PWM | Motor enabled: speed proportional to the duty cycle |
Input pins
The input pins control the direction the motors are spinning. Input 1 and input 2 control motor A, and input 3 and 4 control motor B.
- If you apply LOW to input1 and HIGH to input 2, the motor will spin forward;
- If you apply power the other way around: HIGH to input 1 and LOW to input 2, the motor will rotate backwards. Motor B can be controlled using the same method but applying HIGH or LOW to input 3 and input 4.
For example, for motor A, this is the logic:
Direction | Input 1 | Input 2 | Enable 1 |
Forward | 0 | 1 | 1 |
Backwards | 1 | 0 | 1 |
Stop | 0 | 0 | 0 |
Controlling 2 DC Motors – ideal to build a robot
If you want to build a robot car using 2 DC motors, these should be rotating in specific directions to make the robot go left, right, forward, or backward.
For example, if you want your robot to move forward, both motors should be rotating forward. To make it go backward, both should be rotating backward.
To turn the robot in one direction, you need to spin the opposite motor faster. For example, to make the robot turn right, enable the motor at the left, and disable the motor at the right. The following table shows the input pins’ state combinations for the robot directions.
DIRECTION | INPUT 1 | INPUT 2 | INPUT 3 | INPUT 4 |
---|---|---|---|---|
Forward | 0 | 1 | 0 | 1 |
Backward | 1 | 0 | 1 | 0 |
Right | 0 | 1 | 0 | 0 |
Left | 0 | 0 | 0 | 1 |
Stop | 0 | 0 | 0 | 0 |
Recommended reading: Build Robot Car Chassis Kit for ESP32, ESP8266, Arduino, etc…
Control DC Motor with ESP32 – Speed and Direction
Now that you know how to control a DC motor with the L298N motor driver, let’s build a simple example to control the speed and direction of one DC motor.
Wiring a DC Motor to the ESP32 (L298N Motor Driver)
The motor we’ll control is connected to the motor A output pins, so we need to wire the ENABLEA, INPUT1, and INPUT2 pins of the motor driver to the ESP32. Follow the next schematic diagram to wire the DC motor and the L298N motor driver to the ESP32.
LN298N Motor Driver | Input 1 | Input 2 | Enable | GND |
ESP32 | GPIO 27 | GPIO 26 | GPIO 14 | GND |
We’re using the GPIOs on the previous table to connect to the motor driver. You can use any other suitable GPIOs as long as you modify the code accordingly. Learn more about the ESP32 GPIOs: ESP32 Pinout Reference Guide.
Powering the LN298N Motor Driver
The DC motor requires a big jump in current to move, so the motors should be powered using an external power source from the ESP32. As an example, we’re using 4AA batteries, but you can use any other suitable power supply. In this configuration, you can use a power supply with 6V to 12V.
The switch between the battery holder and the motor driver is optional, but it is very handy to cut and apply power. This way you don’t need to constantly connect and then disconnect the wires to save power.
We recommend soldering a 0.1uF ceramic capacitor to the positive and negative terminals of the DC motor, as shown in the diagram to help smooth out any voltage spikes. (Note: the motors also work without the capacitor.)
Code: ESP32 with a DC Motor – Control Speed and Direction
The following code controls the speed and direction of the DC motor. This code might not have a practical application in the real world but is a great example to understand how to control the speed and direction of a DC motor with the ESP32.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-dc-motor-l298n-motor-driver-control-speed-direction/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
// Motor A
int motor1Pin1 = 27;
int motor1Pin2 = 26;
int enable1Pin = 14;
// Setting PWM properties
const int freq = 30000;
const int pwmChannel = 0;
const int resolution = 8;
int dutyCycle = 200;
void setup() {
// sets the pins as outputs:
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
pinMode(enable1Pin, OUTPUT);
// configure LEDC PWM
ledcAttachChannel(enable1Pin, freq, resolution, pwmChannel);
Serial.begin(115200);
// testing
Serial.print("Testing DC Motor...");
}
void loop() {
// Move the DC motor forward at maximum speed
Serial.println("Moving Forward");
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, HIGH);
delay(2000);
// Stop the DC motor
Serial.println("Motor stopped");
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
delay(1000);
// Move DC motor backwards at maximum speed
Serial.println("Moving Backwards");
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
delay(2000);
// Stop the DC motor
Serial.println("Motor stopped");
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
delay(1000);
// Move DC motor forward with increasing speed
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
while (dutyCycle <= 255){
ledcWrite(enable1Pin, dutyCycle);
Serial.print("Forward with duty cycle: ");
Serial.println(dutyCycle);
dutyCycle = dutyCycle + 5;
delay(500);
}
dutyCycle = 200;
}
Upload the code to your ESP32. Make sure you have the right board and COM port selected. Let’s take a look at how the code works.
Declaring motor pins
First, you define the GPIOs the motor pins are connected to. In this case, Input 1 for motor A is connected to GPIO 27, the Input 2 to GPIO 26, and the Enable pin to GPIO 14.
int motor1Pin1 = 27;
int motor1Pin2 = 26;
int enable1Pin = 14;
Setting the PWM properties to control the speed
As we’ve seen previously, you can control the DC motor speed by applying a PWM signal to the enable pin of the L298N motor driver. The speed will be proportional to the duty cycle. To use PWM with the ESP32, you need to set the PWM signal properties first.
const int freq = 30000;
const int pwmChannel = 0;
const int resolution = 8;
int dutyCycle = 200;
In this case, we’re generating a signal of 30000 Hz on channel 0 with an 8-bit resolution. We start with a duty cycle of 200 (you can set a duty cycle value from 0 to 255).
For the frequency we’re using, when you apply duty cycles smaller than 200, the motor won’t move and will make a weird buzz sound. So, that’s why we set a duty cycle of 200 at the start.
Note: the PWM properties we’re defining here are just an example. The motor works fine with other frequencies.
setup()
In the setup(), you start by setting the motor pins as outputs.
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
pinMode(enable1Pin, OUTPUT);
You need to configure an LEDC pin with the PWM properties you’ve defined earlier by using the ledcAttachChannel() function that accepts as arguments the pin you want to control, the frequency, the resolution, and the pwmChannel as follows:
// configure LEDC PWM
ledcAttachChannel(enable1Pin, freq, resolution, pwmChannel);
Moving the DC motor forward
In the loop() is where the motor moves. The code is well commented on what each part of the code does. To move the motor forward, you set input 1 pin to LOW and input 2 pint to HIGH. In this example, the motor speeds forward for 2 seconds (2000 milliseconds).
// Move the DC motor forward at maximum speed
Serial.println("Moving Forward");
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, HIGH);
delay(2000);
Moving the DC motor backwards
To move the DC motor backwards you apply power to the motor input pins the other way around. HIGH to input 1 and LOW to input 2.
// Move DC motor backwards at maximum speed
Serial.println("Moving Backwards");
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
delay(2000);
Stop the DC motor
To make the DC motor stop, you can either set the enable pin to LOW, or set both input 1 and input 2 pins to LOW. In this example, we’re setting both input pins to LOW.
// Stop the DC motor
Serial.println("Motor stopped");
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
delay(1000);
Controlling the DC motor speed
To control the DC motor speed, we need to change the PWM signal duty cycle. For that you use the ledcWrite() function that accepts as arguments the GPIO that outputs the signal and the duty cycle, as follows.
ledcWrite(enable1Pin, dutyCycle);
In our example, we have a while loop that increases the duty cycle by 5 in every loop.
// Move DC motor forward with increasing speed
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
while (dutyCycle <= 255){
ledcWrite(enable1Pin, dutyCycle);
Serial.print("Forward with duty cycle: ");
Serial.println(dutyCycle);
dutyCycle = dutyCycle + 5;
delay(500);
}
When the while condition is no longer true, we set the duty cycle to 200 again.
dutyCycle = 200;
Watch the Video Demonstration
Watch the next video to see the project in action:
Wrapping Up
In this tutorial,l we’ve shown you how to control the direction and speed of a DC motor using an ESP32 and the L298N motor driver. In summary:
- To control the direction the DC motor is spinning you use the input 1 and input 2 pins;
- Apply LOW to input 1 and HIGH to input 2 to spin the motor forward. Apply power the other way around to make it spin backward;
- To control the speed of the DC motor, you send a PWM signal to the enable pin. The speed of the DC motor is proportional to the duty cycle.
We hope you’ve found this tutorial useful.
This is an excerpt from our course: Learn ESP32 with Arduino IDE. If you like ESP32 and want to learn more about it, we recommend enrolling in Learn ESP32 with Arduino IDE course.
Learn more about the ESP32 with our resources:
- Learn ESP32 with Arduino IDE (eBook)
- Build Web Servers with ESP32 and ESP8266 (eBook)
- Firebase Web App with ESP32 and ESP8266 (eBook)
- SMART HOME with Raspberry Pi, ESP32, and ESP8266
- Free ESP32 Projects and Tutorials…
Thanks for reading.
Couldn’t you use two PWM channels to drive the H-bridges? Should give you smoother control.
Hi Alan.
Yes, you can use two PWM channels. For example, one controls one motor, and the other channel the other motor.
Or you can use the same PWM channel for both motors if you want them to have a similar behavior.
this is my program to control two motors, i use L293D motor driver, but the motor couldn’t spin in the same time. the first motor spin and stop, then the second motor start and not stop, please help me how to spin motor in the same time. im sorry for my bad english.
{
digitalWrite(leftForward,HIGH);
digitalWrite(leftBackward,LOW);
digitalWrite(rightForward,HIGH);
digitalWrite(rightBackward,LOW);
while (dutyCycle <= 255){
ledcWrite(ledChannel1, dutyCycle);
ledcWrite(ledChannel2, dutyCycle);
dutyCycle = dutyCycle + 5;
delay(500);
}
dutyCycle = 100;
}
Hi Evan.
Change one of the motors red wire with the black wire, when connecting to L293D motor driver.
For example, connect motor A red wire to OUT2 and the black wire to OUT1, and see what you get.
I hope this helps.
Regards
Sara 🙂
Please tell me the code you are using it does not look like Arduino C+?
Thanks, Bob
Hi, how do i set a 16bit resolution to drive two motors, how do I decide the frequency?
Hello Surya,
You can set the bit resolution in your sketch in that line:
const int resolution = 8;
I recommend trying different frequencies and read the datasheet for your particular motor to find the best frequency. With these types of motors we usually use a frequency between 2000-40000 Hz
I hope this helps. Regards,
Rui
Hi, I can’t figure out how to PWM modulate speed on 2 channels. Whatever I tried, only one channel changes speed.
I’m copying samples of my sketch below, knowing that I’m only asking if according to you this should work and, if not, why. It’s kinda frustrating to be back to square one with ESP32! lol
Thanks in advance.
Here is the code I’m using:
[code]
// Setting PWM properties
const int freq = 40000;
const int pwmChannelL = 0;
const int pwmChannelR = 1;
const int resolution = 8;
(…)
// configure LED PWM functionalitites
ledcSetup(pwmChannelL, freq, resolution);
ledcSetup(pwmChannelR, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(ENABLE_LEFT, pwmChannelL);
ledcAttachPin(ENABLE_RIGHT, pwmChannelR);
(…)
int dutcycl = SLOW; // sartpoint
if (SpeedReqST > reqSpeed) { // if ST requested a speed greater than the last one registered by fwd() or here
while (dutcycl <= SpeedReqST) {
ledcWrite(pwmChannelL, dutcycl);
ledcWrite(pwmChannelR, dutcycl);
// Serial.print("Forward with duty cycle: ");
// Serial.println(dutcycl);
dutcycl += 1;
delay(100);
}
}
else if (SpeedReqST = SpeedReqST) {
ledcWrite(pwmChannelL, dutcycl);
ledcWrite(pwmChannelR, dutcycl);
// Serial.print(“Forward with duty cycle: “);
// Serial.println(dutcycl);
dutcycl -= 1;
delay(100);
}
}
// update last value
reqSpeed = SpeedReqST;
[/code]
Hi.
Which GPIOs are you using to control the motors? Make sure you are not using “Input only GPIOs”.
If you want both motors to have the same behavior, you can attach both enable pins to the same channel. Then, you just need to control one channel and both motors will work similarly.
Regards,
Sara 🙂
Thank you for your answer! Actually it was a problem with my encoders management code, which was systematically reducing pwm on one channel, continuously… pure coding mistake, in a library I had forgotten to correct… :p
Thanks again Sara.
many many thanks fpr the great tutorial – would love to see a port to mycropython . d o you thnk taht this is possible
love to hear from you
greetings
Hi Martin.
What do you mean by “port to micropython”?
We’re working on a tutorial for the L298N with ESP8266 and ESP32 with MicroPython.
It is not published yet, but it will be published soon.
Regards,
Sara
Hi which pin of esp32 can be connected to motor driver if we use two motor (Motor A&B)? I tried to connect many pin of esp32 for two motor but doesn’t work.how to code PWM
to control two motor?
Hi Tracy.
Any output pin of the ESP32 can connect to the motor driver (except input-only pins). Read the GPIO reference guide for more information: https://randomnerdtutorials.com/esp32-pinout-reference-gpios/
You can connect the following pins, for example:
IN1: GPIO27
IN2: GPIO 26
ENA (enable pin for motor A): GPIO 14
IN3: GPIO 33
IN4: GPIO 25
ENB (enable pin for motor B): GPIO 32
To learn more about PWM with the ESP32, you can read the following tutorial: https://randomnerdtutorials.com/esp32-pwm-arduino-ide/
I hope this helps.
Regards,
Sara
Thanks Sara
Hey tracy you succeed move 2 dc motor?
Hi Sara,
I tried with this modified code below but only my left motor works . There is no movement in my right motor. Is that any problem in my code? Can help?
// Motor A
int LM1 = 27;
int LM2 = 26;
int ENA = 14;
//Motor B
int RM1 = 33;
int RM2 = 25;
int ENB= 32;
// Setting PWM properties
const int freq = 30000;
const int pwmChannelLM = 0;
const int pwmChannelRM = 1;
const int resolution = 8;
int dutyCycle = 200;
void setup() {
// sets the pins as outputs:
pinMode(LM1, OUTPUT);
pinMode(LM2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(RM1, OUTPUT);
pinMode(RM2, OUTPUT);
pinMode(ENB, OUTPUT);
// configure LED PWM functionalitites
ledcSetup(pwmChannelLM, freq, resolution);
ledcSetup(pwmChannelRM, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(ENA, pwmChannelLM);
ledcAttachPin(ENB, pwmChannelRM);
Serial.begin(115200);
// testing
Serial.print(“Testing DC Motor…”);
}
void loop() {
// Move the DC motor forward at maximum speed
Serial.println(“Moving Forward”);
digitalWrite(LM1, LOW);
digitalWrite(LM2, HIGH);
digitalWrite(RM1, LOW);
digitalWrite(RM2, HIGH);
delay(2000);
// Stop the DC motor
Serial.println(“Motor stopped”);
digitalWrite(LM1, LOW);
digitalWrite(LM2, LOW);
digitalWrite(RM1, LOW);
digitalWrite(RM2, LOW);
delay(1000);
// Move DC motor backwards at maximum speed
Serial.println(“Moving Backwards”);
digitalWrite(LM1, HIGH);
digitalWrite(LM2, LOW);
digitalWrite(RM1, HIGH);
digitalWrite(RM2, LOW);
delay(2000);
// Stop the DC motor
Serial.println(“Motor stopped”);
digitalWrite(LM1, LOW);
digitalWrite(LM2, LOW);
digitalWrite(RM1, LOW);
digitalWrite(RM2, LOW);
delay(1000);
// Move DC motor forward with increasing speed
digitalWrite(LM1, HIGH);
digitalWrite(LM2, LOW);
digitalWrite(RM1, HIGH);
digitalWrite(RM2, LOW);
while (dutyCycle <= 255){
ledcWrite(pwmChannelLM, dutyCycle);
ledcWrite(pwmChannelRM, dutyCycle);
Serial.print("Forward with duty cycle: ");
Serial.println(dutyCycle);
dutyCycle = dutyCycle + 5;
delay(500);
}
dutyCycle = 200;
}
Dear Tray,
I used your code on other pins of the ESP32.
Needless to say, it worked and thanks to you my project has movement.
I searched earth and land for a code that did this.
I also edited it having two dutyCycles (CycleA and B) to have each motor work at a different speed.
Thank you so much.
Hola intente mesclar el proyecto de los leds por servidor wiffi y el este y que mi carro no andaba y crei que era porque el codigo no tiene el PWM y este si pero me arroja error-
CODIGO:
#include
const char* ssid = “CowBoy”;
const char* password = “GATOSxGATOS”;
WiFiServer server(80);
String header;
…
}
Hi Martin.
What error do you get?
Can you copy the error?
Next time try to post your question in English so that our readers can understand.
Regards,
Sara
Sara what frequency for 100 duty cycle
You should be able to leave the same frequency
Hi,
Do you have a micropython example?
Hi.
At the moment, we don’t have any MicroPpython tutorial about this subject.
However, it can be easily adapted to MicroPython if you know how to use PWM.
You can follow the next tutorial: https://randomnerdtutorials.com/esp32-esp8266-pwm-micropython/
Regards,
Sara
Is there a way have the battery pack also power the esp32?
That way I just flip the on switch and every is working from one power source instead of USB and double A batteries
ssue: unable to flash micropython to esp 32: open serial error, please try again. hope to connect internet and try again.
pretty new to micropython – want to flash micropython to esp 32 ( resp 8266) board.
Quote
getting this errors all the time.
open serial error, please try again.
hope to connect internet and try again.
current version only open py txt json ini file.
hope to connect internet and try again.
hope to connect internet and try again.
any idea;
many thanks for any and all help in advance.
Hi Martin.
Next time, please try to post your question in the right blog post. This article is not related with MicroPython.
I recommend flashing micropython firmware using esptool: https://randomnerdtutorials.com/flashing-micropython-firmware-esptool-py-esp32-esp8266/
Then, I recommend using Thonny as you IDE: https://randomnerdtutorials.com/getting-started-thonny-micropython-python-ide-esp32-esp8266/
I hope this helps.
Regards,
Sara
What happens if one wants to drive a 1.5v / 3v motor?
Much below the 6v lower limit for the L298?
You have to use pwm signal in order to reduce the frequency or the motor will die soon if receives 6v constantly
Hi! thank you for your tutorial
Quote: “For the frequency we’re using, when you apply duty cycles smaller than 200, the motor won’t move and will make a weird buzz sound”
How can this be avoided? because if the resolution allows values beteween 0 and 255, by starting at 200 we lose 78% of the values and the motor is much less controllable!!
Thank you
Hello,
I am having some trouble getting my motors to spin with my ESP32 and the L298N. I believe I have narrowed down the problem to the voltage that the ESP32 is supplying to the L298N’s input pins.
Using a multimeter, I am reading an expected 3.2v when I use digitalWrite() to the ESP32’s output pin. However, when it’s attached to the motor’s input pin on the L298N, nothing happens. When I supply 5v to the input pin, the motor moves.
From the L298N’s datasheet, I see that the input voltage is from -0.3 – 7v. Would you know why my ESP32’s 3.2 is failing to drive the motor?
Thank you!
Hey guys, the L298N is ancient, dont use it.
Why? it’s literally back from 1980s.
– it needs 3 GPIOs for one motor, wtf?! (wtf= what for?)
– it uses old transistors, loosing a lot of energy (draining your batteries and reducing max voltage significantly)
– it puts that energy into heat (needing to be cooled)
– so it has a big heatsink (making that board giantic overall)
I dropped dead when i received those monsters, they are bigger than my ESP board.
I reccomend the adarfruit drv8871: can handle more Amperes, less hot, much smaller, needs 2 wires per motor, still cheap. Done.
I checked L298 spec sheet, that its nominal input voltage is 5V, but esp32 out put is only 3.3V. That means for 12V power supply we provide 10V something to motors?
Hello,
I’m trying to follow this tutorial, I did everything step-by-step, cabling everything as shown and using the same exact code.
There are 2 differences in my experiment, I’m using a 7.4V battery to power the L298N and I’m using a different motor. My motor is one of those 6V yellow motors used by robot car kits.
My problem is that it only rotates only if motor1Pin1 is set to LOW and motor1Pin2 is set to HIGH (forward direction), not if they are set opposite (backward).
I’ve connected the L298N to Arduino and the motor can rotate forward and backward.
What problem could I have with this tutorial?
Hey can i use this method – L298N for a 3.7v pump If so what are the changes
Hello,
I’m trying to use the tutorial sketch with an H brigde L193D.
One thing seems odd.
At startup, the Forward, Stopped and Backward sequences do not work. They execute only after running the Forward increase sequence. After that the sketch runs normally. Do you have any idea what the problem could be.
Thanks for your help.
Hello
It isn’t a L193D but a L293D
Reg
output of l298n is 2.5V??? I want to increase its base output voltage 3-5V to drive the motor faster?
Hello,
I don’t find much information about the frequency setting
“const int freq = XXX”
I see examples that put 40Khz and other 1Khz for very similar DC motors. Yet something will change ..
Doing some tests with the classic yellow motors for arduino I noticed that by putting a lower frequency (700 hz) the dutycicle also works at values below 100 (with 8bit = 0/255) but using 2 motors it seems to me that are more evident some speed differences between motors, while at high frequencies the motors run at equal speed.
Anyone have similar experiences?
Are there any reference parameters to choose the right frequency for different actuators?
and again …
Does the frequency value affect the motor torque?
On my side it is not working. I have removed the jumpers but no rotation
One of the shortfalls of using the L298N board is that it doesn’t use the sense pins on the L298N chip. One needs to use the bare L298N chip in order to access them. The purpose of those pins is to measure the current drawn by each motor through a shunt resistor. If you connect the hot side of that resistor to an analog input of the ESP32, you can verify that the motor is consuming the correct amount of current. No current could mean that te motor is not spinning for some reason (like a bad connection or broken motor coil), too much current would mean that the motor can’t cope with the load or is even stalling.
The only limitation is that the voltage drop across the shunt resistor must not exceed 2V (I assume that he voltage drop is at the expense of Vgs to drive the lower leg of the H-bridge).
You’re using a way too high frequency. I tell you why. Moving my experimental robot driven by two geared 12V/0,58A DC motors from an Uno to an ESP32, I had to change the PWM-part of my code and I set the PWM-frequency at 10 kHz. This resulted in motors that would hardly move if the duty cycle was reduced to about 50% and didn’t move at all for lower duty cycles. Since the default PWM frequency of an Uno is 490 Hz, I lowered it to this value. After that my motors were driving as I was used to.
Choosing a very high frequency reduces the transferred energy to the motor immense. A normal DC motor is, seen from the electronical point of view, a slow device. Compare it with a potter’s wheel of which you control the speed by giving it a firm kick once a while. Imagine the ineffectiveness to softly kick it ten times a second.
I believe it’s reasonless to choose a PWM frequency higher than about 1000 Hz for any motor whatsoever.
Hi.
Thanks for the advice.
I have to try this with a lower frequency.
Regards,
Sara
Hey Rui and Sara,
Thanks so much for this tutorial! BTW, I just used the code with an ESP32-S3 DevKitC-1 board, and the only changes required were the motor pin numbers. Unless I’m missing something, pins 26 and 27 aren’t exposed on this board. I used 12 and 13 instead, and the code worked like a charm.
Steve
That’s great!
Thanks for sharing your feedback.
Regards,
Sara
Question on your code…
When you are using the pwm function on the enable pin, you are also using a delay of 500 ms… so I’m a little bit confused, because the frequency that you are using in there is 30 kHz (period of 33.33 ns) but this whole thing is governed by the 500 ms delay, am I right?
Btw, love the site, I am controlling a lego motor with esp32 through telegram, reading all your posts.
Correction: 33.33 ms, not ns
I keep on making mistakes… sorry about that
33.33 µs (micro seconds) 0.00003333 s
Hello. I followed everything in the tutorial exactly but my motor barely even moves. When I put the jumper to the L298N to have 100% duty cycle, the motor spins as it should. But when I try to send PWM from the esp32, the motor barely turns at all. I’ve tried frequencies from as high as 30000Hz to as low as 1Hz. Although frequencies lower than 500Hz did help the motor spin slightly faster, I could never get it to spin at more than 10% speed with PWM. I’d appreciate some help.
update: the example itself works just fine, it’s when I try to incorporate it’s functionality to an ESPnow remote control code that problems arise. I’ve searched for hours but can’t find why this happens.
update 2: I just found the solution!!! It was as simple as getting rid of all the LEDC commands and replacing ledcWrite(channel, value) with analogWrite(pin, value).
By taking a look at the LEDC documentation by Espressif https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/ledc.html#:~:text=ledcWrite,duty%20for%20the%20LEDC%20channel.&text=chan%20select%20the%20LEDC%20channel,be%20set%20for%20selected%20channel.
I found that there is an “analogWrite” command for esp32 that is fully compatible with the analogWrite command for arduino UNO/NANO etc. Using this command instead worked straight away. There is a few more handy PWM-related commands on that page too.
it worked for me, im soo happy….now i need to know how to make a car controled by movil or joistick
Thanks for the great tutorial.
Just wanted to mention there is a small bug in you program.
In the code below the LOW should be connected to motor1Pin1 and the HIGH to motor1Pin2.
// Move DC motor forward with increasing speed
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
can’t I just use analogWrite(), instead of going through setting up PWM signal
The L298N has a Three-State Output. When enabled, the output has low impedance; when not enabled, it has high impedance. Consequently, if both outputs are the same and the L298N is enabled, you achieve a fast stop. On the other hand, if the L298N is not enabled and the outputs have high impedance, you experience a free-running stop.