Переключаем режимы кнопкой
Часть раздела Отсчёт времени без delay путешествия по Arduino на Coddy. Урок 11 из 18.
У многих гаджетов есть одна кнопка, которая переключает режимы: велосипедный фонарь выключен, включён, мигает, быстро мигает, а затем снова выключен. Это конечный автомат, в котором переход к следующему состоянию выполняется нажатием кнопки, а не по таймеру.
Вынеси переключение в отдельную функцию. Конструкция switch задаёт следующий режим на основе текущего, а из последнего режима возвращает к первому:
void nextMode() {
switch (mode) {
case OFF:
mode = ON;
Serial.println("ON");
break;
// ... и так далее, пока FAST снова не перейдёт в OFF
}
}Скетч вызывает nextMode() один раз при каждом нажатии. Устрани дребезг кнопки так, как ты научился в разделе «Входы»: когда показание меняется, выполни действие, а затем подожди 20 мс, пока контакты не стабилизируются. Вторая конструкция switch на основе mode задаёт состояние светодиода.
Задание
СреднеКнопка и светодиод уже написаны за тебя. Напиши 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;
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Отсчёт времени без delay
1millis()
Часы на millis()Время в unsigned longМигание без задержкиДва светодиода, две скоростиМигание и переключение кнопкойСвет по таймеру4Точное измерение времени
Измерение с помощью micros()Когда millis() переполняетсяСекундомер с кнопкой2Конечные автоматы
Запоминаем режимВыбор с помощью switchИменованные состояния с enumКонечный автомат светофораПереключаем режимы кнопкойПотренируйтесь самостоятельно: Песочница Arduino