Last active
April 4, 2024 13:41
-
-
Save YaLTeR/8e8bd0cddb324a9e372b32e742ff992a to your computer and use it in GitHub Desktop.
Latency measuring device firmware
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Bounce2.h> | |
// Where I have stuff plugged in on my board. | |
#define BUTTON_PIN 2 | |
#define LIGHT_PIN 23 | |
// This one is standard for Teensy. | |
#define LED_PIN 13 | |
// The program repeatedly: | |
// 1. presses the first key | |
// 2. waits for light sensor change | |
// 3. releases the first key | |
// 4. waits for a bit | |
// 5. does the same with the second key | |
// | |
// This allows to loop the measurements, like entering and | |
// erasing a space in a terminal. | |
// | |
// These are the two keys it uses. | |
#define KEY_FIRST KEY_SPACE | |
#define KEY_SECOND KEY_BACKSPACE | |
// If defined, this modifier will be held for the entire duration | |
// of the test. | |
#define MODIFIER MODIFIERKEY_CTRL | |
// Number of times to repeat the sequence above before | |
// automatically stopping. | |
#define TIMES 120 | |
// Light threshold for step 2. Seems big enough to not trigger on noise. | |
#define RELEASE_LIGHT_THRESHOLD 50 | |
// Constant wait duration for step 4. | |
// | |
// Light level more or less stabilizes after this time. | |
#define WAIT_MS 400 | |
// Random wait duration for step 4. | |
// | |
// This gets rid of aliasing with display refresh rate. | |
// 15 is the GCD of 144 (my current refresh rate) and | |
// 60 (another common / interesting refresh rate), so | |
// it produces a uniform random start time for those | |
// refresh cycles. | |
#define RANDOM_WAIT_MS (1000 / 12) | |
Button button = Button(); | |
int working = 0; | |
int state = 0; | |
int timesLeft = 0; | |
int startLight = 0; | |
elapsedMicros sinceStart; | |
elapsedMillis sinceRelease; | |
void setup() { | |
button.attach(BUTTON_PIN, INPUT); | |
button.interval(5); | |
button.setPressedState(LOW); | |
pinMode(LED_PIN, OUTPUT); | |
digitalWrite(LED_PIN, working); | |
// Not required on Teensy, but waits until the serial port is ready. | |
Serial.begin(9600); | |
} | |
void print(int light) { | |
Serial.print("T"); | |
Serial.print(sinceStart); | |
Serial.print("L"); | |
Serial.print(light); | |
Serial.println("D"); | |
} | |
void print_ts(char c) { | |
Serial.print(c); | |
Serial.print(sinceStart); | |
Serial.println(c); | |
} | |
void setWorking(bool value) { | |
working = value; | |
digitalWrite(LED_PIN, working); | |
if (working) { | |
state = 0; | |
timesLeft = TIMES; | |
sinceStart = 0; | |
sinceRelease = 0; | |
#ifdef MODIFIER | |
Keyboard.press(MODIFIER); | |
#endif | |
} else { | |
Keyboard.release(KEY_FIRST); | |
Keyboard.release(KEY_SECOND); | |
#ifdef MODIFIER | |
Keyboard.release(MODIFIER); | |
#endif | |
} | |
} | |
void loop() { | |
button.update(); | |
if (button.pressed()) | |
setWorking(!working); | |
if (!working) | |
return; | |
int light = 0; | |
switch (state) { | |
case 0: | |
light = analogRead(LIGHT_PIN); | |
print(light); | |
if (sinceRelease < WAIT_MS) | |
break; | |
print_ts('+'); | |
startLight = light; | |
Keyboard.press(KEY_FIRST); | |
state = 1; | |
break; | |
case 1: | |
light = analogRead(LIGHT_PIN); | |
print(light); | |
if (max(light, startLight) - min(light, startLight) > RELEASE_LIGHT_THRESHOLD) { | |
Keyboard.release(KEY_FIRST); | |
sinceRelease = random(RANDOM_WAIT_MS); | |
state = 2; | |
} | |
break; | |
case 2: | |
light = analogRead(LIGHT_PIN); | |
print(light); | |
if (sinceRelease < WAIT_MS) | |
break; | |
print_ts('='); | |
startLight = light; | |
Keyboard.press(KEY_SECOND); | |
state = 3; | |
break; | |
case 3: | |
light = analogRead(LIGHT_PIN); | |
print(light); | |
if (max(light, startLight) - min(light, startLight) > RELEASE_LIGHT_THRESHOLD) { | |
Keyboard.release(KEY_SECOND); | |
sinceRelease = random(RANDOM_WAIT_MS); | |
state = 0; | |
if (--timesLeft == 0) | |
setWorking(false); | |
} | |
break; | |
default: | |
return; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment