interval_buffer_isr: The Tiny Motion-Control Engine That Won’t Lose Its Phase
A stepper-motor ISR planner that carries sub-step position across frames, survives direction flips, and uses formal verification to prove the error stays bounded.
- interval_buffer_isr is really about preserving a continuous phase estimate that ordinary step schedulers tend to lose at frame boundaries.
- Its half-step offset and direction inversion logic keep discretization error bounded instead of letting it drift.
- The planner, runner, simulator, and CBMC checks form one pipeline, so the same motion plan can be executed and then proved safe.
- The project is small, but its ambition is high: treat motion control like a correctness problem, not a guess-and-check loop.
The hidden state inside every step
Stepper motors look discrete from the outside. Inside the firmware, they are anything but. The real job is to keep track of a hidden fractional state, then turn that state into timer-driven pulses without letting the error wander.
That is why interval_buffer_isr stands out. It is not just a buffer for interrupts. It is an attempt to preserve phase continuity across frames, direction changes, and ISR boundaries, while still fitting the math into a small embedded footprint.
Why this repo exists
There is no public launch post or founder story to lean on here, so the code has to do the talking. What it says is clear: somebody wanted a stepper planner that would not quietly lose sub-step position every time the timer frame rolled over.
That matters in CNC and 3D printer firmware, where motion is continuous but execution is chopped into interrupts. If you round too early, reset too eagerly, or treat each frame as a fresh start, the machine can drift. The repo’s answer is to keep the invariant explicit and keep carrying it forward.
The trick: carry phase, do not reset it
The core idea is a half-step-centered phase model. Instead of asking only, “How many steps fit in this frame?” the planner asks, “Where is the continuous motion path relative to the next pulse, and how do I carry the leftover phase into the next interval?”
The subtle part is the boundary behavior. A frame can end before the next pulse is due, or it can end right after one has been scheduled. The planner has to avoid phantom steps at the seam, so the phase offset is centered and the remaining fraction survives into the next frame.
That is why the project feels more like a proof sketch than a queue. It is less concerned with storing events than with preserving a relationship between target position, actual pulses, and residual error.
How the planner, runner, and simulator fit together
- The planner turns a target position into a frame plan with step intervals and phase bookkeeping.
- The runner consumes that plan the way a timer ISR would, emitting pulses at the scheduled moments.
- The simulator stitches many frames together so the same logic can be exercised over longer motion sequences.
- CBMC adds the hard part, checking that the motion error stays within the bound the code promises.
That split is elegant because each layer does one job. The planner reasons about motion, the runner reasons about timing, and the simulator reasons about end-to-end behavior. The verification layer then asks whether the invariant still holds for every valid input it can explore.
Why fixed-point math is the real enabler
The repo leans on fixed-point formats such as Q15.16 and Q27.5 because embedded motion code needs predictable cost. Floating point can be fine on bigger chips, but it is often a poor trade on tiny controllers where every interrupt has a budget.
There is also a very practical twist: the research notes point to 64-bit-free multiplication tricks, which is a strong signal that the code is designed for hardware where wide math is expensive. That is the difference between a neat algorithm and one that can actually live inside an ISR.
The technical charm here is not just precision. It is precision at a price the microcontroller can afford.
The proof matters more than the simulation
Simulation can show a trajectory that looks good. Formal verification tries to show that the bad case cannot happen at all, at least within the modeled assumptions. That is a very different bar.
In this repo, CBMC is not a decorative extra. It is the mechanism that turns a motion heuristic into something closer to a contract: for valid inputs, the error bound should hold. That is a much stronger claim than, “It passed my test path.”
For motion control, that distinction is huge. Boundary mistakes are exactly the kind of bug that show up rarely, hide in timing edges, and cost real hardware time when they do.
What this beats, and what it does not
| Approach | Phase handling | Error behavior | What it buys you |
|---|---|---|---|
| Naive per-frame rounding | Resets the story at each boundary | Boundary drift can accumulate into visible jitter | Very simple, but the hidden invariant is implicit |
| interval_buffer_isr | Carries fractional phase forward and centers it around the half-step | Keeps the commanded path aligned across frame changes | An explicit correctness model for ISR timing |
| Generic queue-based ISR planning | Schedules work well, but usually abstracts away the motion invariant | Flexible, yet less focused on phase continuity | Useful as plumbing, not as a proof-oriented motion model |
That comparison is the right one. This repo is not trying to be a full industrial firmware stack. It is a focused lab for one hard subproblem: how to preserve motion state without paying a heavy math tax.
Seen that way, its value is bigger than its size. It shows how a small embedded algorithm can be written as if correctness were the product.