Мигание без задержки
Часть раздела Отсчёт времени без delay путешествия по Arduino на Coddy. Урок 3 из 18.
delay() останавливает весь скетч. Пока мигающий светодиод ждёт 500 ms, в loop() больше ничего не выполняется: нажатие кнопки в это время не будет замечено, пока ожидание не закончится.
Решение — никогда не ждать. Пусть loop() снова и снова выполняется очень быстро, и каждый раз сравнивай часы с моментом, когда светодиод в последний раз изменился. Пока не прошло 500 ms, ничего не делай. Затем измени состояние светодиода и сохрани новый момент:
const unsigned long interval = 500;
unsigned long previousMillis = 0; // когда светодиод в последний раз изменил состояние
void loop() {
unsigned long now = millis();
if (now - previousMillis >= interval) {
previousMillis = now; // запомнить этот момент
// здесь переключить светодиод
}
// всё остальное здесь выполняется тысячи раз в секунду
}now - previousMillis — это время, прошедшее с последнего изменения. Чтобы переключать светодиод, храни его состояние в переменной: int redState = LOW;, меняй его с помощью if/else и записывай его с помощью digitalWrite(redLed, redState);.
Если забыть обновить previousMillis, условие останется истинным после первых 500 ms, поэтому светодиод будет менять состояние в каждом цикле и будет казаться наполовину горящим.
Задание
СреднеЖёлтый светодиод должен следовать за кнопкой, но он реагирует с задержкой, потому что вызовы delay() для красного светодиода останавливают цикл. Перепиши мигание красного светодиода с помощью millis():
- оставь часть с кнопкой без изменений
- каждые 500 ms переключай красный светодиод на выводе 13
- нигде не используй
delay()
Нажми Run, удерживай кнопку и наблюдай за обоими светодиодами, затем нажми Check.
Попробуйте сами
const int redLed = 13;
const int yellowLed = 12;
const int buttonPin = 2;
void setup() {
pinMode(redLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
// Жёлтый светодиод реагирует на кнопку. Оставьте эту часть без изменений.
if (digitalRead(buttonPin) == LOW) {
digitalWrite(yellowLed, HIGH);
} else {
digitalWrite(yellowLed, LOW);
}
// Красный светодиод мигает, но каждый вызов delay() приостанавливает выполнение строк выше
// на полсекунды. Перепишите эту часть с использованием millis().
digitalWrite(redLed, HIGH);
delay(500);
digitalWrite(redLed, LOW);
delay(500);
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Отсчёт времени без delay
1millis()
Часы на millis()Время в unsigned longМигание без задержкиДва светодиода, две скоростиМигание и переключение кнопкойСвет по таймеру4Точное измерение времени
Измерение с помощью micros()Когда millis() переполняетсяСекундомер с кнопкойПотренируйтесь самостоятельно: Песочница Arduino