Why Motors Need a Driver, in Detail
You already know the rule: never wire a motor straight to an Arduino pin. Here is the reasoning behind it, because understanding it is what lets you apply it to components this course never mentions.
An output pin is a signal source. It can supply a small current — enough for an LED through a resistor — and that is by design; the chip is built to control things, not to power them. A DC motor needs far more, and its appetite is not constant. The moment it starts, before it has begun turning, it draws a large surge. If a wheel jams against a table leg the motor stops turning but the current does not stop flowing; that stall current is the largest the motor will ever demand, and it is the number that destroys hardware.
There is a second, less obvious hazard. A motor is a coil of wire, and coils resist changes in current. When you switch a motor off, the magnetic field in that coil collapses and pushes a brief voltage spike back out, in the opposite direction to the supply and potentially much higher than it. That spike is called back-EMF, and it is perfectly capable of destroying whatever switched the motor. A flyback diode connected across the motor gives the spike a loop to circulate in until it dies out harmlessly, instead of forcing it back into your circuit.
A motor driver solves both problems at once. It takes your small signal on one side and switches the battery's large current on the other, and it includes the protection diodes already. The L298N module is the standard beginner choice, it handles two DC motors, and it costs very little. Newer driver modules waste less voltage than the L298N does and are worth knowing about, but the L298N is what most tutorials and most kits assume, so it is what this course uses.
- Running current — what a motor draws once it is spinning freely
- Startup surge — the larger current in the instant before it begins to move
- Stall current — the largest of all, drawn when the motor is powered but held still; this is what kills components
- Back-EMF — the reverse voltage spike produced when a motor is switched off
- Driver — the module that switches battery current on your behalf, with the protection built in
- Check the current your particular motor needs against what your driver module is rated for, from the datasheets rather than from memory. A driver comfortably running two small gear motors can overheat and shut down driving larger ones, which looks in practice like a robot that works for thirty seconds and then stops.
The H-Bridge: How Reversing Works
Reversing a DC motor means reversing the direction of current through it. With a battery in your hand that is easy — swap the two wires. Your robot cannot swap wires while driving, so a driver contains an arrangement of four electronic switches known as an H-bridge. The name comes from the shape of the circuit diagram: the motor sits in the crossbar of an H with a switch at each of the four ends.
Close the top-left and bottom-right switches and current flows through the motor one way. Close the top-right and bottom-left and it flows the other way. Close none and the motor coasts. That is the entire idea, and on an L298N you control it with two pins per motor, called IN1 and IN2 for the first channel.
The truth table is short and worth learning rather than looking up each time. IN1 HIGH and IN2 LOW gives one direction. IN1 LOW and IN2 HIGH gives the other. Both LOW lets the motor coast freely to a stop. Both HIGH short-circuits the motor's own terminals together, which acts as a brake — the motor's own generated voltage fights its motion and it stops abruptly.
There is one combination the driver must never be allowed into: both switches on the same vertical arm of the H closed at once, which would connect the battery straight to ground through the driver. This is called shoot-through, and it is the reason you should not try to build an H-bridge from four loose transistors on your first attempt. The L298N and every ready-made module handle this internally, which is another good reason to use one.
IN1HIGH,IN2LOW — motor turns one wayIN1LOW,IN2HIGH — motor turns the other wayIN1LOW,IN2LOW — motor coasts to a stop with no brakingIN1HIGH,IN2HIGH — motor brakes and stops sharplyENA— the enable pin; PWM here sets how fast that channel runs
- If a motor runs backwards from what you expected, do not rewrite your code. Swap the two wires going from the driver's OUT terminals to that motor. It is faster, and it keeps
moveForward()meaning forward in every part of the sketch.
PWM: Speed Control That Is Not Really a Voltage
You control motor speed with analogWrite(enA, value), where value runs from 0 to 255. The name is misleading and the misunderstanding it creates causes real bugs, so it is worth being precise about what is actually happening.
The pin is not producing a smaller voltage. It is switching fully on and fully off, several hundred times a second, and varying how much of each cycle it spends on. That proportion is called the duty cycle. At analogWrite(pin, 128) the pin is at full voltage for about half of each cycle and at zero for the other half. This is PWM, short for pulse width modulation.
It works because a motor cannot respond that fast. Its rotor has weight, so it effectively averages out the rapid pulses and behaves as though it were receiving a steady half-strength supply. The same trick dims an LED: your eye cannot follow flicker at that rate and perceives an average brightness. Nothing is genuinely halfway on at any instant.
Knowing this explains behaviour that is otherwise mystifying. Very low values do not produce a very slow robot — below some threshold the motor has enough average power to hum but not enough turning force to overcome friction, so it buzzes and stays still. That threshold is different for each motor and rises when the robot is on carpet rather than a smooth floor. It is also why a stationary robot may need a brief burst at a higher value to get moving before settling to its cruising speed. And it is why two identical motors at the same PWM value will not drive your robot perfectly straight: small manufacturing differences mean one is always slightly faster, so straight-line driving needs a small correction on one side, found by experiment.
One more constraint: PWM only works on the digital pins marked with a tilde (~). Calling analogWrite() on any other pin does not fail loudly — it just behaves as an ordinary on/off output, giving you full speed or nothing, which looks like broken speed control.
// One motor on the L298N's channel A
const int enA = 9; // MUST be a ~ (PWM) pin for speed control
const int in1 = 8;
const int in2 = 7;
void setup() {
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
}
void loop() {
// forward, gently accelerating
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
for (int speed = 100; speed <= 255; speed += 5) {
analogWrite(enA, speed);
delay(30);
}
delay(1000);
// coast to a stop (both LOW)
analogWrite(enA, 0);
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
delay(1000);
// reverse at roughly half speed
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, 128);
delay(2000);
// brake sharply (both HIGH)
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
delay(1000);
} - The loop above starts at 100 rather than 0 because the low end of the range usually cannot move a robot at all. Find your own motors' lowest useful value by testing on the surface the robot will actually run on, and use that as your minimum everywhere in the sketch.
Wiring the L298N Without Destroying Anything
Wire the driver in a fixed order every time and the whole thing becomes routine. Motors to the OUT terminals first, then the control pins to the Arduino, then power last — always last, with the battery disconnected while you work.
The control side needs three Arduino pins per motor: two direction pins to IN1 and IN2, and one PWM pin to ENA. The power side takes the battery's positive lead into the driver's motor supply terminal and the battery's negative into the driver's GND terminal.
Then the connection people forget, and the one that produces the strangest symptoms: run a wire from an Arduino GND pin to the driver's GND terminal as well. Your Arduino and your motor battery are two separate power sources, and a voltage only means something as a difference between two points. Without a shared ground the driver has no fixed reference against which to judge whether your IN1 signal is HIGH or LOW.
The failure looks like this: motors twitch at random, the robot works while the USB cable is plugged in and dies the instant you unplug it, or it lurches whenever you touch the chassis. Every one of those symptoms sends students back to their code, where the fault is not. One wire between the two grounds fixes all of them.
Two more points specific to the L298N. Many of these modules carry a small jumper that enables an on-board 5 V regulator, which can then power the Arduino's 5 V line from the motor battery; whether that is appropriate depends on your battery voltage, so check your module's own documentation rather than copying a photo from a tutorial. And the L298N is an older design that loses a noticeable amount of voltage inside itself, so your motors receive meaningfully less than the battery supplies. If your robot feels underpowered, that loss is often the reason rather than a flat battery.
// L298N connection map for a two-motor robot
//
// DRIVER ARDUINO / BATTERY
// ---------------------------------------------------
// ENA ----------> pin 9 (PWM, right motor speed)
// IN1 ----------> pin 8 direction
// IN2 ----------> pin 7 direction
// IN3 ----------> pin 5 direction
// IN4 ----------> pin 4 direction
// ENB ----------> pin 3 (PWM, left motor speed)
//
// OUT1, OUT2 -----> right motor terminals
// OUT3, OUT4 -----> left motor terminals
//
// motor supply <--- battery positive
// GND <--- battery negative
// GND <--- Arduino GND <== THE SHARED GROUND
//
// Connect power LAST, after checking every wire above. - Never feed motor battery voltage into the Arduino's 5 V pin. That pin is the output of the board's own regulator; pushing voltage back into it bypasses the protection the board depends on. Motor power goes to the driver's power terminal, and only ground is shared.
- Before the first power-up, check polarity twice. Reversed battery leads destroy driver modules instantly and can make them hot enough to burn you.
Servo Motors: Commanding an Angle
A servo is a different kind of device from a DC motor, even though a DC motor is inside it. Sealed into the case with it are a gearbox, a sensor that measures the output shaft's position, and a small circuit that continuously compares where the shaft is with where you asked it to be, and drives the motor until the two match. You do not command speed or direction. You command a position, and the servo holds it.
A hobby servo has three wires: power, ground, and signal. The colours are usually brown or black for ground, red for power, and orange, yellow or white for signal. The signal is not a voltage level — it is a short pulse repeated about fifty times a second, whose width encodes the angle you want. The Arduino Servo library generates those pulses for you, so in code you simply call myServo.write(90).
Now the practical warning, which is where most first servo projects go wrong. A servo is not a signal-level device; it is a motor, and it draws real current, especially at the moment it starts moving and when it is holding a position against a load. Powering one small servo from the Arduino's 5 V pin often works while it is unloaded, which is exactly what makes this trap so effective — it works on the bench and fails on the robot. Add a second servo, or a load on the arm, and the current draw drops the supply voltage far enough to reset the board. The symptom is a servo that jitters wildly while the Arduino restarts over and over.
The correct arrangement is a separate power supply for the servos, with — as always — its ground connected to the Arduino's ground so the signal wire has a shared reference. USB from a laptop is limited too, so "it is plugged into my computer, it should be fine" is not a safe assumption for anything with several servos.
One last detail that surprises people on an Uno: the Servo library takes over the timer that generates PWM on pins 9 and 10, so analogWrite() on those two pins stops working as soon as the library is used, whichever pins your servos are actually attached to. If your motor speed control mysteriously breaks the moment you add a servo, this is why — move the motor's enable pin to a different PWM pin.
#include <Servo.h>
Servo armServo;
void setup() {
armServo.attach(6); // signal wire on pin 6
armServo.write(90); // start at the middle
delay(500);
}
void loop() {
// sweep slowly so the servo is not fighting its own inertia
for (int angle = 0; angle <= 180; angle++) {
armServo.write(angle);
delay(15); // give it time to actually get there
}
for (int angle = 180; angle >= 0; angle--) {
armServo.write(angle);
delay(15);
}
}
// Power: servo red wire -> separate 5 V supply, NOT the Arduino 5 V pin
// servo brown/black wire -> that supply's ground AND Arduino GND
// servo orange/yellow wire -> Arduino pin 6 write()only sends the target angle; it returns immediately and does not wait for the servo to arrive. Commanding a new angle in the very next line means the servo never reaches the first one. The shortdelay(15)in the sweep above is what gives it time to move.- A servo that buzzes continuously without moving is straining against a mechanical limit or a jammed joint. Cut the power quickly — a stalled servo draws its highest current and can overheat and strip its plastic gears.
