The core idea is very raw: create a very small USB host, send a signal to press a button, measure the time when the device status will change.
In here, we assume that we have access to the PCB button wire and that the PCB is a common ground.
Here's what is needed:
- Arduino Uno or Mega
- USB Host Shield or clone (with the ICSP connector for easier installation)
- Some wires and a protection diode
The software that we will install will change the voltage on pin 7 between 5V and 0V in order to simulate the button press.
If the device to measure is not a common ground or if the device is a 3.3V. Make the necessary adjustment to perform the button press using the pin 7 signal.
Install the lag tester program in the Arduino.
The experimentation protocol
Once everything is installed, launch the Serial Monitor (115200 bauds) of the Arduino IDE.
- Connect your device
- Reset the Arduino using the on-board button to ensure that the device is properly initialized
- Note the polling interval
- Try command
1to see if you signal is properly routed to your board. If it works you should see a lag value in ms.
- Send the command
pto set the native polling rate
- Clear output
- Send the command
t... wait for the test to be finished
- Copy the results in a spreadsheet
The polling rate settings
There are three main settings for the polling rate. The software supports overriding the polling rate using three schemes:
- Descriptor (command
n): use the value that was given by the device.
- Native (command
p): use the next power of 2 (1, 2, 4, 8, 16, 32ms). This is how usual systems like the PS4 or a PC will poll a device.
- Overclock (command
o): just use 1ms. Some systems uses this overclocking like the undamned USB decoder to read the device as fast as possible.
The most important setting is Native because it relates how the device behave in a standard system. The rest may be useful to understand how it works on the inside and how it can be boosted.
The result analysis
A Google Spreadsheet has been prepared to compute all the necessary metric and graphs for analysis.
The relevant metrics are the following:
stddevare good tools for understanding the bounds and variations of the distribution.
%on timeis the probability of having an input properly read on time in a 60fps game.
%on time metric is the most important one because it shows the actual implication on gameplay and it makes the comparison
with other devices easier, there is just one number to compare.
The lag distribution graph shows more detail on how the lag spreads. The histogram is computed using buckets of 1ms.
If you have performed new measures: please ping me somewhere so I can share them here.
Plug two controllers in a system with a fighting game that has a very stable latency; bind the same button to both PCB; press it and count how many times the players have traded or not.
The most notorious analysis is Teyah’s study (a lot of details there!).
Use the video interruption input lag method on a very stable game (say BlazBlue CPE). By analysing the report card, you are able to estimate the lag distribution.
Obviously, the one behind this idea is Noodalls who did a full report specifically on this topic. Having tested this method myself, it is pretty effective but requires some hardware.
LED / Camera
There is also the standard input lag method which is not specific to controllers but you could still use this to get an approximation. As a matter of fact some people have done extensive studies about this.
MitM USB injection
Finally, a better solution would be to have a custom man-in-the-middle USB device that decodes each USB exchange to detect when the input is properly transmitted to the device. Some people like Jim Hejl have succeeded in doing so.
What about bluetooth?
Bluetooth can be tested by changing the
1 in the
usblag.ino file. You do need to have a
decent bluetooth dongle and also an arduino mega in order to perform the measure.
Pairing can be a bit tricky, hit me up if you struggle with it.
How %ontime is computed?
By definition, the
%on time is the probability of being on time for a frame read.
If we look at one timing
t, then the probability
P(lag < t) is easy to estimate with our data. Assuming that
the inter-frame timing
t is uniform across the 16.6ms, we can just average the different results.
Debug: My device is recognized but does not poll data
In some device, you need a handshake upon plug and the device will not send data unless the proper handshake is performed. I tried to implement some but I know that some Xbox devices will not correctly send data. Help is requested.
Debug: I get phantom input and/or input drops
Make sure you have the latest version of usblag. It should not get weird inputs but some devices have proved me wrong.