Closed-loop control is a system where a microcontroller continuously reads sensor feedback to adjust its output and correct errors, whereas open-loop control blindly sends commands without verifying the physical result. In a real robotics circuit, implementing a closed loop changes a blind, stall-prone PWM signal into a dynamic feedback architecture, meaning your robot can maintain a set speed up a ramp or hold a robotic arm perfectly still against gravity. Makers commonly confuse closed-loop control architecture (the software feedback loop you code) with closed-loop stepper motors (a specific, expensive hardware package with an integrated encoder), or assume standard RC servos are open-loop because the feedback happens internally.
The Core Architecture: How Feedback Changes the Circuit
When you build DIY robotics tech using open-loop actuators (like standard stepper motors or basic DC motors), your microcontroller simply outputs a pulse train or a static PWM duty cycle. The MCU assumes the physical world obeys the command. If the robot hits a carpet edge, the open-loop DC motor slows down, and the MCU does nothing to compensate. The robot drifts.
By adding an encoder (optical or magnetic) and closing the loop, you introduce an error-calculation step into your firmware. The MCU reads the encoder, calculates the delta between the target state and the actual state, and feeds that error into a control algorithm (like PID). The output of that algorithm dictates the new PWM duty cycle. This requires hardware interrupts or dedicated peripherals (like the ESP32's PCNT) to count encoder pulses without bogging down the main CPU loop.
The Math in Motion: A Worked Numeric Example
Let us look at a concrete Proportional (P) control calculation for a DC gearmotor. We will use a JGA25-370 DC gearmotor paired with an AS5600 12-bit magnetic encoder (4096 steps per revolution).
- Target Speed: 100 RPM
- Encoder Resolution: 4096 counts/rev
- Target Counts per Second: (100 / 60) * 4096 = 6826 counts/sec
- Sample Rate: 50ms (20 Hz control loop)
- Target Counts per Sample: 6826 / 20 = 341 counts
During the last 50ms window, the ESP32 reads the encoder and finds it only moved 280 counts. The motor is bogging down under a physical load.
We apply a Proportional Gain ($K_p$) of 0.5. The required PWM adjustment is Error * $K_p$ = 61 * 0.5 = 30.5 (rounded to 31). If our current PWM duty cycle was 120 (out of 255), the microcontroller updates the H-bridge driver to a new PWM value of 151 (120 + 31). The motor receives more voltage, torque increases, and the speed recovers to the 100 RPM target in the next cycle.
Where You Meet This in Practice
You will encounter the open vs closed-loop decision in almost every DIY robotics tech project, but it manifests differently depending on the application:
- Self-Balancing Robots (Inverted Pendulums): Strictly closed-loop. An IMU (like the MPU6050) provides angle feedback at 200Hz+ to a PID controller that drives the wheels. Open-loop is physically impossible here; the robot would fall over instantly.
- Robotic Arms and CNC Routers: Often open-loop using NEMA stepper motors. The high holding torque and precise step angle of steppers mean the MCU can blindly send step pulses and trust the motor moved. Closed-loop is only added if the arm lifts heavy, variable payloads where missed steps would ruin the project.
- Line-Following and Odometry: Differential drive robots use closed-loop motor control to ensure both wheels spin at the exact same RPM. Without it, slight manufacturing differences in the DC motors cause the robot to veer off course even when the MCU commands identical PWM values to both sides.
Decision Tree: Picking Your Actuator Architecture
Do not default to the most complex architecture. Use this decision path to select the right motor and control style for your specific mechanical requirements.
| Mechanical Requirement | Control Architecture | Concrete Hardware Pick |
|---|---|---|
| Need high holding torque at zero speed, precise incremental positioning, low coding effort. | Open-Loop Stepper | NEMA 17 + TMC2209 Driver |
| Need high continuous speed, dynamic load handling, battery efficiency, and stall recovery. | Closed-Loop DC Motor | JGA25-370 + AS5600 Encoder + TB6612FNG |
| Need simple positional holding under 180 degrees, low cost, zero custom PID tuning. | Internal Closed-Loop (Servo) | MG996R RC Servo |
Hardware Reality: Microcontrollers, Drivers, and Encoders
Executing a closed-loop algorithm requires hardware that can handle high-frequency sensor interrupts without dropping step counts. Here is the exact bill of materials for a robust 2026-era DIY robotics drivetrain:
The Brain: ESP32-S3
While an Arduino Uno can run a basic PID loop, it struggles with multiple encoders and WiFi telemetry simultaneously. The ESP32's Pulse Counter (PCNT) peripheral is a hardware-level accumulator. It counts encoder edges in the background without firing a CPU interrupt for every single pulse, freeing up your main cores to run the PID math and ROS 2 micro-ROS nodes.
The Muscle: TB6612FNG Dual Motor Driver
Skip the ancient L298N. It uses bipolar junction transistors that drop nearly 2V to 3V of your battery voltage as heat. The TB6612FNG uses MOSFETs, dropping only about 0.5V at 1A. It handles 1.2A continuous per channel (3.2A peak), costs around $3 to $6, and supports PWM frequencies up to 100kHz, allowing you to push the motor whine out of human hearing range.
The Senses: AS5600 Magnetic Encoder
Optical encoders are fragile and sensitive to dust. The AS5600 12-bit magnetic rotary encoder reads a diametrically magnetized shaft through I2C or analog output. It provides 4096 steps per revolution, costs about $2, and is virtually immune to the dust and grit encountered in mobile robotics.
FAQ: Common DIY Robotics Tech Stumbling Blocks
Why does my closed-loop DC motor oscillate and vibrate at standstill?
This is caused by an overly aggressive Proportional ($K_p$) or Derivative ($K_d$) gain in your PID controller. When the error approaches zero, the high gain causes the MCU to overshoot the target, reverse the PWM, and overshoot again. Lower your $K_p$ value by 20% and introduce a small "deadband" in your code (e.g., if the absolute error is less than 5 counts, output 0 PWM instead of calculating a correction).
Can I just use a standard RC servo for a robotic arm instead of coding a closed-loop DC motor?
Yes, for light payloads (under 1kg) and slow movements. An MG996R servo contains a potentiometer and an internal analog control board that handles the closed-loop math for you. However, RC servos draw massive current spikes when stalling, have poor positional resolution compared to a digital encoder, and cannot easily be back-driven for compliant control.
Do I need to tune my PID controller every time I change the battery?
If you are using raw PWM values (0-255) as your controller output, yes. A fully charged 2S LiPo (8.4V) will spin the motor much faster at PWM 150 than a depleted LiPo (6.4V). To fix this, implement voltage compensation in your firmware: read the battery voltage via an ADC voltage divider, and scale your PID output by the ratio of (Nominal Voltage / Actual Voltage) before sending it to the motor driver.






