ESP32 Bench
Boards: ESP32, S2, S3, C3, C6
Flash and monitor: Web Serial
← All projects

Reaction timer

How fast are you? The onboard LED lights after a random wait and you slap the BOOT button. Your best time survives a power cut.

Starter5 min115200 baud
Board
Fig. 1. Pins this project uses on the ESP32-DevKitC V4, 38 pin. USB connector at the bottom.

Wiring

FromTo boardNote
Onboard LEDGPIO 2Already on the board. On the classic ESP32 DevKitC, add an LED and 220 Ω from GPIO 2 to GND
BOOT buttonGPIO 0Already on the board

Tested on this board

Not run on this board yet. Treat the wiring and code as a first draft.

Firmware, Arduino sketch for ESP32 Dev Module

// Reaction timer: the LED lights after a random wait, press BOOT as fast as you can.
#include <Preferences.h>

const int LED = 2;          // the board's LED
const bool LED_IS_RGB = false;  // an addressable RGB LED rather than a plain one
const int LED_ON = HIGH;        // the level that lights a plain LED
const int BUTTON = 0;       // the BOOT button

Preferences prefs;
unsigned long best = 0;  // best time in ms, 0 until the first round

void led(bool on) {
  if (LED_IS_RGB) rgbLedWrite(LED, 0, on ? 64 : 0, 0);  // green
  else digitalWrite(LED, on ? LED_ON : !LED_ON);
}

bool pressed() {
  return digitalRead(BUTTON) == LOW;
}

void waitForRelease() {
  while (pressed()) delay(5);
  delay(30);  // let the contacts settle
}

void setup() {
  Serial.begin(115200);
  delay(500);
  pinMode(BUTTON, INPUT_PULLUP);
  if (!LED_IS_RGB) pinMode(LED, OUTPUT);
  led(false);
  prefs.begin("reaction", false);
  best = prefs.getULong("best", 0);
  randomSeed(esp_random());
  Serial.println("Reaction timer. Press BOOT when the LED lights.");
  if (best) Serial.printf("best so far: %lu ms\n", best);
}

void loop() {
  Serial.println("get ready...");
  waitForRelease();
  unsigned long wait = random(1500, 5000);
  unsigned long start = millis();
  while (millis() - start < wait) {
    if (pressed()) {
      Serial.println("false start! wait for the light");
      for (int i = 0; i < 6; i++) {
        led(i % 2 == 0);
        delay(80);
      }
      led(false);
      waitForRelease();
      delay(1000);
      return;
    }
    delay(1);
  }

  led(true);
  unsigned long lit = micros();
  while (!pressed()) {
    if (micros() - lit > 3000000UL) {
      led(false);
      Serial.println("too slow, try again");
      delay(1000);
      return;
    }
  }
  unsigned long ms = (micros() - lit) / 1000;
  led(false);
  Serial.printf("reaction=%lu ms\n", ms);
  if (best == 0 || ms < best) {
    best = ms;
    prefs.putULong("best", best);
    Serial.printf("new best: %lu ms\n", best);
  }
  waitForRelease();
  delay(1500);
}

Parts

QuantityPartWhere to buy
1×ESP32 dev boardBuy at Amazon
1×LED and 220 Ω resistor, only on a board without its own LED

Amazon buy links may include an Associates tag, and this site may earn a commission from qualifying Amazon purchases at no extra cost to you. Adafruit links are direct.

Libraries

Preferences (built in)

Load it

  1. In the Arduino IDE, install the esp32 board package and pick the board named above the sketch.
  2. Paste the sketch, choose the board's port and upload. Hold BOOT if the upload stalls at Connecting.
  3. Close the IDE's serial monitor, then open the bench here to watch the output.

Field notes

  • The classic ESP32-DevKitC V4 has no user LED. Many 30-pin clones have one on GPIO 2; otherwise add an LED and a 220 Ω resistor from GPIO 2 to GND.
  • The S3, C3, S2 and C6 DevKits have an addressable RGB LED instead, driven with rgbLedWrite(). On the first S3-DevKitC-1 revision it is on GPIO 48, not 38.
  • The XIAO ESP32S3's LED lights when its pin is low, which is why LED_ON is LOW there.
  • Do not hold BOOT while the board resets: that puts it in download mode. Start pressing once it prints 'get ready'.
  • The best time is kept with Preferences, so it survives a power cut. Erasing the whole flash clears it.
  • Most people land between 200 and 300 ms. Under 150 ms is usually a lucky guess.

Not tested yet

  • Not tested on hardware yet. Compiles for every board listed with Arduino-ESP32 core 3.3.12.

Built it? Send a build report with your board and what the serial port printed. Working reports become the "Tested on this board" entries above.