Menu
CoddyTech

Мигание без задержки

Часть раздела Отсчёт времени без 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, поэтому светодиод будет менять состояние в каждом цикле и будет казаться наполовину горящим.

challenge icon

Задание

Средне

Жёлтый светодиод должен следовать за кнопкой, но он реагирует с задержкой, потому что вызовы 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);
}
quiz iconПроверьте себя

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

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

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