Robot Electronics Foundations: A Learning Roadmap
Power a robot that stays up under load, put several sensors on one I²C bus, and write a loop that reads them all without ever blocking.
Most robot problems that look like software problems are not. The board resets and the code is blamed; a sensor returns nonsense and the library is blamed; the robot ignores its bumper and the logic is blamed. In each case the fault is a layer below, in the part of the system nobody wrote a tutorial about because it felt too basic to need one.
This path is that layer. It covers power — why a battery’s voltage collapses when the motors start and what to do about it; the I²C bus — what those two wires shared by every sensor are actually doing; and timing — why a loop that stops to wait is a robot that cannot react.
None of it is difficult. All of it is assumed by every other path on this site.
Before you start
You need a microcontroller you can already flash and the willingness to put a multimeter across a battery. No control theory, no maths beyond addition and one division. If you have built anything at all — even a blinking LED — you are ready.
What you will be able to do
- Tell a reset apart from a crash in under a minute, and know which one you are looking at before you open any code.
- Add up a robot’s current draw and pick a battery pack from that number, rather than from what came in the kit.
- Explain why a 9 V block with the highest voltage on the shelf gives the worst result under load, and predict how far any pack will sag.
- Wire several sensors onto one I²C bus, find them with a scanner, and resolve an address collision three different ways.
- Write a loop that reads sensors, drives motors and reports status at three different rates without ever blocking — and get the rollover comparison right.
- Measure your own worst-case loop time instead of assuming it.
Where people get stuck
Treating “it did not reset” as evidence the power is fine. An Arduino’s brown-out detector is set at 2.7 V, but a 16 MHz ATmega328P needs about 3.8 V to be within its rated speed. In that band the chip runs outside spec and nothing intervenes, which is where the weirdest faults on a robot live — corrupted variables, a servo that jumps, a sensor returning plausible nonsense.
Adding a capacitor and expecting it to fix a reset. The arithmetic says otherwise: a 1000 µF cap asked to carry a 2 A surge for 10 ms would drop 20 V. It cleans up switching ripple and commutation spikes, which is worth doing, but only a stiffer battery carries the surge.
Stacking breakout boards on one bus. Almost every board ships with its own pull-up resistors, and they go in parallel. Three boards is marginal and the fourth drops the bus below the current any device can sink — so three sensors work and the fourth kills all of them, with nothing actually broken.
Reading an 8-bit address from a datasheet. An MPU-6050’s datasheet says 0xD0; the Arduino
library wants 0x68, the same bits shifted right by one. This is the single most common I²C
mistake, and it looks exactly like a dead board.
Writing now >= last + interval. It reads more naturally than the subtraction form and it
breaks at the 49.7-day rollover, firing continuously instead of waiting. Always subtract.
Blaming the loop logic for a blocked loop. Interrupts keep running during delay(), so an
encoder count stays perfectly correct while the robot stops reacting — which makes the symptom
look like a decision-making bug rather than a timing one.
What you need
| What | Why this path needs it | Rough cost |
|---|---|---|
| A microcontroller you can flash | Every measurement here is taken on a running board, not on paper | Arduino Uno, ~$8 clone |
| A multimeter | The one instrument this path cannot do without — every claim it makes is one you verify yourself | ~$15 |
| A battery pack under load | A pack measured with nothing attached tells you nothing; you need one driving something | 4×AA holder or 2S Li-ion |
| Two I²C breakout boards | One board never shows you the pull-up problem. Two start to. | MPU-6050 + anything, ~$5 |
| A motor or two | The load that makes the rail sag — the fault this path exists to explain | Any DC gearmotor |
No oscilloscope. Every measurement on this path is a DC one a cheap multimeter can take.
Why the path runs in this order
The order is not arbitrary — each node removes a way the next one could lie to you.
Timing comes before everything measured. A blocked loop makes every other measurement suspect, because you can no longer say when a reading was taken. Once the loop is non-blocking you can trust a timestamp, and only then is a measurement worth writing down.
Power comes before analog. analogRead on an Arduino is ratiometric — it reports the
input as a fraction of its reference, and the default reference is the same 5 V rail the
motors are dragging down. Measure a battery through a divider on a sagging rail and the
reading rises as the battery falls. Reading a voltage honestly is impossible until you know
what your rail is doing, so the power node has to come first.
I²C comes after power but is independent of analog. The bus is a separate subsystem, and it fails in its own way — through pull-up arithmetic and address collisions, not through supply sag. It hangs off the board node directly, which is why the tree branches there.
The lab comes last. The sensor simulator lets you add noise, bias and dropouts to a clean signal deliberately. That is only instructive once you have seen your own hardware produce them accidentally and know what caused each one.
Checkpoints: how to know a stage landed
Each of these is a bench test, not a quiz. If you cannot produce the number, the stage is not done.
| Stage | The check | What a pass looks like |
|---|---|---|
| Non-blocking timing | Print your loop’s worst-case duration over 10 seconds | A number in microseconds you measured, not one you assumed — and it does not grow when a sensor is unplugged |
| Battery under load | Measure pack voltage with motors off, then stalled | You can state the sag in volts and divide it by the current to get the pack’s internal resistance |
| Power budget | Add up every device’s current draw on paper, then measure the total | Paper and meter agree within about 20%; if they do not, you have found a device drawing more than its datasheet claims |
| Analog input | Read the same battery through your divider with the motors off and running | The reading does not change when the motors start — if it does, your reference is moving |
| I²C bus | Run a bus scanner with each board added one at a time | Every address appears, and you can name the total pull-up resistance on the bus |
| Address collision | Strap the MPU-6050’s AD0 pin high | The scanner reports 0x69 instead of 0x68 — and you can explain why the datasheet says 0xD0 |
Where this path stops
This roadmap deliberately stops at the point where the electronics stop lying to you. It does not cover motor drivers, control loops, or anything that decides where a robot should go — those are the motor control and PID control paths, and both assume everything here.
It also stops short of three things worth naming so you know they exist. It does not cover switching regulators, which is how you get 5 V from a 12 V pack without burning the difference as heat in a linear regulator. It does not cover level shifting between 5 V and 3.3 V devices, which you will need the first time you put an ESP32 and a 5 V sensor on the same bus. And it does not cover PCB layout or soldering — everything here is done on a breadboard, which is fine for learning and is itself a source of intermittent faults once a robot starts moving.
Learning roadmap
The path
Follow the nodes in order—each unlocks the next once you have done it. Your progress saves on this device.
0 / 9 done
Common questions
Frequently asked questions
What electronics do I need to know before building a robot?
Three things, and none of them are advanced. You need to size a power supply from the current your robot actually draws, so it does not reset when the motors start. You need to understand the I²C bus well enough to put several sensors on two shared wires without them fighting. And you need to write a control loop that never stops to wait, so the robot can react while it is doing something else. Everything else—control theory, navigation, kinematics—sits on top of those three.
Why does my Arduino reset when the motors start?
The battery's internal resistance turns the motors' inrush current into a voltage drop, and the whole rail sags with it. A motor drawing a 2 A surge through a pack with 0.5 Ω of internal resistance pulls the rail down by a full volt before anything reaches the regulator. If that dip takes the board below its brown-out threshold, it restarts. The fix is a stiffer battery and a separate motor supply, not a bigger capacitor—a 1000 µF capacitor asked to carry 2 A for 10 ms would drop 20 V, so it cannot bridge a surge of that size.
How many I²C sensors can I put on one Arduino?
The address space allows 112 devices, but the electrical limit arrives long before that. Almost every breakout board carries its own pull-up resistors, typically 4.7 kΩ, and stacking boards puts those resistors in parallel. Four boards give roughly 1.2 kΩ, which at 5 V demands more than 4 mA of sink current—past the 3 mA an I²C device is required to handle. Three boards usually work and the fourth kills the whole bus. Remove the pull-ups from all but one board and you can go much further.
Is delay() really that bad in robot code?
For a robot, yes. While the processor sits in delay() it reads no sensors and makes no decisions—a robot in delay(500) is blind for half a second, which at 0.3 m/s is 15 cm of travel. What makes it hard to diagnose is that interrupts keep running, so encoder counts stay perfectly correct the whole time. The symptom looks like broken decision logic rather than blocked timing. Replace it with the millis() pattern, and subtract rather than add when you compare, or the comparison breaks at the 49.7-day rollover.
Do I need an oscilloscope to work through this path?
No. A multimeter is enough for everything here—measuring a battery's voltage under load, checking a divider's output, confirming a rail has not sagged. A scope makes brown-outs and I²C problems far easier to see, and if you own one you should use it, but every measurement this path asks for is a DC one a £10 meter can take.
How long does this roadmap take?
About two hours of reading across the four tutorials, and realistically an evening or two at the bench to actually do the measurements. The measurements are the point—the numbers this path teaches you to trust are your own battery's sag, your own bus's pull-up total, and your own loop's worst-case time, none of which can be looked up.