Menu
CoddyTech

Trò chơi phản xạ: Bộ hẹn giờ

Thuộc phần Dự án trong hành trình Arduino của Coddy. Bài học 6 trên 24.

Giờ trò chơi sẽ đo phản xạ của bạn. Thời gian phản ứng là khoảng thời gian từ lúc đèn LED sáng đến khi bạn nhấn nút, vì vậy chương trình cần ghi nhớ một thời điểm: lúc đèn LED sáng.

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

Khi bạn nhấn nút trong trạng thái LIT, hiệu số chính là kết quả:

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

Điều này chỉ hoạt động vì chương trình không bao giờ dừng lại trong delay(): loop() kiểm tra nút hàng nghìn lần mỗi mili giây, nên chương trình phát hiện lần nhấn chưa đầy một mili giây sau khi nó xảy ra. Hầu hết mọi người cần từ 200 đến 300 ms.

challenge icon

Thử thách

Trung bình

Đo thời gian của người chơi:

  • lưu millis() vào litAt khi LED sáng
  • khi người chơi nhấn nút trong trạng thái LIT, tính millis() - litAt
  • in ra kết quả theo dạng Reaction: 250 ms

Nhấn Chạy, chơi, đọc màn hình Serial, rồi nhấn Kiểm tra.

Tự làm thử

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

// Ba trạng thái của một lượt chơi
enum State { READY, WAITING, LIT };
State state = READY;

int lastButton = HIGH;       // Giá trị đọc từ nút bấm ở lần trước
unsigned long waitStart = 0; // Thời điểm bắt đầu chờ
unsigned long waitTime = 0;  // Thời gian chờ kéo dài bao lâu

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);  // Nút vừa được nhấn
  lastButton = button;
  unsigned long now = millis();

  switch (state) {
    case READY:
      if (pressed) {
        randomSeed(micros());  // Thời điểm nhấn nút không bao giờ trùng nhau giữa hai lần
        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 iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Dự án

Tự luyện tập: Playground Arduino