Overview
The L298N is a dual H-bridge motor driver module that lets a microcontroller control up to two DC motors or one bipolar stepper motor — independently controlling direction and speed using PWM. It's the classic driver for robot cars, conveyor belts, small CNC projects, and anywhere you need to drive motors that would otherwise blow out a microcontroller's GPIO pins. The module handles up to 46V and ~2A per channel (3A peak), with a big heatsink on the STMicro L298N chip to soak up thermal loads.
The board has two terminal blocks for motor outputs (OUT1/OUT2 and OUT3/OUT4), a power input block for motor supply (5V to 35V recommended) plus a 5V logic output from the onboard 78M05 regulator, and six input pins (ENA, IN1, IN2, IN3, IN4, ENB) for control. ENA and ENB accept PWM for speed control; IN1–IN4 set direction per motor.
This manual covers specifications, the pinout, wiring for Arduino, ESP32, Raspberry Pi, and the Pico, a working DC-motor "hello world" example per platform, and FAQs on voltage drop, jumper behavior, and overheating.
At a Glance
Specifications
| Parameter | Value |
| Driver IC | STMicroelectronics L298N (dual H-bridge) |
| Motor Supply Voltage | 5V - 35V (12V typical) |
| Logic Supply Voltage | 5V (generated on-board or external) |
| Output Current (Continuous) | 2A per channel |
| Output Current (Peak) | 3A per channel |
| Voltage Drop (across H-bridge) | ~1.8 - 2V (typical) |
| Control Inputs | ENA, IN1, IN2, IN3, IN4, ENB |
| PWM Frequency Range | Up to ~25 kHz |
| Protection | Flyback diodes, thermal shutdown |
| Onboard 5V Regulator | Enabled via jumper (disable when motor supply > 12V) |
| Board Format | Screw terminals + 0.1" headers |
Pinout Diagram
Wiring Guide
Arduino Wiring
Use a separate motor supply (7–12V battery) for the 12V input, and keep the 5V-regulator jumper ON so the board powers its own logic. Connect all GNDs together.
| L298N Pin | Arduino / Source | Details |
|---|---|---|
| 12V | Battery + (7–12V) | Motor supply |
| GND | Battery − AND Arduino GND | Common ground |
| 5V | (out) to Arduino 5V | Only if jumper enabled and supply ≤ 12V |
| ENA | D9 (PWM) | Motor A speed |
| IN1 | D8 | Motor A direction |
| IN2 | D7 | Motor A direction |
| IN3 | D5 | Motor B direction |
| IN4 | D4 | Motor B direction |
| ENB | D3 (PWM) | Motor B speed |
| OUT1/OUT2 | Motor A leads | DC motor A |
| OUT3/OUT4 | Motor B leads | DC motor B |
ESP32 Wiring
The ESP32's 3.3V logic is enough to drive the L298N inputs. Use any GPIO for direction and any LEDC-capable pin for PWM.
| L298N Pin | ESP32 Pin | Details |
|---|---|---|
| 12V | Battery + | Motor supply |
| GND | Common ground | Battery − and ESP32 GND |
| ENA | GPIO 13 (LEDC/PWM) | Motor A speed |
| IN1 | GPIO 14 | Motor A direction |
| IN2 | GPIO 27 | Motor A direction |
| IN3 | GPIO 26 | Motor B direction |
| IN4 | GPIO 25 | Motor B direction |
| ENB | GPIO 33 (LEDC/PWM) | Motor B speed |
Raspberry Pi Wiring
The Pi's 3.3V GPIO output can drive the L298N inputs. Use hardware PWM pins for smoothest speed control.
| L298N Pin | Raspberry Pi Pin | Details |
|---|---|---|
| 12V | Battery + | Motor supply |
| GND | Battery − AND Pi GND (Pin 6) | Common ground |
| ENA | GPIO 12 (Pin 32, PWM) | Motor A speed |
| IN1 | GPIO 23 (Pin 16) | Motor A direction |
| IN2 | GPIO 24 (Pin 18) | Motor A direction |
| IN3 | GPIO 27 (Pin 13) | Motor B direction |
| IN4 | GPIO 22 (Pin 15) | Motor B direction |
| ENB | GPIO 13 (Pin 33, PWM) | Motor B speed |
Raspberry Pi Pico Wiring
The Pico has plenty of PWM-capable pins (any GP pin). Wire the L298N inputs to any free GP pins.
| L298N Pin | Pico Pin | Details |
|---|---|---|
| 12V | Battery + | Motor supply |
| GND | Battery − AND Pico GND | Common ground |
| ENA | GP2 (PWM) | Motor A speed |
| IN1 | GP3 | Motor A direction |
| IN2 | GP4 | Motor A direction |
| IN3 | GP5 | Motor B direction |
| IN4 | GP6 | Motor B direction |
| ENB | GP7 (PWM) | Motor B speed |
Code Examples
Arduino
// L298N - Drive 2 DC motors forward, backward, and stop
// Motor A: ENA=D9, IN1=D8, IN2=D7
// Motor B: ENB=D3, IN3=D5, IN4=D4
const int ENA = 9;
const int IN1 = 8;
const int IN2 = 7;
const int ENB = 3;
const int IN3 = 5;
const int IN4 = 4;
void setup() {
pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
pinMode(ENB, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
}
void setMotor(int enPin, int in1, int in2, int speed) {
// speed: -255 (full back) .. 255 (full fwd). 0 = stop.
digitalWrite(in1, speed > 0 ? HIGH : LOW);
digitalWrite(in2, speed < 0 ? HIGH : LOW);
analogWrite(enPin, abs(speed));
}
void loop() {
setMotor(ENA, IN1, IN2, 200); // Motor A forward ~80%
setMotor(ENB, IN3, IN4, 200); // Motor B forward ~80%
delay(2000);
setMotor(ENA, IN1, IN2, -150); // Motor A reverse ~60%
setMotor(ENB, IN3, IN4, -150);
delay(2000);
setMotor(ENA, IN1, IN2, 0); // stop
setMotor(ENB, IN3, IN4, 0);
delay(1000);
}
ESP32
// L298N on ESP32 - dual DC motors using LEDC PWM
const int ENA = 13, IN1 = 14, IN2 = 27;
const int ENB = 33, IN3 = 26, IN4 = 25;
const int PWM_FREQ = 20000, PWM_RES = 8;
void setup() {
pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
ledcAttach(ENA, PWM_FREQ, PWM_RES);
ledcAttach(ENB, PWM_FREQ, PWM_RES);
}
void motor(int enPin, int in1, int in2, int speed) {
digitalWrite(in1, speed > 0);
digitalWrite(in2, speed < 0);
ledcWrite(enPin, abs(speed));
}
void loop() {
motor(ENA, IN1, IN2, 200); motor(ENB, IN3, IN4, 200); delay(2000);
motor(ENA, IN1, IN2, -200); motor(ENB, IN3, IN4, -200); delay(2000);
motor(ENA, IN1, IN2, 0); motor(ENB, IN3, IN4, 0); delay(1000);
}
Raspberry Pi
# L298N on Raspberry Pi - drive 2 DC motors with PWM
# Install: pip install gpiozero
from gpiozero import Motor, PWMOutputDevice
from time import sleep
# gpiozero's Motor handles direction; we add PWM for speed
motor_a = Motor(forward=23, backward=24)
speed_a = PWMOutputDevice(12)
motor_b = Motor(forward=27, backward=22)
speed_b = PWMOutputDevice(13)
def drive(motor, speed_pin, speed):
if speed > 0:
motor.forward()
elif speed < 0:
motor.backward()
else:
motor.stop()
speed_pin.value = abs(speed)
try:
while True:
drive(motor_a, speed_a, 0.8); drive(motor_b, speed_b, 0.8); sleep(2)
drive(motor_a, speed_a, -0.6); drive(motor_b, speed_b, -0.6); sleep(2)
drive(motor_a, speed_a, 0); drive(motor_b, speed_b, 0); sleep(1)
except KeyboardInterrupt:
pass
Raspberry Pi Pico (MicroPython)
# L298N on Raspberry Pi Pico - two DC motors
from machine import Pin, PWM
import time
ENA = PWM(Pin(2)); IN1 = Pin(3, Pin.OUT); IN2 = Pin(4, Pin.OUT)
ENB = PWM(Pin(7)); IN3 = Pin(5, Pin.OUT); IN4 = Pin(6, Pin.OUT)
ENA.freq(20000); ENB.freq(20000)
def motor(en, in1, in2, speed):
# speed in -65535..65535
in1.value(1 if speed > 0 else 0)
in2.value(1 if speed < 0 else 0)
en.duty_u16(min(abs(speed), 65535))
while True:
motor(ENA, IN1, IN2, 50000); motor(ENB, IN3, IN4, 50000); time.sleep(2)
motor(ENA, IN1, IN2, -40000); motor(ENB, IN3, IN4, -40000); time.sleep(2)
motor(ENA, IN1, IN2, 0); motor(ENB, IN3, IN4, 0); time.sleep(1)
Frequently Asked Questions
Stepper or Python's AccelStepper-like packages simplify the sequencing.