DIY Arduino Latency Tool

Everything about latency. Tips, testing methods, mouse lag, display lag, game engine lag, network lag, whole input lag chain, VSYNC OFF vs VSYNC ON, and more! Input Lag Articles on Blur Busters.
CrazyCookie
Posts: 8
Joined: 04 Jun 2023, 05:30

DIY Arduino Latency Tool

Post by CrazyCookie » 09 Jul 2023, 10:31

After years of dealing with Input delay I finally decided to make my own latency tool. It's based on the Arduino Micro and LM393 Light Sensor.
This tool is capable of measuring the System Latency, excluding mouse.(PC+Monitor+USB Port Latency)

DIY ARDUINO LATENCY TOOL
20230709_121908.jpg
20230709_121908.jpg (4.69 MiB) Viewed 3330 times
This is a Prototype, which contains the most important parts. Provisionally, I put tape around the sensor to shield it against incoming ambient light.
Additionally I will built 2 boxes, one for the arduino and one for the light sensor with a mount to fixate the sensor on the monitor.
But at the moment, cosmetics are secondary.

All in all, it cost me only ~40 Dollar to built it. This is really affordable, compared to other latency tools, which cost well over 100 dollar. :D

Here is a List of the Parts:
- Arduino Micro
- LM393 Light Sensor
- Toggle Switch
- Breadboard
- Male to Female Jumper Wires
- Male to Male Jumper Wires
- Micro USB Cable 1m
- Tape (to shield the sensor against incoming Light or for fixating Wires)


CODE
This is the more complicated part of the project. Luckily I found a guy that made the same latency tool and provided the code for it.
You need to upload and compile the code in the Arduino IDE. To display the results, open the Serial Monitor inside IDE.

Code:

Code: Select all

// Mouse - Version: Latest
#include <Mouse.h>

// light sensor pin
const byte lightSensorPin = 11;
// the number of the pushbutton pin
const byte buttonPin = 2;

// used in tests to get time when test starts
unsigned long startTime;
// used in tests to get time when sensor responded to pixel changes
unsigned long endTime;

// variable for reading the pushbutton state
bool buttonState = 0;

// variable for reading the light sensor state
bool newLightSensorState = 0;
// variable for storing previous state of light sensor
bool oldLightSensorState = 0;

void setup() {
  
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // initialize mouse
  Mouse.begin();
  
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
  // initialize light sensor pin as an input
  pinMode(lightSensorPin, INPUT);
  // initialize the LED pin as an output:
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // read the state of the pushbutton value:
  int buttonState = digitalRead(buttonPin);

  // check if the button is pressed. If it is, the buttonState is LOW:
  if (buttonState == LOW) {
    // turn LED on:
    digitalWrite(LED_BUILTIN, HIGH);
    
    oldLightSensorState = newLightSensorState; // store previous state of light sensor
    newLightSensorState = digitalRead(lightSensorPin); // get new state of light sensor
    
    
    //Serial.println(newLightSensorState);
    Mouse.press();
    startTime = micros();
    delay(0);
    // wait until sensor's state is changed
    while(newLightSensorState == 1 && buttonState == LOW)
    {
      oldLightSensorState = newLightSensorState; // store previous state of light sensor
      newLightSensorState = digitalRead(lightSensorPin); // get new state of light sensor
      buttonState = digitalRead(buttonPin);
      delay(0);
    }
    
    endTime = micros();
    Mouse.release();
    
    float responseTime = (endTime - startTime)/1000.0;
    Serial.print("startTime: ");
    Serial.print(startTime);
    Serial.print(", ");
    Serial.print("endTime: ");
    Serial.print(endTime);
    Serial.print(", ");
    Serial.print("responseTime: ");
    Serial.println(responseTime);
    delay(random(400, 600));
  } else {
    // turn LED off:
    digitalWrite(LED_BUILTIN, LOW);
  }
}
How it works:
1. Arduino sends a emulated mouse click every 400-600ms to the PC
2. The mouse click will trigger a light change on the monitor
3. The lightsensor will detect the light change
4. Arduino calculates the delay between the emulated mouse click and the light change on the monitor.

I already made some tests. I used a simple HTML Website, which turns from white to black when a arduino mouse click get triggered.
http://plnkr.co/edit/Q8CzgCo451XKKFbdmJAH?p=preview

I calculated the delay of 100 measurements
Results:
Maximum: 44.05 ms
Minimum : 36.22 ms
Average : 39.98 ms

I think these values are realistic, given then fact I have a low end PC (GTX1070, R5 2600, 144hz Monitor) and Chrome Hardware Acceleration turned OFF.

As a little experimental test, I repeated my measurment with Chrome Hardware Acceleration turned ON.
Results:
Maximum: 41.95 ms
Minimum : 28.21 ms
Average : 33.16 ms

Chrome Hardware Acceleration ON gave me around 7ms Latency reduction compared to disabling it. :)
I would say this behavior is expected. Of course the reduction only applies to web browsing, not for games! As clarification, this is just a test, of how well the tool can detect changes, that got applied to the system.

Of course I need a Validation Method.I will repeat the test with a 240fps camera and see if I get similar results, updates will get posted in this thread.

Can't wait to test bunch of settings and tweaks. :D Especially Optimized vs Unoptomized windows.
If anyone have questions or if someone can tell me what I can improve, please write it in here!
Last edited by CrazyCookie on 14 Jul 2023, 11:20, edited 3 times in total.

InputLagger
Posts: 203
Joined: 13 Sep 2021, 12:39
Location: RUS

Re: DIY Arduino Latency Tool

Post by InputLagger » 10 Jul 2023, 21:11

Nice work! Pls test Ubuntu Desktop too :roll:

CrazyCookie
Posts: 8
Joined: 04 Jun 2023, 05:30

Re: DIY Arduino Latency Tool

Post by CrazyCookie » 11 Jul 2023, 06:07

InputLagger wrote:
10 Jul 2023, 21:11
Nice work! Pls test Ubuntu Desktop too :roll:
Thank you, it could be better but it does what its meant to ^^ I always wondered if there is a difference in responsiveness between Linux and Windows. I might try that out!

0ka
Posts: 19
Joined: 25 Jun 2023, 02:17

Re: DIY Arduino Latency Tool

Post by 0ka » 13 Jul 2023, 11:23

use rtss latency marker

op forgot the html code so here it is https://drive.google.com/file/d/1U361Ot ... sp=sharing
i used different arduino and html code and got 36ms with HW accel on
arduino code v1
arduino code v2
Last edited by 0ka on 13 Jul 2023, 18:58, edited 2 times in total.

CrazyCookie
Posts: 8
Joined: 04 Jun 2023, 05:30

Re: DIY Arduino Latency Tool

Post by CrazyCookie » 13 Jul 2023, 11:58

0ka wrote:
13 Jul 2023, 11:23
use rtss latency marker
I would love to use the RTSS Latency Marker, but I encountered a few major Problems. I tested the RTSS Latency Marker and it's not accurate at all. I used a 240hz camera for validation, and I noticed the results with the latency marker are always 20-30ms lower compared to e.g. using muzzle Flash as marker.

Second Problem, the RTSS Latency Marker cannot pick up certain changes that got applied to the system. For example when playing a game in borderless fullscreen. It usually introduces 5-10ms lag. The rtss marker "ignores" this and shows me the same results as with fullscreen mode.
My main guess is that it's not fully integrated into the game engine, and that's why i'm seeing these results.
Nvidia for example has a implementation of it's own Flash Indicator that is integrated into certain games, that needs to be enabled in the settings and it's known to be more accurate then the rtss marker.

0ka
Posts: 19
Joined: 25 Jun 2023, 02:17

Re: DIY Arduino Latency Tool

Post by 0ka » 13 Jul 2023, 12:01

CrazyCookie wrote:
13 Jul 2023, 11:58
For example when playing a game in borderless fullscreen. It usually introduces 5-10ms lag. The rtss marker "ignores" this and shows me the same results as with fullscreen mode.
it works fine for me (i don't have g-sync or free-sync, MPO is disabled)
upd: 16ms of latency in fullscreen and 30ms in windowed/borderless (77hz display)

what game did you test? iirc in DX12 borderless and fullscreen modes are the same
Last edited by 0ka on 13 Jul 2023, 12:12, edited 1 time in total.

CrazyCookie
Posts: 8
Joined: 04 Jun 2023, 05:30

Re: DIY Arduino Latency Tool

Post by CrazyCookie » 13 Jul 2023, 12:12

0ka wrote:
13 Jul 2023, 12:01
CrazyCookie wrote:
13 Jul 2023, 11:58
For example when playing a game in borderless fullscreen. It usually introduces 5-10ms lag. The rtss marker "ignores" this and shows me the same results as with fullscreen mode.
it works fine for me (i don't have g-sync or free-sync, MPO is disabled)
upd: 16ms of latency in fullscreen and 30ms in windowed/borderless (77hz display)
Did you test using Muzzle Flash vs using the RTSS Latency Marker for measurments? For windowed mode, I also see a increase of around 15ms. I tested Apex Legens in DX12.

0ka
Posts: 19
Joined: 25 Jun 2023, 02:17

Re: DIY Arduino Latency Tool

Post by 0ka » 13 Jul 2023, 12:19

CrazyCookie wrote:
13 Jul 2023, 12:12
I tested Apex Legens in DX12.
enable different frame indicator in rtss like "moving bar" and check if you have screen tearing in borderless mode

CrazyCookie
Posts: 8
Joined: 04 Jun 2023, 05:30

Re: DIY Arduino Latency Tool

Post by CrazyCookie » 13 Jul 2023, 12:33

0ka wrote:
13 Jul 2023, 12:19
CrazyCookie wrote:
13 Jul 2023, 12:12
I tested Apex Legens in DX12.
enable different frame indicator in rtss like "moving bar" and check if you have screen tearing in borderless mode
I get screentearing regardless of borderless, because I dont use V-sync or Freesync etc.

0ka
Posts: 19
Joined: 25 Jun 2023, 02:17

Re: DIY Arduino Latency Tool

Post by 0ka » 13 Jul 2023, 12:47

CrazyCookie wrote:
13 Jul 2023, 12:33
I get screentearing regardless of borderless, because I dont use V-sync or Freesync etc.
now check with any other game that doesn't use dx12

Post Reply