Đo phản xạ với Arduino Uno
Uno bật một đèn vào một thời điểm ngẫu nhiên và in ra bạn mất bao nhiêu mili giây để phản ứng. Toàn bộ mạch, gồm một Arduino Uno và 5 linh kiện khác, chạy ngay trong trình duyệt của bạn với firmware bên dưới; mở nó trong trình soạn thảo để đổi cách nối dây hoặc code rồi chạy lại.
Đang dạy học? Giao bài này cho lớp của bạn chỉ với một cú nhấp.
Trung bình About 15 minutes to build and run. Chạy trong trình duyệt của bạn. Miễn phí, không cần tài khoản.
Lắp theo Starter Kit: linh kiện trong các túi đánh số và một sách hướng dẫn kiểm tra từng bước. Bán lẻ khoảng $34, miễn phí trên 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: Trung bình
- Time: About 15 minutes
- Board: Arduino Uno R3
- Parts: 7
Cách hoạt động
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, nối tới 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.
Danh sách linh kiện
7 linh kiện, cộng thêm dây cắm. Bán lẻ khoảng $33; trên Mokxi thì miễn phí.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Breadboard cỡ lớn
- 1 × Điện trở, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
- 1 × LED, xanh láIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × Nút nhấnIn Starter Kit, Christmas Lights Kit, Logic Lab Kit.
- 1 × Còi buzzerIn Starter Kit, Rocket Flight Computer Kit.
- 1 × Loa 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.
| Linh kiện và chân | 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 |
Code
Firmware y như khi trình soạn thảo mở ra. Sửa một dòng ở đó và nhấn Chạy: nó được biên dịch ngay trong trình duyệt.
// 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. Nút nhấn
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.
Sửa và giữ lại
Mở trong trình soạn thảo, đổi mạch hoặc code, và giữ phiên bản của bạn trong một tài khoản miễn phí.