Menu
CoddyTech

反应力游戏:计时器

本课属于 Coddy Arduino 学习旅程的“项目”单元。第 6 课,共 24 课。

现在,游戏会测量你的反应时间。反应时间是从 LED 点亮到你按下按钮所经过的时间,因此草图需要记住一个时刻: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

点击运行,进行游戏,查看 Serial 监视器,然后点击检查。

亲手试试

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

// 一轮中的三种状态
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 在线编辑器