Learning Goals 5 min
One transistor gives you on / off. To reverse a motor you'd have to physically swap wires — silly for a robot. The H-bridge solves this with four transistors per motor, arranged so software can choose direction, speed, brake, or coast. By the end of this lesson you will:
- Explain the four states of an H-bridge — forward, reverse, brake, coast — using the "close two switches" mental model.
- Wire the L298N module to a UNO and a 4 × AA pack with the correct power-rail discipline: VS from the battery, GND shared, VCC/5V either jumpered or supplied from the Arduino.
- Drive one motor forward, reverse, brake and coast using
digitalWriteon IN1 / IN2, controlled by serial commands typed into the Serial Monitor.
Warm-Up 10 min
Pull out your L298N module — the bright red PCB with a big silver heatsink in the middle. Identify these connectors and pins on the board:
- Big screw terminal block (one side): three terminals labelled
+12V(orVS),GND,+5V. - Two more screw terminal blocks (the other two corners):
OUT1 / OUT2andOUT3 / OUT4. These go to your two motors. - Header pins:
ENA,IN1,IN2,IN3,IN4,ENB— these are the control inputs from the Arduino. - Two jumpers: one labelled "5V enable", one across each of the
ENA/ENBpins. We'll discuss both in §3.
The big question
Why does the screw terminal have three pins — VS, GND, +5V — when most modules have only two (power + and power −)?
Reveal
The L298N is two boards in one:
- A high-power motor side that needs the full battery voltage (VS) — 6 V to 35 V depending on your motor.
- A low-power logic side that runs the chip's internal control circuitry on 5 V.
The +5V terminal is bidirectional: with the "5V enable" jumper installed, the board generates 5 V from VS (via an on-board regulator) and outputs it on the +5V pin — handy if you want to power your Arduino from the same battery. Without the jumper, you must supply 5 V into that pin from the Arduino. Both wiring styles are valid.
New Concept · Four switches, four states 25 min
The H-bridge mental model
Imagine the motor as a vertical bar in the middle of an H. Four switches sit at the corners of the H: top-left (S1), top-right (S2), bottom-left (S3), bottom-right (S4). Each top switch connects its corner to the battery+; each bottom switch connects its corner to GND.
| State | Closed switches | What the motor sees |
|---|---|---|
| Forward | S1 (top-left) + S4 (bottom-right) | Battery+ on left lead, GND on right — motor spins one way. |
| Reverse | S2 (top-right) + S3 (bottom-left) | Battery+ on right lead, GND on left — motor spins the other way. |
| Brake | S3 + S4 (both bottoms) | Both motor leads shorted to GND. Back-EMF dumps into a short → strong braking. |
| Coast | None (or both tops only) | Motor disconnected. Spins down slowly under its own friction. |
| FORBIDDEN — "shoot-through" | S1 + S3 (or S2 + S4) | Both transistors in one column on → direct short across the battery. Smoke. |
The L298N chip enforces that you can never accidentally close S1 + S3 at the same time, because IN1 controls the pair S1/S3 and IN2 controls S2/S4 — only one switch per column can be closed.
The four control combinations on the L298N
| IN1 | IN2 | ENA | Result for Motor A |
|---|---|---|---|
| HIGH | LOW | HIGH | Forward at full speed |
| LOW | HIGH | HIGH | Reverse at full speed |
| HIGH | HIGH | HIGH | Brake (both outputs HIGH = both shorted to VS) |
| LOW | LOW | HIGH | Brake (both outputs LOW = both shorted to GND) |
| anything | anything | LOW | Coast (outputs floating) |
So ENA is the gate: when low, the motor is disconnected regardless of IN1/IN2. When high, IN1/IN2 set direction. PWM on ENA gives speed control — that's L03-09.
The jumpers explained
- 5V enable jumper: ON if your battery VS is ≤ 12 V. The on-board regulator generates 5 V from VS for the chip's logic. You can also use that 5 V to power your Arduino if you want a single-supply robot. OFF if VS is > 12 V — the regulator overheats above 12 V.
- ENA / ENB jumpers: shorting these jumpers ties the enable pin permanently HIGH — useful if you don't need PWM speed control and want to free up an Arduino pin. Remove them when you want to drive ENA / ENB from the Arduino for PWM.
Wiring diagram (in words)
- Battery + → L298N
VS(or+12V) screw terminal. - Battery − → L298N
GNDscrew terminal. - L298N
GND→ ArduinoGND(common ground!). - Either: L298N
+5Vscrew → Arduino5V(board powers Arduino), OR: 5V enable jumper OFF, Arduino5V→ L298N+5V(Arduino powers L298N logic). Don't do both at once. - Arduino D9 → L298N
IN1. - Arduino D8 → L298N
IN2. - L298N
ENA: jumper installed for now (always-on). - Motor leads → L298N
OUT1+OUT2.
Worked Example · Forward / reverse / brake / coast from serial 25 min
Step 1 — wire it
Follow the wiring list from §3. For this lesson, set the "5V enable" jumper to ON (board generates 5V) and leave the ENA jumper installed (motor always enabled when IN pins call for it). One motor on OUT1/OUT2.
Step 2 — the sketch
// L03-08 · L298N H-bridge — forward/reverse/brake/coast from serial.
// f = forward, b = back, s = brake, c = coast. + Enter to send.
const int IN1 = 9;
const int IN2 = 8;
void forward() { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); }
void reverse() { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); }
void brake() { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); }
// "coast" requires releasing ENA. With ENA jumpered HIGH (this lesson),
// we approximate coast with brake — the motor stops, just more abruptly.
// L03-09 wires ENA to a PWM pin and gives us a real coast.
void coast() { brake(); }
void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
brake();
Serial.begin(9600);
Serial.println("# H-bridge ready. f/b/s/c + Enter.");
}
void loop() {
if (Serial.available() == 0) return;
char cmd = Serial.read();
switch (cmd) {
case 'f': case 'F': forward(); Serial.println(">> FORWARD"); break;
case 'b': case 'B': reverse(); Serial.println(">> REVERSE"); break;
case 's': case 'S': brake(); Serial.println(">> BRAKE"); break;
case 'c': case 'C': coast(); Serial.println(">> COAST"); break;
default: return;
}
}Step 3 — upload and try every command
Power the L298N from the battery pack. Open Serial Monitor at 9600 baud, line ending "Newline". Type:
f→ motor spins one ways→ motor stops abruptlyb→ motor spins the other ways→ stops
If the motor spins the "wrong" way on f, swap the two motor leads at OUT1/OUT2. Convention done — "forward" should mean "the direction you call forward".
Step 4 — feel the brake vs the coast (preview)
With the ENA jumper installed we can't really coast — the chip will always actively drive both outputs. To see the difference, momentarily lift the ENA jumper while the motor is spinning. You should feel the motor go from "hard hold" (brake) to "spins down freely" (coast). Put the jumper back. (We get proper PWM-controlled enable in L03-09.)
Step 5 — the "both motors" preview
Wire the second motor to OUT3/OUT4, and the second pair of control pins to D7 (IN3) and D6 (IN4). Add equivalent functions for Motor B. Now you have a 2-motor driver — you're ready for the chassis in L03-10.
Step 6 — sanity-check the heatsink temperature
After a few minutes of driving, touch the silver heatsink — gently. It should feel warm, not hot. The L298N is an old chip and dissipates ~1.5 V per output transistor times the motor current — for a 1 A motor that's 3 W of heat. If it's painful to touch, you're drawing too much current and either need a bigger motor driver or a smaller motor.
Try It Yourself 15 min
Goal: Make the motor automatically alternate every 2 seconds: forward, brake, reverse, brake, repeat. No user input.
Hint
void loop() {
forward(); delay(2000);
brake(); delay(500);
reverse(); delay(2000);
brake(); delay(500);
}The 500 ms brake between direction changes gives the motor a chance to fully stop before reversing — avoiding the gear-stripping "snap reverse" that a worn motor will complain about loudly.
Goal: Convert to non-blocking timing (L02-35 / L03-03 pattern). Same behaviour, but other things can run in parallel.
Hint
enum State { FWD, BRK1, REV, BRK2 };
State state = FWD;
unsigned long stateEntered = 0;
void loop() {
unsigned long now = millis();
switch (state) {
case FWD: if (now - stateEntered >= 2000) { brake(); state = BRK1; stateEntered = now; } break;
case BRK1: if (now - stateEntered >= 500) { reverse(); state = REV; stateEntered = now; } break;
case REV: if (now - stateEntered >= 2000) { brake(); state = BRK2; stateEntered = now; } break;
case BRK2: if (now - stateEntered >= 500) { forward(); state = FWD; stateEntered = now; } break;
}
}You'll recognise this pattern from the smart bin lid (L02-26). The motor schedule and any other timer in your sketch run independently.
Goal: Two motors, two buttons. Button A on D2 selects Motor A; Button B on D3 selects Motor B. The Serial monitor commands (f / b / s) only affect the currently-selected motor.
Hint
Add a global int activeMotor = 0; and read the buttons in loop() to set it. Refactor your direction functions to take a motor index: void forward(int m) {...}. Use a 2D pin array const int PINS[2][2] = {{9,8},{7,6}}; to look up the right IN1/IN2 for the selected motor.
This is the foundation of multi-motor robotics — the addressable "motor as a thing" pattern. We'll build on it in the chassis project of L03-10.
Mini-Challenge · Write a small motor helper file 10 min
The four direction functions (forward, reverse, brake, coast) will be used in every Cluster B sketch. Refactor them into a reusable header next to your servo-config.h from L03-02.
- Create
motor.h:
// motor.h — minimal L298N driver helpers
#ifndef MOTOR_H
#define MOTOR_H
#include <Arduino.h>
struct Motor {
int in1;
int in2;
};
inline void motorInit(const Motor& m) {
pinMode(m.in1, OUTPUT);
pinMode(m.in2, OUTPUT);
}
inline void motorForward(const Motor& m) {
digitalWrite(m.in1, HIGH);
digitalWrite(m.in2, LOW);
}
inline void motorReverse(const Motor& m) {
digitalWrite(m.in1, LOW);
digitalWrite(m.in2, HIGH);
}
inline void motorBrake(const Motor& m) {
digitalWrite(m.in1, LOW);
digitalWrite(m.in2, LOW);
}
#endif- In your sketch:
#include "motor.h"
const Motor motorA = {9, 8};
const Motor motorB = {7, 6};
void setup() {
motorInit(motorA);
motorInit(motorB);
}Now any sketch that needs a motor just #include "motor.h", declares its motor as a Motor struct with pin numbers, and uses the friendly helpers. We'll add a motorSpeed(m, duty) helper in L03-09 (PWM control), and finally a full Motor class in L03-41.
Recap 5 min
The H-bridge is the foundation of every powered robot you'll ever build. Four transistors per motor let software choose direction, brake, or coast. The L298N module is the classroom standard — a chip + heatsink on a red PCB with screw terminals for power and motors and header pins for control. Two pins per motor (INx) set direction; one enable pin (ENx) gates it on / off (and later, takes a PWM signal for speed). The mandatory rules: common ground; one source of 5 V logic, not two; don't exceed the chip's 2 A continuous limit. Tomorrow we add PWM to ENA and unlock continuous speed control — the L03-09 lesson is what makes a robot feel smooth instead of switched.
- H-bridge
- A circuit of four transistors arranged in an "H" with the motor in the middle bar. Lets software switch the motor between forward, reverse, brake, and coast.
- L298N
- A classic dual H-bridge IC (two motors per chip). Cheap, robust, but old: 1.5–2 V drop per transistor, no current sensing, big heatsink needed.
- VS (motor supply)
- The voltage rail that powers the motors. Comes from a battery, separate from the Arduino's logic supply.
- VCC / +5V (logic supply)
- The voltage that powers the chip's internal logic — always 5 V for the L298N. Can be supplied by the board itself (5V enable jumper) or by the Arduino.
- Common ground
- The Arduino's GND and the motor pack's − must be connected to each other. Without it, the IN pin signals from the Arduino have no shared reference at the L298N.
- Enable pin (ENA / ENB)
- The "master switch" for each motor. When low, the motor is disconnected; when high (or PWM'd), the IN pins control direction (and speed).
- Brake vs coast
- Brake = both motor leads shorted to the same rail; back-EMF causes rapid deceleration. Coast = motor disconnected; spins down under friction alone.
- Shoot-through
- A failure mode where the top and bottom transistor in the same H-bridge column conduct simultaneously, shorting the battery. The L298N's logic prevents this by design — but home-made H-bridges from discrete transistors must be designed carefully to avoid it.
Homework 5 min
- Save your
motor.hfrom §6 and the "serial-controlled H-bridge" sketch ashbridge-serial.ino. We'll PWM-extend it tomorrow. - Wire your second motor to OUT3/OUT4 and the second pair of pins (D7 = IN3, D6 = IN4) so you have both motors ready for L03-09 / L03-10. Verify both spin in both directions with the serial rig from §4 (extend the switch to cover Motor B).
- Estimate the L298N's thermal limit: with two motors averaging 700 mA at a 6 V supply, the chip dissipates approximately 2 × 0.7 × 1.5 = 2.1 W. With a heatsink and no airflow, what surface temperature do you predict after 5 minutes? (Just guess; we'll measure in class.)
Bring back next class:
- Your dual-motor wired build, both motors working in both directions.
- Your saved
motor.hfile. - Your thermal guess.
- A potentiometer — we'll use it as a throttle in L03-09.