# Changes ## 2026-04-27 — Arduino firmware refactor (`Gaugecontroller/Gaugecontroller.ino`) ### Non-blocking VFD multiplexer `vfd::refresh()` previously held each digit for 2000 µs via `delayMicroseconds`, which capped the effective stepper pulse rate at roughly 500 Hz regardless of `maxSpeed`. It now tracks `phaseStartMicros`/`phaseActive` and returns immediately while the digit is still being held; the main loop runs at microsecond cadence again and the configured `maxSpeed = 4000.0f` steps/s is actually achievable. ### Fixed-buffer command parser (no more `String` heap churn) Replaced `String rxLine` with `char rxBuf[128]` and converted the entire command pipeline to take `const char*`: - `processLine`, `sendReply`, `vfd::parseCommand` - All `parse*` functions: `parseSet`, `parseSpeed`, `parseAccel`, `parseEnable`, `parseZero`, `parseHome`, `parseSweep`, `parsePosQuery`, `parseCfgQuery`, `parseLedQuery`, `parseLed`, `parseBlink`, `parseBreathe`, `parseDflash`, `parseVfd`, `parsePing`. `parseSpeed` / `parseAccel` / `parseSweep` use `strncmp` + `atof` because the default AVR-libc `sscanf` doesn't support `%f`. No allocations on the command path; the Mega's heap no longer fragments over time. ### Cached `ledNeedsSwap[TOTAL_LEDS]` Per-LED RGB-vs-GRB swap flag is now precomputed once in `setup()` from `gaugePins[].ledOrder`. `encodeForStrip` is a single array index instead of walking the gauge table on every LED read/write. ### Cached step direction per gauge Added `Gauge.lastDir`. `setDir()` skips the DIR-pin `digitalWrite` when the direction hasn't flipped (the common case during a step run) and adds a 1 µs DIR-to-STEP setup delay only when it actually flips. ### Cleanups - Removed the `absf` helper; use `fabsf` consistently. - Removed the `+ 0.0001f` epsilon in the trapezoidal braking-distance divisor. `parseAccel` already rejects `accel <= 0`, so the divisor is always positive. - Fixed the ` ` typo to ` ` in the protocol comment for `DFLASH`. ### Build verification `arduino-cli compile --fqbn arduino:avr:mega Gaugecontroller`: 17758 B flash (6%), 1845 B SRAM (22%).