Menu
CoddyTech

反応ゲーム:タイマー

CoddyのArduinoジャーニー「プロジェクト」セクションの一部。レッスン 6/24。

今度はゲームが反応時間を測ります。反応時間とは、LEDが点灯してからボタンを押すまでの時間です。そのため、スケッチは点灯した瞬間を記録しておく必要があります。

digitalWrite(ledPin, HIGH);
litAt = millis();
state = LIT;

LIT状態のときにボタンが押されると、その差が答えになります。

unsigned long reaction = millis() - litAt;
Serial.print("Reaction: ");
Serial.print(reaction);
Serial.println(" ms");

これは、スケッチが決してdelay()で停止しないからこそ機能します。loop()は毎ミリ秒に数千回ボタンを確認するため、押されてから1ミリ秒も経たないうちに検知できます。ほとんどの人の反応時間は200~300 msです。

challenge icon

チャレンジ

中級

プレイヤーの反応時間を計測します:

  • LEDが点灯したとき、millis() を litAt に保存します
  • LIT の状態でボタンが押されたら、millis() - litAt を計算します
  • Reaction: 250 ms の形式で表示します

Run を押してプレイし、シリアルモニターを確認してから、Check を押します。

自分で試してみよう

const int ledPin = 12;
const int buttonPin = 2;

// 1回の動作における3つの状態
enum State { READY, WAITING, LIT };
State state = READY;

int lastButton = HIGH;       // 前回のボタンの読み取り値
unsigned long waitStart = 0; // 待機を開始した時刻
unsigned long waitTime = 0;  // 今回の待機時間

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Press the button to start");
}

void loop() {
  int button = digitalRead(buttonPin);
  bool pressed = (button == LOW && lastButton == HIGH);  // たった今押された
  lastButton = button;
  unsigned long now = millis();

  switch (state) {
    case READY:
      if (pressed) {
        randomSeed(micros());  // ボタンを押す時刻は毎回異なる
        waitTime = random(1000, 3001);
        waitStart = now;
        state = WAITING;
      }
      break;
    case WAITING:
      if (now - waitStart >= waitTime) {
        digitalWrite(ledPin, HIGH);
        state = LIT;
      }
      break;
    case LIT:
      if (pressed) {
        digitalWrite(ledPin, LOW);
        state = READY;
      }
      break;
  }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

プロジェクトのすべてのレッスン

自分で練習してみよう: Arduinoプレイグラウンド