Motors are how a robot acts on the world — everything the robot decides to do finally becomes a motor turning. This lesson covers the three motor types you will meet first: DC motors for wheels, servos for precise angles, and steppers for exact positioning. You will learn why a microcontroller cannot drive a motor directly, what a motor driver does, and how to control speed and direction in code. Get this right and your robot moves the way you intend instead of stalling or resetting.
- Tell a DC motor, a servo, and a stepper apart and pick the right one
- Explain why a motor needs a driver between it and the microcontroller
- Control motor speed with PWM and direction with an H-bridge
- Drive a hobby servo to a commanded angle in code
Three kinds of motor
Most first robots use one of three motors, and choosing the right one saves a lot of grief. A DC motor spins continuously when powered; speed follows voltage and direction follows polarity. It is what drives wheels — cheap, fast, but with no built-in sense of position (you add an encoder for that). A servo is a small geared motor with built-in electronics that holds a commanded *angle*, typically 0 to 180 degrees; you tell it 'go to 90 degrees' and it goes and holds. It is perfect for a robot arm joint, a steering linkage, or a sensor pan. A stepper moves in precise fixed steps and can hold an exact position without feedback, which makes it the choice for 3D printers and anything needing repeatable precision, at the cost of speed and more complex driving.
- DC motor → wheels and continuous motion; needs a driver, add an encoder for position.
- Servo → a held angle 0–180°; great for arm joints and steering.
- Stepper → exact repeatable steps; precise but slower and needs a stepper driver.
Why you cannot drive a motor from a pin
A microcontroller pin can supply only a tiny current — around 20 to 40 milliamps. A motor draws hundreds of milliamps to several amps, especially at the moment it starts or stalls. Wire a motor straight to a pin and you will destroy the pin, the board, or both, and a spinning motor also generates voltage spikes back into the circuit. So a motor is always driven through a separate circuit — a motor driver — that takes a small control signal from the microcontroller and switches the large motor current from a separate power supply. The microcontroller commands; the driver does the heavy lifting.
Never connect a DC motor directly to an Arduino pin, and never power motors from the board's 5V pin. Use a driver and a separate motor supply, and join the two grounds so they share a reference. This single rule prevents most fried boards.
The H-bridge: speed and direction
The standard DC-motor driver is an H-bridge — four switches arranged so they can send current through the motor in either direction, which is how you reverse it. Boards like the L298N or the smaller TB6612 or DRV8833 give you two control pins to set direction and one PWM pin to set speed per motor. You set the two direction pins to one combination for forward, the opposite for reverse, both low to coast, and you feed a PWM value to the enable pin for speed. Two motors driven this way is a complete differential-drive robot: both forward to go straight, one faster to turn, opposite directions to spin in place.
// Drive one DC motor through an H-bridge (e.g. L298N).
const int IN1 = 7, IN2 = 8, ENA = 9; // ENA must be a PWM (~) pin
void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENA, OUTPUT);
}
void drive(int speed, bool forward) {
digitalWrite(IN1, forward ? HIGH : LOW);
digitalWrite(IN2, forward ? LOW : HIGH);
analogWrite(ENA, speed); // 0-255 sets speed via PWM
}
void loop() {
drive(180, true); delay(1000); // forward, ~70% speed
drive(0, true); delay(500); // stop
drive(180, false); delay(1000); // reverse
drive(0, true); delay(500);
}Servos: commanding an angle
A servo is easier: it has three wires — power, ground, and one signal — and you command an angle with the Arduino Servo library. Under the hood the library sends a pulse every 20 milliseconds whose width (roughly 1 to 2 milliseconds) encodes the angle, but you never deal with that directly; you just call write(angle). A small servo can run off the board for testing, but anything under load needs its own supply, with grounds joined, exactly like a DC motor. Servos are the fastest way to give a robot precise, repeatable joints.
#include <Servo.h>
Servo joint;
void setup() {
joint.attach(9); // signal wire on pin 9
}
void loop() {
joint.write(0); delay(600); // go to 0 degrees
joint.write(90); delay(600); // centre
joint.write(180); delay(600); // full travel
}If a servo jitters or the board resets when it moves, it is a power problem: the servo's stall current is dipping the supply. Give the servo its own battery or a separate regulator, join the grounds, and the jitter usually stops.
Making two motors go straight
A practical surprise: command two DC motors to the same speed and the robot still curves, because no two motors are identical and one wheel grips more. There are two fixes. The cheap one is trim — nudge one motor's PWM up by a fixed amount you find by trial until it tracks straight, which works but drifts as the battery drains. The proper one is closed-loop control with encoders: measure each wheel's actual speed and adjust its PWM to match a target, so the robot corrects itself. You will meet that control idea in depth in the control lesson; for now, know that 'drive straight' is a control problem, not just equal PWM.