Robot car drive on an Arduino Uno
Two gearbox motors on an L298N module from six Uno pins: forward, a turn, a spin on the spot and reverse, with the speed on ENA and ENB. The whole build, an Arduino Uno and 3 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Intermediate About 30 minutes to build and run. Runs in your browser. Free, and no account needed.
Build it as the Robot Car Kit: the parts in numbered bags and a booklet that checks every step. Retails for about $50, free on Mokxi.
Step by step, with the wiring and the common mistakes: Arduino L298N Motor Driver: Wiring, Jumpers and Code
What you'll learn
- Driving two DC motors with an H-bridge module
- Using one direction pair and one PWM pin per motor
- Steering a car by changing the speed of each side
- Why the driver chip keeps some of the battery voltage
- Difficulty: Intermediate
- Time: About 30 minutes
- Board: Arduino Uno R3
- Parts: 5
How it works
An L298N module drives two motors from six Uno pins. Pins 5 and 10 set the speed of the left and right side with PWM. Pins 6 and 7 set the left direction, and pins 8 and 9 set the right. The motors get power from a 7.4 V pack on the 12V terminal, and the grounds are joined.
A car has no steering. It turns by running one side slower, and it spins by running the two sides in opposite directions. The sketch repeats a fixed show: forward, a gentle left, a spin right, stop, reverse, stop.
Parts list
5 parts, plus the jumper wires. They retail for about $32; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Motor driver module, L298NIn Robot Car Kit.
- 2 × DC motorIn Robot Car Kit.
- 1 × Power, 7.4 V
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Arduino Uno R3 pin GND | Ground |
| Motor driver module, L298N pin ENB | Arduino Uno R3 pin 10 |
| Motor driver module, L298N pin IN4 | Arduino Uno R3 pin 9 |
| Motor driver module, L298N pin IN3 | Arduino Uno R3 pin 8 |
| Motor driver module, L298N pin IN2 | Arduino Uno R3 pin 7 |
| Motor driver module, L298N pin IN1 | Arduino Uno R3 pin 6 |
| Motor driver module, L298N pin ENA | Arduino Uno R3 pin 5 |
| DC motor (1) pin 2 | Motor driver module, L298N pin OUT1 |
| DC motor (1) pin 1 | Motor driver module, L298N pin OUT2 |
| Motor driver module, L298N pin 12V | 7.4 V |
| Motor driver module, L298N pin GND | Ground |
| DC motor (2) pin 1 | Motor driver module, L298N pin OUT3 |
| DC motor (2) pin 2 | Motor driver module, L298N pin OUT4 |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Robot car drive: two motors on an L298N, the way every robot car does it.
//
// pin 5 ENA, the left motor's speed (the ENA jumper is off)
// pin 10 ENB, the right motor's speed (the ENB jumper is off)
// pin 6 IN1 pin 7 IN2 the left motor's direction
// pin 8 IN3 pin 9 IN4 the right motor's direction
// L298N 12V from the battery (7.4 V here), GND to the Uno's GND,
// 5V left alone: the regulator jumper is on and it makes its own
//
// A car has no steering. It turns by running one side slower than the other,
// and it spins on the spot by running the two sides opposite ways. So the
// whole of driving is four numbers: a direction and a speed for each side.
// drive() takes them as two signed speeds, -255 to 255.
//
// # The volts the bridge keeps
//
// The L298 is a bipolar chip and keeps about 2.5 V for itself: 1.35 V in the
// high side and 1.2 V in the low side. A 7.4 V pack leaves the motors under
// 5 V, which is why the car is slower than the motors' label says. And the
// regulator on the module needs 2 V of headroom to make its 5 V, which is why
// a 6 V pack of four AA cells runs nothing at all with the jumper fitted.
//
// # Why the ENA and ENB jumpers are off
//
// Fitted, a jumper ties the enable to 5 V and the motor only has full speed.
// Pulled off, the enable is a pin, and analogWrite on it is the throttle.
const int ENA = 5;
const int IN1 = 6;
const int IN2 = 7;
const int ENB = 10;
const int IN3 = 8;
const int IN4 = 9;
void side(int en, int a, int b, int speed) {
if (speed > 0) {
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
} else if (speed < 0) {
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
speed = -speed;
} else {
// Both inputs low is a brake: the motor's own EMF is shorted out.
digitalWrite(a, LOW);
digitalWrite(b, LOW);
speed = 255;
}
analogWrite(en, speed > 255 ? 255 : speed);
}
void drive(const char *what, int left, int right, unsigned long ms) {
Serial.print("car: ");
Serial.println(what);
side(ENA, IN1, IN2, left);
side(ENB, IN3, IN4, right);
delay(ms);
}
void setup() {
const int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
for (int i = 0; i < 6; i++) {
pinMode(pins[i], OUTPUT);
digitalWrite(pins[i], LOW);
}
Serial.begin(115200);
Serial.println("Mokxi Uno: a robot car on an L298N");
}
void loop() {
drive("forward", 255, 255, 2000);
drive("gentle left: the left side slower", 110, 255, 1500);
drive("spin right on the spot", 200, -200, 1500);
drive("stop", 0, 0, 700);
drive("reverse", -255, -255, 2000);
drive("stop", 0, 0, 1000);
}
Code walkthrough
The key functions of the sketch, and what each one does.
side sketch.ino
Controls one motor. A positive speed sets the first input high and the second low. A negative speed swaps them and flips the sign. Zero sets both inputs low, which brakes the motor. Then analogWrite on the enable pin sets the speed, capped at 255.
void side(int en, int a, int b, int speed) {
if (speed > 0) {
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
} else if (speed < 0) {
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
speed = -speed;
} else {
// Both inputs low is a brake: the motor's own EMF is shorted out.
digitalWrite(a, LOW);
digitalWrite(b, LOW);
speed = 255;
}
analogWrite(en, speed > 255 ? 255 : speed);
}drive sketch.ino
Prints a label, then sets the left and right sides with side, each given a signed speed from -255 to 255. It waits for the time given, so each move lasts that long.
void drive(const char *what, int left, int right, unsigned long ms) {
Serial.print("car: ");
Serial.println(what);
side(ENA, IN1, IN2, left);
side(ENB, IN3, IN4, right);
delay(ms);
}loop sketch.ino
Calls drive for each part of the show: both sides forward at 255, left at 110 against right at 255 for a gentle turn, 200 and -200 for a spin, stop, reverse at -255, and stop again.
void loop() {
drive("forward", 255, 255, 2000);
drive("gentle left: the left side slower", 110, 255, 1500);
drive("spin right on the spot", 200, -200, 1500);
drive("stop", 0, 0, 700);
drive("reverse", -255, -255, 2000);
drive("stop", 0, 0, 1000);
}Troubleshooting
The usual mistakes with this circuit, and the fix for each.
- A motor runs at full speed and ignores the code This project
Remove the jumper on ENA or ENB. A fitted jumper ties the enable high, so PWM has no effect. - A wheel spins the wrong way This project
Swap that motor's two wires on the L298N output, or swap its two input pins. - Nothing runs on a four AA pack This project
The module's regulator needs headroom and the bridge keeps about 2.5 V. Use a higher voltage pack, like the 7.4 V one here. - The motors do not run or run weakly. Motor driver module
Check the power jumpers and supply. Motor voltage goes on the +12V terminal, and ground must join the Arduino's ground. The driver drops about 2 V, so use a supply above the motor voltage. - Speed control with analogWrite does nothing. Motor driver module
Remove the ENA and ENB jumpers and connect those pins to PWM pins. With the jumpers on, the channel is always at full speed. - The motor does not spin, or the pin gets hot or the board resets when it is wired straight to a GPIO pin. DC motor
A pin gives about 20 mA and a motor needs far more. Drive it through a transistor or motor driver, with its own supply and a shared ground. - The transistor or pin is damaged by spikes when the motor stops. DC motor
Put a flyback diode across the motor, cathode to the positive side. A motor is a coil and kicks back voltage when switched off. Add a 0.1 uF capacitor across the motor terminals to cut noise. - Upload fails or nothing runs after wiring pins 0 and 1 to a module. Arduino Uno R3
Pins 0 and 1 are the USB serial port. Move the module to other pins, or unplug it while uploading. Also check the right board is selected.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.