反応ゲーム:タイマー
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です。
チャレンジ
中級プレイヤーの反応時間を計測します:
- 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;
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
プロジェクトのすべてのレッスン
自分で練習してみよう: Arduinoプレイグラウンド