Skip to content

Instantly share code, notes, and snippets.

@russeree
Last active January 17, 2024 13:08
Show Gist options
  • Save russeree/935dc1b5d2f107ea6ada600b477dc938 to your computer and use it in GitHub Desktop.
Save russeree/935dc1b5d2f107ea6ada600b477dc938 to your computer and use it in GitHub Desktop.
A Raspberry Pi Keyboard Latency Tester GPIO18
###
# Portland.HODL USB HID Latency Tester
# Engineered for RaspberryPi(4/5)
import csv
import hid
import time
import RPi.GPIO as GPIO
def list_hid_devices():
devices = hid.enumerate()
return devices
def display_devices(devices):
print("Available HID Devices:")
for idx, device in enumerate(devices):
vid_hex = hex(device['vendor_id'])
pid_hex = hex(device['product_id'])
print(f"{idx + 1}. Vendor ID: {vid_hex}, Product ID: {pid_hex}")
def select_device(devices):
while True:
choice = input("Start a test on (number): ")
if choice.isdigit() and 1 <= int(choice) <= len(devices):
return devices[int(choice) - 1]
else:
print("Invalid selection. Please try again.")
def main():
GPIO.setmode(GPIO.BCM) # or GPIO.setmode(GPIO.BOARD)
GPIO.setup(18, GPIO.OUT) # Set pin 18 as an output pin
GPIO.output(18, GPIO.HIGH) # Turn on the LED
# Lets setup the GPIO pins
devices = list_hid_devices()
display_devices(devices)
selected_device = select_device(devices)
# Now lets Open the selected HID device
try:
keyboard = hid.device()
keyboard.open(selected_device['vendor_id'], selected_device['product_id']) # open device
print("Device opened successfully")
test_cnt = 0
test_results = []
start_times = []
final_times = []
while test_cnt < 1000000:
time_ns_start = time.perf_counter_ns()
GPIO.output(18, GPIO.LOW) # Press the active low key
start_times.append(time_ns_start) # Store start time
data = []
data = keyboard.read(8)
final_time = time.perf_counter_ns() - time_ns_start
final_times.append(final_time)
GPIO.output(18, GPIO.HIGH) # Release the active low k[]ey
test_results.append((time_ns_start, final_time)) # Store start time and total time
test_cnt += 1
data = keyboard.read(8)
# Filter and prepare data for CSV
filtered_data_for_csv = [(start, total) for start, total in test_results if total <= 100000000]
print(f'Average time of {(sum(final_times) / len(final_times)) / 1000000000 * 1000}ms')
# Write to CSV
with open('latency_results.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['Start Time', 'Total Time']) # Header
for result in filtered_data_for_csv:
writer.writerow(result)
print("Results written to test_results.csv")
except IOError as e:
print(f"Error opening device: {e}")
finally:
GPIO.cleanup()
keyboard.close()
print("Device closed")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment