Hi,
I was curious how input lag can be affected on a 60hz monitor with various settings e.g. vsync on/off, RTSS scanline sync, in-game video settings low vs ultra, screen resolution scale increased, etc.
I have an Arduino Due with a photodiode pointed at a 60hz monitor (Dell U2414H). The photodiode is polled every 1ms, the Arduino Due sends a single Mouse.move(127,127,0) command via USB to the PC. The input lag is determined based on number of readings since the Mouse.move command until the photodiode readings change e.g. low to high (dark to light).
Here are some graphs I put together in case anyone is interested. Each type of test is run 100 times with random 1000-2000ms delay between each test of the Mouse.move command. Each line is 1 test run.
https://imgur.com/a/4qTnm85
This is somewhat working as far as I can tell but I dont have any way to be sure.
There is around a 16ms transition between its initial climb until it reaches it's peak which I think makes sense as it's a 60hz monitor and I think this is when the monitor has finished drawing of the frame and this is when the end user will see it.
However I notice there is quite a lot of variance for each run of the test (each line) initial climb start time when using random delays between each test. If i set the delay between each test to the same e.g. 1000ms, then the graphs line up almost perfectly (initial climb start the same time each run). I dont know if this is expected behavior or maybe something not quite right in my set-up. From what I tested the Arduino could poll the photodiode around 200 times per 1 ms, which is why I capped it to poll once per 1 ms to make the data more manageable to work with, as far as I could tell the uncapped polling had similar results.
I guess I was curious whether I can cap my fps to 60 frames, turn up video settings in game and still experience the same input lag as before. To me it felt like input lag got slightly worse when increasing video settings in game even though the GPU can easily render frames within the 16.67ms window, e.g. 60fps low video quality settings vs 60fps ultra. But I cant say for sure even with the graphs as there is so much variance between the first (min lag) and slowest (max lag) runs.
According to TFTcentral the Dell U2414H has a 4ms input lag which is similar to some of the quickest 144/240hz panels they also tested. I was curious whether the input lag is noticeable even though it's a 60hz panel.
Edit: I should also mention capping the fps to 60fps with vsync off also produced the worst screen tearing experience in my case so in practical terms it was not really a viable option as the screen tearing made spotting enemies much harder compared with frames uncapped or capped at 70 fps. The closer it was capped to 60 fps the worse the screen tearing became with vsync off. I dont know if that is expected behavior as I dont have another PC to test with. The RTSS scanline sync method was a pretty good middle ground experience which helped to eliminate screen tearing while adding slight (noticeable but manageable) input delay as long as the GPU usage was below 70%.
Input Lag Test Analysis with Arduino Due and a 60Hz monitor
Re: Input Lag Test Analysis with Arduino Due and a 60Hz moni
Wow! That is a neat and cheap way to test input lag. No mouse modification nor 1000FPS camera required, and seems much faster to take the samples too!
I'd suggest uploading the code for that on github or similar. Surely such a setup would be interesting to many display experts?
I'd suggest uploading the code for that on github or similar. Surely such a setup would be interesting to many display experts?
Isn't the slight latency increase simply due to the lower FPS compared to running the game completely uncapped? I don't think RTSS (scanline sync or just normal cap) adds any input lag whatsoever.os4321 wrote:The RTSS scanline sync method was a pretty good middle ground experience which helped to eliminate screen tearing while adding slight (noticeable but manageable) input delay as long as the GPU usage was below 70%.
Steam • GitHub • Stack Overflow
The views and opinions expressed in my posts are my own and do not necessarily reflect the official policy or position of Blur Busters.
The views and opinions expressed in my posts are my own and do not necessarily reflect the official policy or position of Blur Busters.
Re: Input Lag Test Analysis with Arduino Due and a 60Hz moni
The code is very simple, it just sends a mouse move command, takes readings of the photodiode every 1ms for total 200 times in my case, then moves the mouse back to its original position.
code for Arduino:
Then copy the data output from the Arduino Serial monitor console and paste it into a spreadsheet in CSV format. In my case I use Libreoffice Calc then transpose the data (swap columns to rows) to make it easier to draw the graphs: select the data in Libreoffice Calc -> Cut (ctrl + x) -> Paste Special -> choose Transpose. This makes each column separate test where the photodiode readings displayed per row, so row 1 is the first 1ms reading, etc.
From what I could tell the 200 readings take 200ms, but after around 2000 readings it starts to drift by 1ms so 2000 readings take 2001ms.
I just dont know how accurate this method is as I dont have any way to be sure. There are also some unknowns such as I dont have a datasheet for the photodiode so I dont know the response time of it.
code for Arduino:
Code: Select all
#include <Mouse.h>
// define pins used on Arduino Due
int button1pin = 38;
int analogueInPin0 = 0; // photodiode
void setup() {
// configure input button with internal pullup resistor enabled
pinMode(button1pin, INPUT_PULLUP);
//initiate the Mouse library
Mouse.begin();
// Initialize Native USB port
SerialUSB.begin(9600);
}
void loop() {
// button press to start the test
if (digitalRead(button1pin) == LOW){
// delay to allow time for button to be depressed e.g. simple debounce mechanism
delay(500);
// run 100 tests
for (int i = 0; i < 100; i++) {
// delay between tests to allow time for light sensor reading to stablize
//delay(1000);
delay(random(1000,2000));
runInputLagTestMouseMoveReadSensorOnly();
}
}
}
void runInputLagTestMouseMoveReadSensorOnly(){
int photodiodeReading = 0;
unsigned long totalTime = 0;
// start timer
unsigned long startTime = millis();
//SerialUSB.println (startTime);
// send mouse move command
Mouse.move(127,-127,0);
// take 200 readings at 1ms intervals, output readings in CSV format to serial monitor
for (int i = 0; i < 200; i++) {
photodiodeReading = analogRead(analogueInPin0);
SerialUSB.print(photodiodeReading);
SerialUSB.print(",");
delay(1);
}
unsigned long endTime = millis();
//SerialUSB.println(endTime);
// newliine at end of CSV format so list of readings for each test on a seperate line
SerialUSB.println();
totalTime = endTime - startTime;
//SerialUSB.println(totalTime);
// move mouse back to original position
Mouse.move(-127,127,0);
}
From what I could tell the 200 readings take 200ms, but after around 2000 readings it starts to drift by 1ms so 2000 readings take 2001ms.
I just dont know how accurate this method is as I dont have any way to be sure. There are also some unknowns such as I dont have a datasheet for the photodiode so I dont know the response time of it.
Re: Input Lag Test Analysis with Arduino Due and a 60Hz moni
A random delay is required to de-correlate the test from the framerate. If the framerate is 60hz, there's a 17ms window in which an input will result in an output at the same time. Ideally that random delay is a common multiple of polling interval and frame interval. Without the random delay, you're just measuring the variance in frame time, and only know average latency to +- 1 frame.However I notice there is quite a lot of variance for each run of the test (each line) initial climb start time when using random delays between each test. If i set the delay between each test to the same e.g. 1000ms, then the graphs line up almost perfectly (initial climb start the same time each run). I dont know if this is expected behavior or maybe something not quite right in my set-up. From what I tested the Arduino could poll the photodiode around 200 times per 1 ms, which is why I capped it to poll once per 1 ms to make the data more manageable to work with, as far as I could tell the uncapped polling had similar results.
To make the data easier to process you can set a threshold, then measure the delay until the input crosses that threshold.
With vsync off the variance in latency should correlate to frame times. With vsync on(uncapped), the variance should correlate to 1/refresh rate). With vsync on (capped), the variance should correlate to 1/(refresh rate + framerate). With freesync(capped) the variance should correlate to 1/(framerate).
I did pick up some phototransistors, to replace the photoresistor in my old setup. Maybe I'll get around to reworking it.
Here are a couple relevant posts. Though the due is built on a different microcontroller, so if you use my code you'll need to change the parts relating the the prescaler and the USB ISR.
viewtopic.php?f=10&t=3005&start=50#p22634
viewtopic.php?f=10&t=1381&start=310#p23272
One thing you can do with the Due that hasn't been done yet AFAIK is use the USBHost capability to measure the absolute latency of mice and keyboards.
Re: Input Lag Test Analysis with Arduino Due and a 60Hz moni
Thanks for the explanation
Re: Input Lag Test Analysis with Arduino Due and a 60Hz moni
I dug up this chart from some testing a few years ago: https://docs.google.com/spreadsheets/d/ ... nteractive