The Controller: Arduino, ESP32 or Raspberry Pi
The controller is where your code lives, and picking the wrong one is the most common way a first project stalls. The three boards students meet are genuinely different kinds of machine, not three sizes of the same thing.
An Arduino Uno carries a microcontroller: one chip, one program, no operating system. Give it power and it starts running your code within a fraction of a second, and it keeps running it exactly the same way forever. Its pins connect straight to the outside world, so reading a switch or timing a sensor pulse is a single instruction. It cannot browse the internet, store photos or run Python, and it does not need to. For a line follower or an obstacle-avoiding car, that simplicity is an advantage — there is no operating system to freeze halfway through a turn.
A Raspberry Pi is a small computer. It runs Linux, has a proper file system, connects to a screen and keyboard, and runs Python and OpenCV comfortably. That makes it the right choice when your robot has to see — recognising a face, tracking a coloured ball, reading a number plate. The costs are real though: it takes tens of seconds to boot, it draws far more current than a microcontroller, its timing is at the mercy of the operating system's scheduler, and pulling the power without shutting down properly can corrupt the memory card.
An ESP32 sits between them. It is a microcontroller like the Arduino, so it boots instantly and talks to pins directly, but Wi-Fi and Bluetooth are built into the chip. If your robot needs to be controlled from a phone over Wi-Fi or send readings to a web dashboard, the ESP32 saves you a separate module. The catch matters and is easy to miss: an ESP32 runs on 3.3 V logic, so a sensor module designed for a 5 V Arduino may need a level shifter before you connect it. Wiring a 5 V signal straight into a 3.3 V pin can damage the board.
- Arduino Uno — instant start, dead simple, direct pin control; best for your first robots and for anything time-critical
- ESP32 — microcontroller with Wi-Fi and Bluetooth built in; remember it uses 3.3 V logic
- Raspberry Pi — a full Linux computer; choose it when you need cameras, vision or heavy processing
- Both together — a common professional pattern: the Pi decides where to go, the Arduino drives the motors
- Arduino Nano — the Uno's chip in a much smaller board; the same code, useful when space is tight
- The whole of this course targets the Arduino Uno, so every sketch here assumes 5 V logic and Uno pin numbers. Most of it runs unchanged on a Nano. Before moving a project to an ESP32, check every module's voltage requirement first.
Sensors: How a Robot Learns Anything
A sensor's job is to convert some physical quantity into an electrical signal your controller can read. Which sensor you pick decides what your robot can possibly know, so it is worth understanding what each one is actually measuring rather than what its product listing claims.
The ultrasonic sensor (usually an HC-SR04) sends out a burst of sound above human hearing and times how long the echo takes to come back. Since sound travels at a known speed, that time converts to distance. It works in complete darkness and is cheap, which is why it is on almost every beginner robot. Its weakness is geometry: sound bounces off a smooth wall at an angle the way light bounces off a mirror, so a wall approached at a sharp angle can reflect the pulse away and read as "nothing there". Soft objects such as curtains or a person in a woollen sweater absorb sound and can also read as empty space.
An infrared sensor shines infrared light down and measures how much bounces back. A white surface reflects strongly, a black surface absorbs, so a pair of them can tell a robot whether it is over a black line. They are fast and cheap. They are also easily confused by strong ambient light — sunlight through a window contains plenty of infrared — and by shiny floors, and they must sit at a fairly precise height above the surface to work at all.
A camera gives you enormously more information than either, and demands enormously more processing to make sense of it, which is why cameras generally pair with a Raspberry Pi rather than an Arduino. An IMU, short for inertial measurement unit, combines an accelerometer and a gyroscope to report how the robot is tilting and turning; it is what lets a self-balancing robot stay upright.
- Ultrasonic (HC-SR04) — distance in centimetres; used for obstacle avoidance; struggles with angled walls and soft surfaces
- Infrared reflectance — black versus white underneath; used for line following; sensitive to ambient light and mounting height
- Push button or limit switch — has something been pressed or reached; used for start buttons and end-stops
- Potentiometer — a knob position as a voltage; the simplest way to feed a changeable number into a sketch
- LDR (light dependent resistor) — how bright it is; used for light-seeking robots and automatic lamps
- IMU (accelerometer plus gyroscope) — tilt and rotation; used for balancing and for knowing which way you turned
- Camera — a full image; used for object and colour tracking, normally with a Raspberry Pi
- No sensor is ever perfectly accurate. Readings jitter, and occasionally one comes back wildly wrong. Robust robots never act on a single reading — a common fix is to take three or five readings and use the middle value, so one bad measurement cannot make the robot swerve.
Actuators: DC Motors, Servos and Steppers
Three kinds of motor cover almost everything a hobby robot does, and choosing between them comes down to one question: do you care about how fast it turns, or about exactly where it ends up?
A DC motor is the simple case. Apply voltage and it spins; swap the two wires and it spins the other way; give it less average voltage and it turns more slowly. It has no idea what position it is in and it cannot tell you. That is fine for wheels, where you only care about driving forward. Bare DC motors spin far too fast and far too weakly to push a robot, so the ones you buy for robots are gear motors, with a gearbox already attached that trades speed for turning force.
A servo motor is a small DC motor with a gearbox, a position sensor and a control circuit packed into one case. You do not tell it to spin — you tell it an angle, and it moves there and holds itself there against a load. That makes servos the natural choice for a robotic arm joint, a gripper, or a sensor you want to swivel. The trade-off is that a standard hobby servo only rotates through a limited arc, commonly around 180 degrees, so it cannot drive a wheel continuously.
A stepper motor moves in fixed, equal steps, which lets it be positioned very precisely without needing a sensor, as long as nothing forces it out of position. That is why 3D printers and small CNC machines use them. Steppers need their own driver module and draw current even while holding still, so they are usually more than a first robot needs.
- DC gear motor — continuous rotation, speed set by PWM, direction set by swapping polarity; used for wheels
- Servo motor — you command an angle and it holds it; used for arms, grippers and sensor mounts
- Stepper motor — precise repeatable steps; used for printers and machines that must return to an exact position
- Buzzer — the cheapest possible debugging output; a beep tells you your code reached a line
- LED — a status light that costs almost nothing and saves hours; always wire it through a series resistor
- Every one of these actuators draws far more current than a controller pin can supply. That is not a detail to fix later — it is the single most important electrical fact in this course, and the next section explains what to do about it.
Never Wire a Motor Straight to a Controller Pin
This is the rule that saves boards. An Arduino output pin is designed to deliver a small signal current — enough to light an LED through a resistor, or to feed the input of another chip. It is a control signal, not a power supply. A DC motor, even a small toy one, needs far more current than that, and the moment it starts or stalls it demands more still.
Connect a motor directly and one of three things happens: the motor barely twitches, the board browns out and resets, or the pin is permanently damaged. Sometimes the pin dies quietly and everything else keeps working, which is worse, because you spend the next week wondering why one particular pin no longer does anything.
The fix is a driver — a component that sits between the controller and the motor. Your low-current signal pin tells the driver what to do; the driver switches the motor's much larger current, drawn straight from the battery. An L298N module does this for two DC motors and is the standard beginner choice. For a single motor turning one way, a transistor with a flyback diode is enough.
Motors and relays are inductive loads, and inductors resist sudden changes in current. When the current is switched off, the collapsing magnetic field produces a brief voltage spike in the opposite direction, which can be far higher than the supply voltage and can destroy whatever switched it. A flyback diode placed across the motor gives that spike a harmless path to circulate through instead. Ready-made driver modules include this protection already, which is one more reason to use one rather than improvise.
// WRONG - this can damage the pin and will not drive the motor properly
// motor red wire -> Arduino pin 9
// motor black wire -> Arduino GND
// RIGHT - the pin only sends a signal; the battery supplies the power
// Arduino pin 9 -> driver ENA (speed)
// Arduino pin 8 -> driver IN1 (direction)
// Arduino pin 7 -> driver IN2 (direction)
// battery + -> driver motor supply input
// battery - -> driver GND
// Arduino GND -> driver GND <-- the shared ground, never skip this
// driver OUT1/OUT2 -> the two motor terminals - The same rule applies to anything with a coil in it, including relays and solenoids. If a component has a magnet and a winding, it needs a driver and a flyback diode.
- Check the specification for your particular board before assuming how much current a pin can supply. It is a few tens of milliamps at most on a typical Arduino, and there is also a limit on the total drawn across all pins at once, which is easy to exceed with several LEDs lit together.
Power, and Why Everything Must Share a Ground
Once your robot has motors, it needs two supplies rather than one: a clean, steady supply for the controller and sensors, and a bigger, rougher one for the motors. Running both from a single small battery is what causes the classic symptom of a robot that resets every time it tries to move — the motors momentarily pull the voltage down below what the controller needs to keep running.
For bench work, USB from your laptop powers the board fine and is the easiest way to develop. It cannot power motors or several servos, so a robot that must move needs its own battery pack. A pack of AA cells in a holder is cheap and adequate to begin with. Rechargeable packs last longer and are more economical over a term, at the cost of needing a proper charger.
The part almost nobody is told in advance: separate supplies must share a common ground. In electronics, a voltage is never absolute — it is always a difference measured between two points, and "ground" is the agreed zero that everything is measured against. If your Arduino's ground and your motor battery's ground are not wired together, the two halves of the circuit have no shared reference. Your signal pin might read as HIGH to the driver, or LOW, or something in between that changes as the motors load the battery.
The symptoms of a missing common ground are unmistakable once you have seen them: motors that twitch at random, a robot that works only while the USB cable is plugged in and dies the moment you unplug it, sensors that give nonsense readings whenever the motors run. It is not a software problem and no amount of code will fix it. One wire from the Arduino's GND to the battery's negative rail solves it completely.
- USB from a computer — fine for the board and sensors while you write code; not for motors
- A holder of AA cells — cheap, easy to find anywhere, good for a first mobile robot
- A rechargeable pack — better value over time, but use a charger made for that battery chemistry
- A power bank — convenient 5 V, though some switch themselves off when a robot draws too little current
- Always connect the grounds of every supply together, and never connect two different positive supplies to the same rail
- Do not run a motor supply into the Arduino's 5 V pin. That pin is an output of the board's own regulator, and feeding voltage back into it bypasses the protection the board relies on. Motor power goes to the driver module's power input, and only the ground is shared.
