AnyLearn
All lessons
Roboticsbeginner

Closing the Loop: Microcontrollers and Feedback

Open-loop control is a guess; closed-loop control is a conversation. Learn why feedback transforms an unreliable robot into a reliable one, how the read-compute-actuate cycle works, what microcontrollers and single-board computers each do best, and why loop timing is just as critical as the algorithm running inside it.

Not signed in — your progress and quiz score won't be saved.
Lesson progress1 / 10

The problem with blind commands

Imagine telling someone to walk exactly 10 meters by saying: take 14 steps and stop. On smooth tile that might work. On carpet, uphill, or after fatigue, 14 steps might get you 8 meters — or 12. You have no way of knowing without looking.

This is open-loop control: you send a command and trust the output matches your intention, with no mechanism to check or correct. It works when the system is very predictable — a microwave timer, a garage door opener. It fails when the world varies.

Robots live in the real world, which is relentlessly variable. Motor characteristics drift with temperature. Wheels slip on wet floors. Payloads change. Batteries deplete. Open-loop control fails in all of these situations.

The solution is to close the loop: measure what actually happened, compare it to what you wanted, and use the difference to adjust the next command. This single idea — feedback — is what separates reliable robots from expensive toys.

Full lesson text

All 10 steps on one page — for reading, reference, and search.

Show

1. The problem with blind commands

Imagine telling someone to walk exactly 10 meters by saying: take 14 steps and stop. On smooth tile that might work. On carpet, uphill, or after fatigue, 14 steps might get you 8 meters — or 12. You have no way of knowing without looking.

This is open-loop control: you send a command and trust the output matches your intention, with no mechanism to check or correct. It works when the system is very predictable — a microwave timer, a garage door opener. It fails when the world varies.

Robots live in the real world, which is relentlessly variable. Motor characteristics drift with temperature. Wheels slip on wet floors. Payloads change. Batteries deplete. Open-loop control fails in all of these situations.

The solution is to close the loop: measure what actually happened, compare it to what you wanted, and use the difference to adjust the next command. This single idea — feedback — is what separates reliable robots from expensive toys.

2. Open-loop vs closed-loop: a concrete comparison

The difference is easiest to see with a simple example: making a robot wheel spin at 100 RPM.

Open-loop approach: Measure the motor at 6 V on a test bench; 100 RPM appears. In production, always apply 6 V. Done — until the battery drops to 5.5 V (motor slows) or the wheel hits a ramp (motor slows more).

Closed-loop approach: Read the encoder to get actual RPM. If actual < target, increase voltage. If actual > target, decrease voltage. Repeat at 100 Hz.

PropertyOpen-loopClosed-loop
Requires sensorNoYes
Handles disturbancesNoYes
Hardware complexityLowHigher
AccuracyVaries with conditionsConsistent
Risk of instabilityNeverPossible if tuned poorly

Open-loop is appropriate when accuracy requirements are low and the system is stable — a cooling fan, a conveyor belt at fixed speed. Closed-loop is mandatory whenever precision, reliability, or safety matters.

3. Bang-bang control: the simplest feedback

The simplest closed-loop algorithm is bang-bang control (also called on/off control or the thermostat rule): if the measured value is below the target, turn on full power; if it's above, turn off completely.

Your home thermostat works this way. Here it is as code:

# Bang-bang temperature controller
TARGET_TEMP = 22.0   # degrees Celsius
HYSTERESIS  = 0.5    # prevent rapid switching

while True:
    current_temp = read_temperature_sensor()

    if current_temp < TARGET_TEMP - HYSTERESIS:
        heater_on()
    elif current_temp > TARGET_TEMP + HYSTERESIS:
        heater_off()
    # else: maintain current state

    sleep(1)  # check once per second

The hysteresis band prevents the system from switching on and off fifty times per second as noise pushes the reading back and forth across the threshold. Without it, the heater relay would burn out in hours.

Bang-bang is robust and simple. Its weakness: the output oscillates around the target rather than settling smoothly. For temperature control that's fine (±0.5°C is good enough). For a robotic joint that needs to hold still at 90°, the constant back-and-forth is unacceptable — that's where PID control enters, covered in later lessons.

4. The read-compute-actuate cycle

Every closed-loop robot controller — from a thermostat to a Boston Dynamics leg — executes the same three-phase cycle, over and over:

  1. Read: Sample all relevant sensors. Store the values.
  2. Compute: Run the control algorithm. Given current state and desired state, calculate what command to send.
  3. Actuate: Send the command to the motor driver, servo, valve, or other actuator.

Then immediately go back to step 1.

The rate at which this cycle repeats is the loop rate (or control frequency), measured in Hz. A robot arm might run its inner joint velocity loop at 1 kHz and its outer position loop at 100 Hz. A slow mobile robot might get away with 20 Hz. A drone's attitude controller typically runs at 500–2000 Hz to stay stable.

The key design principle: the loop rate must be fast enough that the system cannot change significantly between two successive readings. If your drone can tilt 5° in 10 ms, a 10 Hz loop sampling every 100 ms will miss that tilt entirely — the drone crashes before the controller ever knew there was a problem.

5. Microcontrollers vs single-board computers

The compute pillar of a robot can be filled by very different hardware depending on what the loop needs:

FeatureMicrocontroller (e.g. Arduino Uno)Single-board computer (e.g. Raspberry Pi 4)
Boot timeInstant (microseconds)Slow (10–30 seconds)
OSNone (bare metal) or RTOSLinux (not real-time by default)
Timing precisionMicrosecond-levelMillisecond-level at best
Processing powerLowHigh
Camera / visionNoYes
Typical roleMotor control, sensor readingPath planning, vision, ROS
Power drawVery low (mA)Medium (2–5 W)

For tight, time-critical loops — reading encoders, sending PWM, running a PID controller — a microcontroller is often the right choice. It boots instantly, runs deterministically, and responds within microseconds.

For tasks requiring heavy computation (processing a camera feed, running a navigation algorithm) a single-board computer or a dedicated compute module is needed. Many real robots use both: an Arduino handles real-time motor control while a Raspberry Pi handles perception and high-level planning, communicating over serial or I2C.

6. Real-time constraints and what 'real-time' actually means

Real-time does not mean fast. It means deterministic — the system guarantees that a computation will complete within a specific time bound, every single time. A 1 kHz control loop is real-time if it reliably executes in under 1 ms. It is not real-time if it sometimes takes 1.1 ms.

Standard Linux (as on a Raspberry Pi) is not real-time by default. The OS scheduler may suspend your control loop to handle a file system write or a network packet, introducing unpredictable delays called jitter. For a fast drone controller, 5 ms of jitter is catastrophic.

Solutions, in order of increasing rigor:

  1. Offload to a microcontroller: Let the Pi do planning; let the Arduino do motor control.
  2. PREEMPT-RT patch: Turns Linux into a soft real-time OS; jitter typically reduces to tens of microseconds.
  3. Dedicated RTOS: FreeRTOS, Zephyr, or CycloneDX on a microcontroller gives hard real-time guarantees.
  4. FPGA: For sub-microsecond timing (motor current control, encoder counting), an FPGA runs at hardware speed with zero OS overhead.

For most beginner robots, offloading to a microcontroller is sufficient. Understanding why timing matters is more important than the specific solution.

7. Latency: the enemy of fast control

Latency is the total delay from when something happens in the world to when the robot's actuator responds. It accumulates from several sources:

  • Sensor latency: A camera at 30 Hz delivers a frame up to 33 ms after capture; the image is already 33 ms old when the algorithm sees it.
  • Compute latency: Running a neural-network perception model might take 20–50 ms.
  • Communication latency: Sending a command over USB serial adds 1–5 ms; over Ethernet, less.
  • Actuator latency: A servo takes time to move; a hydraulic valve takes time to open.

Total latency of 100 ms doesn't sound like much — until you consider that a drone at 10 m/s travels 1 meter in that time. The controller always thinks the drone is 1 meter behind where it actually is.

The practical response: minimize latency where it matters most (sensor → controller pipeline for fast inner loops), and design control algorithms that account for the delays that remain. Predictive controllers, for instance, explicitly model expected latency and act as if looking slightly into the future.

8. A complete closed-loop example on Arduino

Here is a minimal closed-loop speed controller for a DC motor on an Arduino, using encoder feedback and bang-bang control as a baseline:

#include <Arduino.h>

const int ENCODER_PIN = 2;   // interrupt pin
const int MOTOR_PIN   = 9;   // PWM output
const int TARGET_RPM  = 100;

volatile long pulses = 0;
const int PPR = 360;         // pulses per revolution

void countPulse() { pulses++; }

void setup() {
  pinMode(MOTOR_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(ENCODER_PIN),
                  countPulse, RISING);
  Serial.begin(9600);
}

void loop() {
  // Sample window: 100 ms
  pulses = 0;
  delay(100);
  long p = pulses;  // snapshot

  // Convert pulses in 100 ms to RPM
  float rpm = (p / (float)PPR) * 600.0;  // 600 = 60s/0.1s

  // Bang-bang: full on or full off
  if (rpm < TARGET_RPM) analogWrite(MOTOR_PIN, 200);
  else                  analogWrite(MOTOR_PIN, 100);

  Serial.print("RPM: "); Serial.println(rpm);
}

This loop reads encoder pulses over 100 ms, converts to RPM, and adjusts PWM. It oscillates around the target — a PID controller would smooth that out — but it reliably holds near 100 RPM regardless of battery sag or load changes.

9. Choosing your loop rate in practice

There's no universal correct loop rate. Here's how engineers decide:

  1. Know your system's fastest dynamic. A pendulum balancing robot tips at ~10 rad/s; to control it you need a loop at least 10× faster — 100 Hz minimum, preferably 500 Hz.
  2. Match sensor sampling rate. There's no point running a control loop at 1 kHz if your sensor samples at 100 Hz — you're just re-reading stale data 10 times.
  3. Budget compute time. Your control algorithm must finish well within one loop period. A 1 kHz loop has 1 ms per cycle; don't put a blocking file-read in there.
  4. Test stability margins. Too slow → instability or sluggish response. Too fast → numerical noise and CPU waste. Tune empirically.

A useful rule of thumb: run the inner (velocity/torque) loop at 10–100× the outer (position/path) loop. Industrial drives run current control at 20 kHz, velocity control at 2 kHz, position control at 200 Hz — exactly this nested ratio.

Once you have a working loop rate, guard it. Add watchdog timers. Alarm when a cycle runs long. Timing bugs are among the hardest to reproduce and the most dangerous in fielded robots.

10. From thermostat to robot: the same idea at every scale

The core insight of this lesson is that closed-loop feedback is a single powerful idea that scales from a 5thermostattoa5 thermostat to a 5 million industrial arm:

  • A thermostat measures temperature, compares to setpoint, toggles a relay.
  • A quadrotor measures orientation from an IMU, compares to desired attitude, adjusts four motor speeds — at 1 kHz.
  • A robotic surgery system measures tool tip force, compares to a safe limit, scales the surgeon's hand movements — with sub-millimeter accuracy.

The algorithm in the middle changes (bang-bang → PID → model predictive control), but the structure never does: read, compute, actuate, repeat.

That's the lesson to carry forward. Future lessons will fill in the algorithm box — starting with PID control, the workhorse of industrial robotics. But PID only makes sense once you've internalized why the loop exists, how fast it must run, and what happens when timing goes wrong.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. A robot applies a fixed PWM signal to a motor to reach 50 cm/s, with no sensor feedback. The battery voltage drops 10% partway through a run. What happens?
    • The motor compensates automatically and maintains 50 cm/s.
    • The robot slows down because the open-loop controller has no way to detect or correct the speed drop.
    • The motor encoder sends an error signal and the controller reduces the target speed.
    • The PWM frequency increases to compensate for the lower voltage.
  2. In the bang-bang thermostat code, why is a hysteresis band added around the target temperature?
    • To increase the heater's average power output.
    • To prevent rapid on/off switching from sensor noise crossing the threshold repeatedly.
    • To allow the temperature to overshoot by a safe margin before cooling.
    • To reduce the sampling rate of the temperature sensor.
  3. Why is a standard Raspberry Pi running Linux generally unsuitable for a 1 kHz robot joint controller?
    • The Raspberry Pi's GPIO pins do not support PWM output.
    • Linux is not real-time by default — the OS scheduler can delay the control loop by unpredictable amounts.
    • The Raspberry Pi draws too much current to operate motors directly.
    • Python cannot execute loops faster than about 100 Hz.
  4. In the nested loop architecture of an industrial drive, which loop typically runs fastest?
    • The path planning loop, because it determines the overall trajectory.
    • The position loop, because position accuracy is the final goal.
    • The current (torque) loop, because it must respond to electrical dynamics in microseconds.
    • All loops run at the same rate to stay synchronized.
  5. A drone's camera has 30 ms latency and the compute pipeline adds 50 ms. The drone flies at 8 m/s. How far has the drone traveled between image capture and the moment the controller acts on that image?
    • About 0.24 m (24 cm)
    • About 0.64 m (64 cm)
    • About 1.5 m
    • About 4 cm

Related lessons