This is the full dataset behind Your Servo Is Lying To You — every plot the MATLAB analysis toolkit produced for all nine units, not just the handful that made it into the article itself. Laid out the same way the toolkit itself lays it out: one figure per servo family, one subplot per unit. Same ground truth, same 55,029 trials, just the unabridged version for anyone who wants a specific unit’s own curve rather than the pooled numbers.
One methodology note that applies throughout: a couple of the raw naive-sweep traces below have a real, reproducible glitch right near their low-pulse edge — a wrap/backoff artifact, not a fabricated data point — and are cleaned the same way the MATLAB toolkit itself cleans them (drops a non-monotonic tail once the sweep’s direction sustainedly reverses). Nothing is smoothed or adjusted beyond that; every curve here is the servo’s own measured response.
A caveat added after this page first went up: every unit’s maximum pulse below was capped by a firmware bug, not each servo’s real mechanical limit — the range-finding firmware’s pulse ceiling was set to a value the AVR Servo library’s own pulse encoding silently overflows, clamping every commanded pulse above ~2076µs down to exactly 2076µs. It’s visible in hindsight: every one of the nine units below reports a max pulse within a few dozen microseconds of 2076, regardless of family or gear ratio — not what nine independent mechanical limits should look like. Re-running two of the nine units (Miuzei unit 3, MG90D unit 3) on the fixed firmware found real ranges far wider than shown here — 313° and 308° respectively, against the 236.2° and 229.8° this page still shows for them — and re-ran the article’s core comparison (naive linear vs. N-point table) across that full corrected range on both: same result, naive still clearly worst, returns still diminish past ~10–20 points. The article’s central finding held up under the real range; the specific range/stroke numbers on this page did not, and are being corrected unit by unit. First correction applied: Miuzei unit 3’s range-finding chart below now reflects the real, fixed-firmware measurement (313.1°, 325–2655µs). Its calibration, accuracy, and error-by-angle charts further down this page — and every chart for every other unit — still show the original, capped numbers pending the same correction.
Range-finding: naive vs. coarse vs. fine
Three passes finding the same physical limit, overlaid: a dead-simple naive sweep (dashed, amber), the smart algorithm’s fast coarse pass (dotted, amber), and its slow, precise fine pass (solid, blue) — what every other number in this study is built on. The two markers show the smart algorithm’s final reported edges. Angle is normalized so 0° sits at the low-pulse edge.
Miuzei 25kg Servo
Unit 1: 232.8° stroke (345–2080µs).
Unit 2: 237.7° stroke (340–2080µs).
Unit 3: 313.1° stroke (325–2655µs) — corrected 2026-08-25, see note above.
Knockoff MG996R
Unit 1: 160.2° stroke (350–2065µs).
Unit 2: 148.0° stroke (370–1975µs).
Unit 3: 158.7° stroke (355–2075µs).
MG90D
Unit 1: 241.6° stroke (265–2075µs).
Unit 2: 230.4° stroke (330–2075µs).
Unit 3: 229.8° stroke (340–2075µs).
Calibration curve and hysteresis
Top: the direction-averaged fine sweep (solid line) that becomes each unit’s ground truth, with a shaded band showing how far the up-sweep and down-sweep disagree at the same commanded pulse — backlash, which no static lookup table can correct. Bottom: that same curve’s local slope (degrees per microsecond) — the raw point-to-point rate (faint), smoothed to cancel out encoder-quantization noise (bold blue), against the curve’s single overall best-fit slope (dashed). Where the smoothed line drifts away from the dashed reference is exactly where the curve bows away from a straight line — the thing a 2-point linear model can’t see and a lookup table exists to fix.
Miuzei 25kg Servo
Unit 1: 348 points, mean backlash 0.989°, worst-case 1.760°.
Unit 2: 349 points, mean backlash 1.067°, worst-case 2.460°.
Unit 3: 351 points, mean backlash 1.442°, worst-case 2.110°.
Knockoff MG996R
Unit 1: 344 points, mean backlash 1.077°, worst-case 2.020°.
Unit 2: 322 points, mean backlash 1.233°, worst-case 1.930°.
Unit 3: 345 points, mean backlash 0.779°, worst-case 1.580°.
MG90D
Unit 1: 363 points, mean backlash 1.311°, worst-case 2.720°.
Unit 2: 350 points, mean backlash 1.245°, worst-case 2.810°.
Unit 3: 348 points, mean backlash 1.437°, worst-case 3.250°.
Accuracy by model
Top: every trial’s signed error (actual minus target), one box per model — box spans the middle 50% of trials, the line inside is the median, whiskers reach to the most extreme trial within 1.5× that spread, dots beyond that are outliers. Bottom: the same data collapsed to one number per model, mean |error|. All six models, each its own color — this is where diminishing returns actually shows up: table10 through table50 cluster together and barely move, while linear2 sits well apart from all of them.
linear2table10table20table30table40table50
Miuzei 25kg Servo
Unit 1.
Unit 2.
Unit 3.
Knockoff MG996R
Unit 1.
Unit 2.
Unit 3.
MG90D
Unit 1.
Unit 2.
Unit 3.
Error by target angle
Mean |error| binned into ten deciles across this unit’s own commanded-angle range, all six models — shows where in the range a model is worst, which a single aggregate number hides. linear2 is drawn heavier since it’s the point of comparison; the five table sizes usually sit close enough to overlap, which is the same diminishing-returns story as the section above, just plotted against angle instead of trial count.
linear2table10table20table30table40table50
Miuzei 25kg Servo
Unit 1 — all six models.
Unit 2 — all six models.
Unit 3 — all six models.
Knockoff MG996R
Unit 1 — all six models.
Unit 2 — all six models.
Unit 3 — all six models.
MG90D
Unit 1 — all six models.
Unit 2 — all six models.
Unit 3 — all six models.