Hazır proje · Arduino Uno R3

Arduino Uno'da tepki zamanlayıcı

Uno rastgele bir anda bir lamba yakar ve kaç milisaniyede tepki verdiğini yazdırır. Tüm yapım, bir Arduino Uno ve 5 parça daha, aşağıdaki firmware üzerinde tarayıcında çalışır; kablolamayı ya da kodu değiştirmek ve yeniden çalıştırmak için düzenleyicide aç.

Öğretiyor musun? Tek tıkla sınıfına ata.

Orta About 15 minutes to build and run. Tarayıcında çalışır. Ücretsiz, hesap gerekmez.

Starter Kit olarak kur: numaralı poşetlerdeki parçalar ve her adımı kontrol eden bir kitapçık. Yaklaşık $34'a satılıyor, Mokxi'de ücretsiz.

Tepki zamanlayıcı · Arduino Uno R3live0.000 s 0.00x
Butona basılı tut
Devrenin kendisi, burada simülatörde çalışıyor. Basılabilecek şeylere bas; düzenleyicide açmak için başka bir şeye tıkla.

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: Orta
  • Time: About 15 minutes
  • Board: Arduino Uno R3
  • Parts: 7

Nasıl çalışır

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, şuna bağlı: 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.

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.

Parça ve pinConnects to
LED, green pin CArduino Uno R3 pin GND
Pushbutton pin 2aArduino Uno R3 pin GND
Buzzer pin 2Arduino Uno R3 pin GND
Piezo speaker pin 2Arduino Uno R3 pin GND
Resistor, 220 Ω pin 1Arduino Uno R3 pin 9
Buzzer pin 1Arduino Uno R3 pin 8
Piezo speaker pin 1Arduino Uno R3 pin 7
Pushbutton pin 1aArduino Uno R3 pin 2
LED, green pin AResistor, 220 Ω pin 2

Kod

Düzenleyicinin açtığı şekliyle firmware. Orada bir satırı değiştir ve Çalıştır'a bas: tarayıcıda derlenir.

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);
}

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 editor

Troubleshooting

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 that beep is 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
    random gives the same sequence each time. Add a randomSeed call 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. Buton
    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.

Değiştir ve sakla

Düzenleyicide aç, devreyi ya da kodu değiştir ve sürümünü ücretsiz bir hesapta sakla.