Driving DC Motors with an L298N
| Difficulty | Intermediate |
|---|---|
| Category | Motion |
| Supported boards | Arduino Uno R3 and compatible ATmega328P boards |
| Time needed | 60 minutes |
| Prerequisites | Controlling an SG90 Servo |
| Tested board | Not yet verified |
| Tested on | Not yet verified |
| Arduino IDE version | Not yet verified |
| Library | Not yet verified |
What it does
An L298N module is an H-bridge: a switching arrangement that lets a small control signal decide which way current flows through a motor, and therefore which way the motor turns. The board carries two of them, so it drives two DC motors independently, forwards and backwards, at a speed you set.
The reason you need it is simple. A DC motor draws far more current than an Arduino pin can supply, and connecting one directly does not work and may not survive. The Arduino’s job here is to send six small logic signals. The motor’s current never passes through it.
Before you begin
Required parts and tools
- An Arduino Uno or compatible board.
- One L298N driver module. This is Siratek product 2533.
- One or two DC motors rated for your supply voltage.
- A separate motor supply. A 6 V or 9 V battery pack, or a 12 V supply for 12 V motors.
- A small screwdriver for the terminal blocks, and five or six jumper wires.
What is on the board
The Siratek module is the common red board. Looking at it:
- A large L298N chip under a black heatsink. That heatsink is not decorative; the chip gets genuinely hot under load.
- Two two-screw terminal blocks, one at each side, marked
OUT1/OUT2andOUT3/OUT4. One motor goes to each. - A three-screw terminal block in the middle: motor supply positive, ground, and 5 V.
- A six-pin logic header:
ENA,IN1,IN2,IN3,IN4,ENB. - Jumpers on
ENAandENB, fitted from the factory. - A jumper beside the power terminals that switches the onboard 5 V regulator in or out. Silkscreen labels for this one vary; check your own board.
The two jumpers, which decide how the board behaves
The ENA and ENB jumpers. Each enable pin turns its half of the bridge on. With the jumper fitted, that pin is tied high permanently, so the motor runs at full speed whenever the direction pins say so. Leave the jumpers on and you cannot control speed at all. To get speed control, pull both jumpers off and wire those pins to PWM-capable Arduino pins.
Keep the jumpers somewhere. They are small and they are the quickest way to test a motor without writing any code.
The regulator jumper. The board has a small 5 V regulator on it, fed from the motor supply. With the jumper fitted, the +5V terminal becomes an output and can power the Arduino’s 5V pin. With it removed, that terminal becomes an input and expects a regulated 5 V from elsewhere.
Two rules follow, and the first one matters:
- With the jumper fitted, never connect anything to the
+5Vterminal. You would be driving one regulator’s output into another’s. - The onboard regulator is specified for a motor supply up to about 12 V. Above that, pull the jumper and power the logic separately, or the regulator overheats.
For a first project the simplest arrangement is: jumper fitted, motor supply into the board, and the Arduino powered separately over USB. Then nothing depends on the regulator at all.
The voltage drop nobody mentions
An L298N is an old bipolar design, and it loses roughly two volts across the bridge. Give the board 6 V and the motor sees about 4. Give it 9 and the motor sees about 7.
So a 6 V motor on a 6 V pack will be noticeably weak and may not start under load. Plan on supplying a couple of volts above the motor’s rating, or use a modern MOSFET driver when efficiency matters. This is the main reason an L298N feels underpowered when it is working perfectly.
Grounds, again
The motor supply’s ground and the Arduino’s GND must be joined, through the middle terminal of the three-screw block. Without it the logic signals have no shared reference and the motors behave unpredictably.
This is the same rule as the servo, and it will be the same rule for every powered module you meet.
Pin reference
| Board terminal or pin | Connect to | Purpose |
|---|---|---|
+12V (supply terminal) |
Motor supply positive | Motor power, 6 to 12 V typical |
GND (supply terminal) |
Motor supply ground and Uno GND |
Shared reference |
+5V (supply terminal) |
Nothing, with the regulator jumper fitted | Output, not input |
OUT1, OUT2 |
Motor A, either way round | Swapping them reverses the motor |
OUT3, OUT4 |
Motor B | |
ENA |
Uno D10 |
Motor A speed, jumper removed |
IN1 |
Uno D9 |
Motor A direction |
IN2 |
Uno D8 |
Motor A direction |
IN3 |
Uno D7 |
Motor B direction |
IN4 |
Uno D6 |
Motor B direction |
ENB |
Uno D5 |
Motor B speed, jumper removed |
D10, D6 and D5 are PWM-capable, which is what the enable pins need.
Wiring steps
- Unplug the USB cable and disconnect the motor supply.
- Screw motor A’s two leads into
OUT1andOUT2. Either way round; you will correct the direction in software or by swapping them later. - Screw motor B into
OUT3andOUT4, if you are using two. - Pull the
ENAandENBjumpers off and keep them. - Wire the six logic pins to the Uno as in the table.
- Run a wire from the board’s middle
GNDterminal to the Uno’sGND. - Screw the motor supply into the
+12VandGNDterminals, watching the polarity. - Plug in the USB cable before connecting the motor supply, so the logic pins are driven rather than floating.
- Connect the motor supply.
Step 8 is worth keeping to. Floating inputs on an H-bridge can leave a motor running at power-up.
Software and libraries
No library is required. The board takes plain digitalWrite() and analogWrite().
Minimal working example
// Siratek: one DC motor, forwards and backwards, with speed control.
const int enA = 10;
const int in1 = 9;
const int in2 = 8;
void setup() {
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
Serial.begin(9600);
Serial.println("Siratek: motor test starting.");
}
void forward(int speed) {
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, speed);
}
void backward(int speed) {
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, speed);
}
void stop() {
analogWrite(enA, 0);
}
void loop() {
Serial.println("forward, slow");
forward(120);
delay(2000);
Serial.println("forward, full");
forward(255);
delay(2000);
Serial.println("stop");
stop();
delay(1000);
Serial.println("backward, full");
backward(255);
delay(2000);
Serial.println("stop");
stop();
delay(2000);
}
The pattern is always the same: two direction pins decide which way, one enable pin decides how hard. IN1 high and IN2 low is one direction; reverse them for the other. Both the same is a brake.
If the motor turns the wrong way, swap IN1 and IN2 in the code, or swap the two motor leads in the terminal block. Either works.
Why slow speeds do not start the motor
Try forward(40) and the motor will probably sit still and hum. That is not a fault. At a low duty cycle there is not enough average torque to overcome the motor’s own friction, and it stalls while still drawing current.
The usual fix is a short full-power kick, then drop to the speed you wanted.
void startAt(int speed) {
analogWrite(enA, 255);
delay(60);
analogWrite(enA, speed);
}
Find your own minimum by stepping the value up until the motor turns reliably from a standstill. Below that figure, do not ask for it.
Expected result
The motor turns one way for two seconds slowly, then faster, stops, reverses, stops. The heatsink becomes warm; under continuous load it becomes hot enough to be uncomfortable to touch, which is within normal for this chip.
Measure the supply voltage at the motor terminals while running and compare it with your supply. The difference is the bridge drop, and seeing it once explains a great deal.
Troubleshooting
| Symptom | Likely cause | Check or fix |
|---|---|---|
| Motor runs at full speed only | ENA or ENB jumper still fitted |
Remove it and wire the pin to a PWM output |
| No movement at all | Motor supply not connected | The +12V terminal needs a real supply |
| No movement, logic LEDs lit | Grounds not joined | Link supply GND to Uno GND |
| Motor runs at power-up, before any code | Inputs floating | Power the Arduino first; set the pins in setup() |
| Turns the wrong way | Direction pins or leads | Swap IN1 and IN2, or swap the motor leads |
| Weak, will not start under load | Two-volt bridge drop | Supply a couple of volts above the motor rating |
| Hums but does not turn at low speed | Below the starting duty cycle | Kick at full power briefly, then reduce |
| Board very hot, cuts out | Current or supply voltage too high | Check the motor’s stall current; improve airflow |
| Arduino resets when the motor starts | Sharing one supply | Separate supplies, grounds joined |
| Smoke or a burnt smell | Short, or reversed supply | Disconnect at once; check the terminal polarity |
+5V terminal measures odd values |
Something connected while the jumper is fitted | Disconnect it; that terminal is an output |
Next steps
- Easier first: Controlling an SG90 Servo, where position matters more than power.
- Related product: the ULN2003 stepper set, Siratek 2745, when you need exact steps rather than speed.
- Next project: a line-following robot, which is two of these motors and a pair of sensors.
Sources and attribution
All text, wiring guidance and code in this tutorial are original Siratek work.
- ST L298N datasheet for the bridge’s saturation voltage drop and the chip’s thermal behaviour.
- The board layout described here, the terminal blocks, the six-pin logic header and the enable and regulator jumpers, was read from the Siratek product photographs for item 2533.
Silkscreen labelling for the regulator jumper varies between batches of this board, so the reader is told to check their own. Starting duty cycle and current draw depend on the motor and are given as something to measure. No third-party tutorial text, diagrams, photographs or code has been reproduced here.

