I have an Arduino that I've programmed to play-back HID reports based on actual real-life mouse movement data - but also entirely synthetic data, so I took a recording of my real-life mouse movement but played it back at fixed report rates of 250 Hz, 333 Hz, 500 Hz and 1000 Hz and re-ran my movement recorder (that uses Win32 Raw Input) and plotted the results... and it's weird, natch.
At first I thought the delayed samples were such that their equivalent delay was half the intended report-rate, but after looking at the data what we see is that (at a regular interval) many reports are delayed by exactly 1ms, which just-has-the-apparent-effect of halfing the report rate, but it isn't the same thing once you try different rates (e.g. 333 Hz):
- At 250 Hz (sent at a 4ms interval) most reports are received with ~4ms between them, but some reports are delayed by an additional 1ms (for 5ms total), hence the second cluster of data with "200 Hz equivalent".
- At 333 Hz (sent at a 3ms interval), again, most reports are received with ~3ms between them, but others (at regular intervals) are received (again) with an additional 1ms delay (for 4ms total), hence why the line appears at 250 Hz and not 166 Hz.
- At 500 Hz (2ms interval), most reports are recieved with ~2ms between them, but the others have almost exactly 3ms between them.
- At 1000 Hz (1ms interval) there's a lot of jitter, but I believe that's due to the (comparatively limited) timer resolution on my Arduino - so I'm not concerned by it - but we see how the extra 1ms to the subset of reports causes their "equivalent hz" to be 500 Hz.
So this is... interesting. The fact that the reports are being delayed by almost-exactly 1ms is surprising and unexpected.
...but it's nice that I no-longer have to rely on my vague "feelings" about how my mouse is because I can now produce consistent USB inputs and get raw data back from the OS which allows me to actually see what's changed.
However I haven't yet fully validated my approach yet: I need to verify that the HID reports are in-fact being sent at regular intervals, I will be able to do that within a few days.
All data was gathered while I ran a program that set `NtSetTimerResolution` to 500us (0.5ms).