Menu
CoddyTech

Игра на реакцию: таймер

Часть раздела Проекты путешествия по Arduino на Coddy. Урок 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() проверяет кнопку тысячи раз за миллисекунду, поэтому нажатие обнаруживается менее чем через миллисекунду после того, как произошло. Большинству людей требуется от 200 до 300 мс.

challenge icon

Задание

Средне

Засеки время игрока:

  • сохрани millis() в litAt, когда загорится LED
  • когда нажатие произойдёт в состоянии LIT, вычисли millis() - litAt
  • выведи результат в формате Reaction: 250 ms

Нажми Run, сыграй, прочитай данные в Serial monitor, затем нажми Check.

Попробуйте сами

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