Menu
CoddyTech

Переключаем режимы кнопкой

Часть раздела Отсчёт времени без delay путешествия по Arduino на Coddy. Урок 11 из 18.

У многих гаджетов есть одна кнопка, которая переключает режимы: велосипедный фонарь выключен, включён, мигает, быстро мигает, а затем снова выключен. Это конечный автомат, в котором переход к следующему состоянию выполняется нажатием кнопки, а не по таймеру.

Вынеси переключение в отдельную функцию. Конструкция switch задаёт следующий режим на основе текущего, а из последнего режима возвращает к первому:

void nextMode() {
  switch (mode) {
    case OFF:
      mode = ON;
      Serial.println("ON");
      break;
    // ... и так далее, пока FAST снова не перейдёт в OFF
  }
}

Скетч вызывает nextMode() один раз при каждом нажатии. Устрани дребезг кнопки так, как ты научился в разделе «Входы»: когда показание меняется, выполни действие, а затем подожди 20 мс, пока контакты не стабилизируются. Вторая конструкция switch на основе mode задаёт состояние светодиода.

challenge icon

Задание

Средне

Кнопка и светодиод уже написаны за тебя. Напиши nextMode(), чтобы каждое нажатие переключало на следующий режим и выводило его название: OFF, ON, BLINK, FAST, а затем снова OFF.

Нажми Запустить, нажми кнопку несколько раз, затем нажми Проверить.

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

const int ledPin = 13;
const int buttonPin = 2;

enum Mode { OFF, ON, BLINK, FAST };
Mode mode = OFF;

bool wasPressed = false;
unsigned long blinkPrevious = 0;
int ledState = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
}

// Переходит к следующему режиму и выводит его название.
void nextMode() {
  // по одному case на каждый режим: установить следующий режим, вывести его название, break
}

// Переключает состояние светодиода каждые interval мс.
void blinkEvery(unsigned long interval) {
  unsigned long now = millis();
  if (now - blinkPrevious >= interval) {
    blinkPrevious = now;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}

void loop() {
  // 1. нажатие (с подавлением дребезга) вызывает nextMode()
  bool pressed = digitalRead(buttonPin) == LOW;
  if (pressed != wasPressed) {
    if (pressed) {
      nextMode();
    }
    wasPressed = pressed;
    delay(20);   // дать контактам стабилизироваться
  }

  // 2. режим определяет, что делает светодиод
  switch (mode) {
    case OFF:
      digitalWrite(ledPin, LOW);
      break;
    case ON:
      digitalWrite(ledPin, HIGH);
      break;
    case BLINK:
      blinkEvery(500);
      break;
    case FAST:
      blinkEvery(100);
      break;
  }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Отсчёт времени без delay

Потренируйтесь самостоятельно: Песочница Arduino