from machine import Pin, I2C
import time
import random
import ssd1306
import gc
# OLED
i2c = I2C(0, sda=Pin(0), scl=Pin(1))
display = ssd1306.SSD1306_I2C(128, 64, i2c)
# Hardware
led = Pin(15, Pin.OUT)
button = Pin(16, Pin.IN, Pin.PULL_UP)
# Predefined text (avoid GC)
TXT_READY = "READY..."
TXT_WAIT = "Wait for LED"
TXT_EARLY = "TOO EARLY!"
TXT_CHEAT = "Cheating!"
TXT_TIME = "TIME:"
TXT_START = "REACTION GAME"
TXT_PRESS = "Press to start"
def update_screen(l1, l2=""):
display.fill(0)
display.text(l1, 0, 10)
display.text(l2, 0, 30)
display.show()
def wait_release():
while button.value() == 0:
time.sleep_ms(10)
def game_loop():
gc.collect() # prevent lag spikes
update_screen(TXT_READY, TXT_WAIT)
led.off()
# Fast integer random delay (2000–5000 ms)
delay_ms = random.getrandbits(12) % 3000 + 2000
start = time.ticks_ms()
# Early press detection
while time.ticks_diff(time.ticks_ms(), start) < delay_ms:
if button.value() == 0:
update_screen(TXT_EARLY, TXT_CHEAT)
time.sleep_ms(1500)
wait_release()
return
time.sleep_ms(5)
# LED ON
led.on()
start_time = time.ticks_ms()
while button.value() == 1:
time.sleep_ms(1)
reaction = time.ticks_diff(time.ticks_ms(), start_time)
led.off()
update_screen(TXT_TIME, str(reaction) + " ms")
print("Reaction:", reaction, "ms")
wait_release()
time.sleep_ms(1500)
# -------- MAIN --------
update_screen(TXT_START, TXT_PRESS)
while True:
if button.value() == 0:
wait_release()
game_loop()