Controller Lag
Methodology

Idea

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.

Hardware Setup

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:

Controller Lag Hardware Setup

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.

  1. Connect your device
  2. Reset the Arduino using the on-board button to ensure that the device is properly initialized
  3. Note the polling interval
  4. Try command 0 and 1 to see if you signal is properly routed to your board. If it works you should see a lag value in ms.
  5. Send the command p to set the native polling rate
  6. Clear output
  7. Send the command t... wait for the test to be finished
  8. 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:

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:

This %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.

Sample Lag Distribution

If you have performed new measures: please ping me somewhere so I can share them here.

Alternative methodologies

Controller Versus

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!).

Video interruption

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.

Addendum

What about bluetooth?

Bluetooth can be tested by changing the ENABLE_BT from 0 to 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.