When a ping pong ball is dropped onto the platform, BaBot detects it within approximately 25 milliseconds and begins correcting its position roughly 40 times every second — creating smooth, continuous balance.
Detecting the Ball
The Challenge
The system must determine the ball's position with millimeter accuracy, 40 times per second, using an invisible light grid beneath the platform.
IR Light
IR (Infrared) light is light that's just beyond what human eyes can see — the wavelength is longer than visible red light but remains completely invisible to humans. This allows BaBot to use constant bright illumination without any visual distraction.
The Sensing System
The IR Sensors PCB contains 21 IR LEDs that continuously emit infrared light upward through the transparent PMMA platform, and 16 IR phototransistors arranged in a 4×4 grid that detect how much light is reflected back down.
Each phototransistor acts like a light-sensitive switch — more light produces proportionally more electrical current.
Without a ball: IR light disperses and phototransistors detect minimal reflection.
With a ball: The smooth surface of the ping pong ball reflects IR light directly back down like a mirror, creating bright spots in the sensor readings directly beneath the ball. Sensors closer to the ball register higher brightness values.
Ambient Light Subtraction
Room lighting (sunlight, artificial lights, screens) also emits infrared and would interfere with readings. BaBot eliminates this noise with a three-step process every cycle:
- LEDs OFF: Measure each sensor to capture background IR from the room.
- LEDs ON: Measure again with IR LEDs active.
- Subtract: Ball signal = (LEDs ON reading) − (LEDs OFF reading).
// Measure ambient light (LEDs off)
digitalWrite(IR_LED_PIN, LOW);
for (int i = 0; i < 16; i++) {
ambientLight[i] = analogRead(sensor[i]);
}
// Measure with IR LEDs on
digitalWrite(IR_LED_PIN, HIGH);
for (int i = 0; i < 16; i++) {
irLight[i] = analogRead(sensor[i]);
}
// Calculate actual signal from the ball
for (int i = 0; i < 16; i++) {
irSignal[i] = irLight[i] - ambientLight[i];
}
Weighted Centroid: 16 Readings → 1 Position
The 16 sensor values are converted into a single precise X,Y coordinate using a weighted centroid calculation. Each sensor's position is weighted by its brightness reading — the result is the mathematical center of the brightness distribution.
- X position = (sum of each sensor's X coordinate × brightness) ÷ (total brightness)
- Y position = (sum of each sensor's Y coordinate × brightness) ÷ (total brightness)
Even when the ball sits between sensors, the weighted average determines the exact position with millimeter precision.
PID Control — The Brain of BaBot
Once the ball's position is known, BaBot must decide how much to tilt the platform to move the ball back to center. Tilting too little leaves the ball off-center; tilting too much causes overshoot and oscillation. This is solved by a PID controller — the same algorithm used in cruise control, thermostats, and drone stabilization.
Output = KP·e(t) + KI·∫e(t) dt + KD·de(t)/dt
Proportional
Tilts proportionally to how far the ball is from center. A 1 cm error produces a 3° tilt; a 2 cm error produces a 6° tilt.
P_term = KP × e(t)
KP = 3.0
Integral
Accumulates error over time to eliminate steady-state drift caused by friction, slight breeze, or platform imperfection. Once centered, stops growing.
I_term = KI × ∫e(t) dt
KI = 0.02
Derivative
Measures the rate of change of error to predict ball motion and prevent overshoot. Acts as a brake when the ball moves quickly toward center.
D_term = KD × de(t)/dt
KD = 30.0
BaBot runs two independent PID calculations — one for each axis:
Y axis (pitch): θ_pitch = KP·ey + KI·Σey + KD·Δey
Tuning the Gains
You can modify the three gain values in the firmware to change BaBot's behavior:
- Increase KP: Faster response, but potentially more oscillation.
- Increase KI: Eliminates steady-state error faster; too much causes "wind-up" and overshoot.
- Increase KD: Smoother motion with better oscillation damping; too much creates aggressive jerky response.
Adjusting these values in real-time is one of the best ways to develop intuition for control systems.
Inverse Kinematics — From Angles to Servos
The PID controller outputs two angles (roll and pitch). But BaBot has three servo motors arranged in a triangle — not two separate roll/pitch motors. Converting two angles into three servo positions is a geometry problem called inverse kinematics.
Mechanism Architecture
- Three servo motors positioned 120° apart around the circular base.
- Each servo controls a two-segment arm: lower arm 50 mm, upper arm 39.2 mm.
- Platform attachment points also spaced 120° apart.
- Neutral state: all three servos at the same angle = level platform at 65 mm height.
A three-point support gives full 3D tilt control with minimal complexity. Three motors at 120° is the mechanically optimal configuration — the same principle as a Stewart platform used in flight simulators and precision machining.
The Three-Step Solution
- Calculate attachment point locations: Starting from a level position at 65 mm height, apply rotational mathematics (sine/cosine) to find where each of the three platform attachment points ends up in 3D space after the desired roll and pitch rotations.
- Solve geometry for each servo: For each servo, use the law of cosines to find the angle that connects the base position to the platform attachment point using the known arm lengths (50 mm + 39.2 mm).
- Command servos: Transmit all three calculated angles simultaneously to the servo motors.
Concrete Example
PID requests a 4° right tilt (roll), 0° pitch:
| Servo | Base position | Commanded angle |
|---|---|---|
| Servo A | 0° | 72° |
| Servo B | 120° | 68° |
| Servo C | 240° | 68° |
Result: platform tilts precisely 4° right — ball experiences a slope pulling it toward center.
Technical Specifications
| Parameter | Value |
|---|---|
| IR sensors | 16 (4×4 grid) |
| IR LEDs | 21 distributed |
| Control loop frequency | 40 Hz (~25 ms per cycle) |
| Lower arm length | 50 mm |
| Upper arm length | 39.2 mm |
| Platform height (neutral) | 65 mm |
| Servo base spacing | 120° apart |
| Proportional gain (KP) | 3.0 |
| Integral gain (KI) | 0.02 |
| Derivative gain (KD) | 30.0 |
The Complete Loop
This entire sequence occurs in milliseconds, repeating 40 times per second:
- 01
Sense
Measure ball position via 16 IR sensors using ambient light subtraction.
- 02
Calculate
Weighted centroid algorithm converts 16 readings into precise X,Y coordinates.
- 03
PID
PID algorithm calculates required roll and pitch angles to move the ball toward center.
- 04
Kinematics
Inverse kinematics converts roll/pitch into three independent servo angles.
- 05
Move
Servo motors move simultaneously. Platform tilts. Ball rolls toward center. Repeat.