Calibration at machine speed
My programmable source needed a per-device calibration table. Claude swept 3,732 DAC codes in 25 minutes, discovered its own readings were wrong, and rebuilt the table against a second instrument — from about forty typed prompts.
0 views
The programmable source on my bench instrument had never been calibrated properly. It has a 12-bit DAC driving a TL431 control loop through a pass FET, and the firmware converted a requested voltage into a DAC code with a straight line — intercept and slope, two constants fitted by hand months ago.
A straight line is the wrong shape. The stage is not linear, and the error against a real lookup table runs to 465 mV. Everyone who has built an analogue supply knows the fix: sweep it, record what each code actually produces, and ship the table instead of the line.
Nobody does it by hand at full resolution, and not because it is tedious. The DAC has 4,096 codes. Set one, wait for the stage to settle, read a meter, write the number down, repeat. I would not attempt a hundred points manually without ruining the calibration somewhere in the middle of them — a transcription slip, a reading taken before the stage settled, a lapse in concentration at point sixty. Covering 3,700 is not a slower version of the same job. It is impractical, so in practice you fit a line through a dozen points and accept the error.
Yesterday it took 25 minutes for the full per-code sweep — 3,732 points — and five minutes for the refined one. I typed 44 prompts across three hours, and most of them were about the analogue design, not the procedure.
What made it possible was access, not intelligence
The interesting part is not that an AI can fit a curve. It is what it had to be able to touch to close the loop at all.
Four channels, none of them exotic:
- The tablet’s WebView, over Chrome DevTools Protocol. The source is driven
from a web UI, so
window.PowerBenchNativeis the same JavaScript bridge the page itself calls. Claude drove the hardware through the app’s own control path rather than around it. - The bench HTTP API on port 8092 for readback — the board’s own voltage sense, and later the precision DVM pod’s reading, both in the same JSON.
minichlinkto flash the hub, guarded by a script that refuses to write if the connected chip is not the one the image was built for.deploy.shto push the web UI.
Between them, one loop: set a code, read the result, decide, repeat. It ran without me.
The one thing missing was a primitive. The existing command took a setpoint in
millivolts and quantised it to 10 mV steps — about 2.4 DAC codes at this
stage’s 4.21 mV per code. You cannot address an individual code through it, so
a per-code sweep is impossible by construction. Claude added SCMD_SET_CODE
(a 12-bit code as a latched high nibble plus a low byte, matching the existing
frame format), flashed it, exposed it on the JavaScript bridge, deployed the
app, and then used it. Four artefacts, one purpose, no discussion.
That is the shape of the leverage. Not “the AI knows analogue design” — it does not, and several of its theories about my output stage were wrong. It is that a competent agent with hardware access will build the fixture it needs and then use the fixture, in the time it takes me to describe the problem.
The loop that corrected itself
The most instructive stretch was not the sweep. It was the settling.
The precision DVM pod publishes at 4 Hz. After you move the DAC, the pod’s next reading is not the new voltage — it is still integrating the old one. Take that sample and your table records the previous setpoint against the current code, silently.
Claude found this by measuring the residual, not by reasoning about it. The first attempt took the first new frame after each step:
mid-point residual: rms 28.4 mV
On an instrument that resolves tenths of a microvolt. The static noise at a fixed code — same code, twenty-five consecutive frames — is 0.395 mV, so 28.4 mV of scatter is not the instrument. It is contamination from unsettled readings.
Second attempt, discard one frame and take the next: 22.3 mV rms. Better, still wrong.
Third attempt, require two consecutive frames to agree within a tolerance before accepting the point. That is the stricter test, and it was worse:
mid-point residual: rms 54.4 mV
Two consecutive stale frames agree perfectly. The tolerance test cannot distinguish “settled” from “has not moved yet”, so tightening it admitted more garbage, not less.
The version that worked requires the reading to have moved away from the pre-step value first, and only then to agree with its successor:
mid-point residual: rms 1.88 mV
Fifteen times better than the best previous attempt, and within a factor of five of the instrument’s own noise floor. Direct measurement of the transient afterwards confirmed why: after a 16-code step the first two frames carry the old value, the third is mid-transition, and only the fourth — about 940 ms in — is correct.
I contributed one fact to that: the long settle only happens when the pod changes range, so paying it on every point is waste. That took the sweep from 3.6 seconds per point to 0.36.
The check that could not fail
There is a caveat I would rather state than bury.
The first table Claude built was swept against the board’s own voltage sense, and then verified against the board’s own voltage sense. It measured 8.5 mV maximum error and I committed it on that basis.
When the precision DVM went onto the output terminals, the same table measured 521 mV maximum error. Sixty times worse, same board, same setpoints, minutes apart.
Nothing was wrong with either measurement. The board’s sense is a 12-bit ADC behind a divider, resolving about 10.5 mV at the output. Build a table from it and check the table with it, and every error the ADC makes cancels — the verification is structurally incapable of detecting the class of error that matters most. It reported repeatability and I read it as accuracy.
The rebuilt table, swept against the DVM, verifies at 5.98 mV maximum, 1.69 mV mean across 1 to 15.5 V. That number means something the first one did not, because the instrument that produced it shares no front end with the thing being calibrated.
This is also why the DVM pod mattered more than any amount of cleverness. The sweep automation was worth an afternoon. The second instrument was worth the difference between a calibration and a plausible-looking fiction.
What shipped
Six commits. A 236-knot table, every 16 codes, covering 745 mV to 15.9 V, living in the tablet rather than hub flash — because a per-device table in firmware makes the firmware per-device, and then every unit needs its own build and field recalibration becomes impossible.
The hub keeps only a coarse fallback law and its safety clamps. The tablet owns the table and the product range. That split is now written down, along with the settle procedure and the note about never validating a calibration with the instrument that built it.
If you are wiring an AI into a hardware bench, the lesson I would take is narrow and practical: spend your effort on what it can reach, not on how you prompt it. A model that can set a DAC code, read an independent meter, flash a board and redeploy an app will find its own way through a calibration. One that can only write code for you to run is a much smaller thing, and the gap between them is entirely instrumentation.