Built-in project · Arduino Uno R3

Reaction timer on an Arduino Uno

The Uno lights a lamp at a random moment and prints how many milliseconds you took. The whole build, an Arduino Uno and 5 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

IntermediateRuns in your browser. Free, and no account needed.

Reaction timer · Arduino Uno R3live0.000 s 0.00x
Hold the button
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// Reaction timer: how fast are you, in milliseconds.
//
//   pin 9  the lamp, through 220 ohm to GND
//   pin 2  the button, to GND, internal pull-up
//   pin 8  an active buzzer straight to GND
//   pin 7  a passive piezo straight to GND
//
// Each round waits a random 1.5 to 4 seconds, lights the lamp, and times the
// button. Press before the lamp and it is a false start: the buzzer (the
// active kind, with its own oscillator, so DC across it is all it needs)
// growls for a moment and the round is thrown away.
//
// The piezo is the other kind. It has no oscillator, so a steady voltage does
// nothing at all; the beep at the end of a good round is this sketch toggling
// pin 7 at 1 kHz for a tenth of a second. Two sound parts, two completely
// different things to send them.
//
// random() here is deterministic (the same sequence every run), which is
// what you want in a simulator. Call randomSeed() with something that varies
// to break that.

const int LAMP = 9;
const int BUTTON = 2;
const int BUZZER = 8;
const int PIEZO = 7;

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

// A square wave on the piezo: half a period high, half low, for `ms`.
static void beep(unsigned int hz, unsigned long ms) {
  unsigned int half = (unsigned int)(500000UL / hz);
  unsigned long cycles = (ms * 1000UL) / (2UL * half);
  for (unsigned long i = 0; i < cycles; i++) {
    digitalWrite(PIEZO, HIGH);
    delayMicroseconds(half);
    digitalWrite(PIEZO, LOW);
    delayMicroseconds(half);
  }
}

static void growl() {
  digitalWrite(BUZZER, HIGH);
  delay(400);
  digitalWrite(BUZZER, LOW);
}

void setup() {
  pinMode(LAMP, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(PIEZO, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP);
  Serial.begin(115200);
  Serial.println("Mokxi Arduino Uno: reaction timer");
  Serial.println("wait for the lamp, then press the button");
}

void loop() {
  digitalWrite(LAMP, LOW);

  // the wait, watching for a false start
  unsigned long wait = (unsigned long)random(1500, 4000);
  unsigned long started = millis();
  while (millis() - started < wait) {
    if (pressed()) {
      Serial.println("too soon");
      growl();
      while (pressed()) delay(5);
      delay(500);
      return;
    }
    delay(5);
  }

  digitalWrite(LAMP, HIGH);
  unsigned long lit = millis();
  while (!pressed()) delay(1);
  unsigned long took = millis() - lit;
  digitalWrite(LAMP, LOW);

  Serial.print("reaction: ");
  Serial.print(took);
  Serial.println(" ms");
  beep(1000, 120);

  while (pressed()) delay(5);
  delay(700);
}

Parts list

7 parts, plus the jumper wires. Every one is in the editor's parts bin.

How it is wired

6 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Ground: Arduino Uno R3 pin GND; LED, green pin C; Pushbutton pin 2a; Buzzer pin 2; Piezo speaker pin 2
  • Arduino Uno R3 pin 9; Resistor, 220 Ω pin 1
  • Arduino Uno R3 pin 8; Buzzer pin 1
  • Arduino Uno R3 pin 7; Piezo speaker pin 1
  • Arduino Uno R3 pin 2; Pushbutton pin 1a
  • Resistor, 220 Ω pin 2; LED, green pin A

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.