Medidor de reflejos con Arduino Uno
El Uno enciende una lámpara en un momento al azar e imprime cuántos milisegundos tardaste. Todo el proyecto, un Arduino Uno y 5 componentes más, corre aquí en tu navegador con el firmware de abajo; ábrelo en el editor para cambiar las conexiones o el código y ejecutarlo de nuevo.
¿Das clases? Asígnalo a tu grupo con un clic.
Intermedio About 15 minutes to build and run. Funciona en tu navegador. Gratis y sin necesidad de cuenta.
Ármalo como el Starter Kit: los componentes en bolsas numeradas y un instructivo que revisa cada paso. Cuesta unos $34 en tiendas, gratis en Mokxi.
What you'll learn
- A random wait with
random - Timing with
millis - Detecting a false start while waiting
- Active buzzer versus passive piezo
- A button with
INPUT_PULLUP
- Difficulty: Intermedio
- Time: About 15 minutes
- Board: Arduino Uno R3
- Parts: 7
Cómo funciona
Each round waits a random 1.5 to 4 seconds, then lights the lamp on pin 9 and starts a clock. You press the button on pin 2, conectado a ground with the internal pull-up. The sketch prints how many milliseconds you took and plays a 1 kHz beep on the piezo for 120 ms.
If you press before the lamp, that is a false start. The sketch prints too soon, the active buzzer on pin 8 growls for 400 ms, and the round is thrown away.
The two sound parts need different signals. The active buzzer has its own oscillator, so steady power is enough. The piezo on pin 7 has none, so the sketch toggles the pin itself.
Lista de componentes
7 componentes, más los cables jumper. Cuestan unos $33 en tiendas; en Mokxi son gratis.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Protoboard completa
- 1 × Resistencia, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
- 1 × LED, verdeIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × Botón pulsadorIn Starter Kit, Christmas Lights Kit, Logic Lab Kit.
- 1 × BuzzerIn Starter Kit, Rocket Flight Computer Kit.
- 1 × Bocina piezoIn Starter Kit, Claw Machine Kit, Vending Machine Kit.
Kits that can build it
These 7 starter kits have every part in the circuit. Each kit's page lists what else it can build.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Componente y pin | Connects to |
|---|---|
| LED, green pin C | Arduino Uno R3 pin GND |
| Pushbutton pin 2a | Arduino Uno R3 pin GND |
| Buzzer pin 2 | Arduino Uno R3 pin GND |
| Piezo speaker pin 2 | Arduino Uno R3 pin GND |
| Resistor, 220 Ω pin 1 | Arduino Uno R3 pin 9 |
| Buzzer pin 1 | Arduino Uno R3 pin 8 |
| Piezo speaker pin 1 | Arduino Uno R3 pin 7 |
| Pushbutton pin 1a | Arduino Uno R3 pin 2 |
| LED, green pin A | Resistor, 220 Ω pin 2 |
El código
El firmware exactamente como lo abre el editor. Cambia una línea ahí y presiona Ejecutar: se compila en el navegador.
// 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);
}
Code walkthrough
The key functions of the sketch, and what each one does.
pressed sketch.ino
pressed returns true when the button pin reads LOW. Because the button uses the pull-up, LOW means it is held down.
static bool pressed() { return digitalRead(BUTTON) == LOW; }beep sketch.ino
beep makes a tone by hand. It works out half a period from the frequency, then sets the piezo pin HIGH and LOW with microsecond pauses, for as many cycles as fit in the time.
// 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);
}
}growl sketch.ino
growl turns the active buzzer on pin 8 HIGH for 400 ms and off again. It needs no tone, just power.
static void growl() {
digitalWrite(BUZZER, HIGH);
delay(400);
digitalWrite(BUZZER, LOW);
}loop sketch.ino
loop waits a random time, returning early on a false start. Otherwise it lights the lamp, waits for a press, prints the time, beeps, and waits for the button to be released.
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);
// ... 3 more lines in the editorTroubleshooting
The usual mistakes with this circuit, and the fix for each.
- The piezo makes no sound. This project
A piezo needs a changing signal. Check it is on pin 7 and thatbeepis being called. - Every round says too soon. This project
The button goes from pin 2 to GND. If it is stuck or wired to 5 V, it reads pressed all the time. - The waits repeat the same way every run. This project
randomgives the same sequence each time. Add arandomSeedcall with something that changes. - The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure. - A pull-up or pull-down resistor is missing, so the input floats and reads random values. Resistor
Tie the input to 5 V or ground through about 10k. Or use INPUT_PULLUP and wire the switch to ground. - The LED does not light, or it lights once and then dies. LED
LEDs have polarity. The longer leg (anode) goes toward the positive side. Always add a series resistor, about 220 ohms to 1 k ohm on a 5 V pin. - A blue or white LED stays dark on 3.3 V. LED
Blue and white LEDs drop about 3 V, so 3.3 V leaves almost nothing for the resistor. Use a 5 V supply, or a smaller resistor and a red or green LED. - The input reads random HIGH and LOW when the button is not pressed. Botón pulsador
A floating pin picks up noise. Add a 10 k pull-down or pull-up resistor, or use INPUT_PULLUP and wire the button between the pin and GND. Then pressed reads LOW.
Cámbialo y consérvalo
Ábrelo en el editor, cambia el circuito o el código y guarda tu versión en una cuenta gratis.