My own app took me out of the Spa 12 Hours
PONNE’s first confirmed race incident was caused by PONNE.
The scene
A 12-hour team endurance race at Spa, somewhere around hour nine. I’m mid-stint, driving my own stint in my own team, running the app I built specifically so that this exact kind of race would go better.
The symptom
A wheel button I’d bound started firing on its own — not once, but machine-gunning, dozens of times a second, every time I turned the wheel. Which, at Spa, is often. The input flood hammered iRacing until my USB stack folded: devices dropped, and somewhere on a straight I was suddenly holding a wheel that was no longer attached to the car in any meaningful sense.
There is no spotter call for this. “Car left, car right, your steering wheel has left the session.”
The cost
My teammates weren’t at their rigs — it was my stint, that’s the whole point of an endurance roster — so there was no quick driver swap to hide behind. I rebooted the PC while the car sat there and the team lost real time. We got going again, but you don’t get those minutes back in a 12-hour race. The app whose pitch is know when to box had invented an entirely new pit strategy: the unscheduled reboot.
The cause
When PONNE captures a wheel button, it listens to the raw USB traffic and remembers which byte changed. Here’s the thing nobody tells you about direct-drive wheelbases: the steering axis and the wheel’s buttons often share the same USB report — one packet, steering and buttons interleaved. If the capture lands on a byte carrying axis data, then every steering movement afterwards looks exactly like that “button” being pressed. Turn the wheel, sweep the axis, fire the binding. At Spa, you turn the wheel a lot.
Why it got through
On a keyboard or a button box, capture is unambiguous — buttons live in their own bytes. This failure needs a wheelbase that packs axis and buttons together, a capture at an unlucky moment, and then actual racing. It can essentially only happen on a rig, mid-session, at speed. Which is why the person who found it was me, nine hours into a twelve-hour race, instead of any test I’d written.
The fix — four defences, because one wasn’t enough
PONNE now assumes any byte might secretly be an axis and makes it prove otherwise.
Rate detection. No human presses the same button six times in 800 milliseconds and keeps going — an axis sweep does it within a few packets. Any byte flipping that fast is treated as an axis and muted until five seconds after the flipping stops.
Hold to confirm. A rising edge only counts as a press if the byte holds its new value for 40 milliseconds. A pressed button stays put; an axis byte has already moved on. This kills the one phantom the rate detector can’t catch — the very first flip of a sweep.
Debounce. A real press can’t legitimately re-fire the same pad within a quarter second — a hard cap on the damage before the rate detector has evidence.
Smarter capture. The root cause was capture trusting the wrong byte, so capture got the same paranoia: a byte that keeps changing during capture is an axis even if it started quiet (wheel centred, then moved), and a candidate press only becomes the binding after its bit stays set while the rest of the byte holds still. Buttons are held for tens of milliseconds; axis bytes never sit that still.
All four were verified by replaying real captured USB report patterns against the detector — because “works on my keyboard” is precisely the test that missed this.
What it cost users, honestly
Wheel bindings made before the fix could still be sitting on an axis byte, so the beta.30 changelog asked testers to re-capture their wheel buttons once. One re-capture per binding — the price of capture having been too trusting.
The lesson
It’s one this log will keep returning to: the failures that matter live where the product actually runs — on a rig, in a race, on hardware with opinions of its own. It’s why every PONNE changelog now marks which features have and haven’t met a real rig yet. And it’s why I keep racing on my own beta builds: worst case, I lose a stint at Spa and you get a better app and this story.