delay()
Останавливает выполнение скетча на заданное число миллисекунд — удобно для простых пауз, но блокирует всё, включая чтение кнопок и датчиков.
Полная статья
Описание
delay() останавливает выполнение программы примерно на столько миллисекунд, сколько вы передадите в параметре. За это время процессор не переходит к следующей строке кода — он просто ждёт. Это самый простой способ сделать паузу, но у него есть важные ограничения, о которых стоит знать с самого начала.
Синтаксис
delay(ms)
Параметры
ms — длительность паузы в миллисекундах. Тип данных: unsigned long. Это беззнаковое 32-битное целое, поэтому максимальная задержка составляет около 49 дней. На практике паузы длиннее нескольких секунд встречаются редко, а при больших значениях лучше пересмотреть архитектуру скетча.
Возвращает
Функция ничего не возвращает.
Пример кода
Скетч ниже переключает состояние вывода каждую секунду — классический «Blink»:
int ledPin = 13; // светодиод подключён к цифровому пину 13
void setup() {
pinMode(ledPin, OUTPUT); // настраивает цифровой пин как выход
}
void loop() {
digitalWrite(ledPin, HIGH); // включает светодиод
delay(1000); // ждёт одну секунду (1000 мс)
digitalWrite(ledPin, LOW); // выключает светодиод
delay(1000); // ждёт одну секунду (1000 мс)
}
Где применяется
- Мигание светодиода — самый распространённый учебный пример.
- Устранение дребезга кнопки — короткая пауза 10–50 мс после обнаружения нажатия, чтобы отсеять ложные срабатывания.
- Простые задержки инициализации — например, подождать 100–500 мс после подачи питания на датчик, прежде чем начать с ним общаться.
- Прототипирование — когда точное время не важно и нужно быстро проверить идею.
Блокирующее поведение: главный недостаток
Пока delay() держит программу на паузе, скетч не может делать больше ничего: не читать датчики, не обрабатывать кнопки, не обновлять дисплей. Если вы, например, вызываете delay() на 1000 мс, то в течение этой секунды нажатие кнопки будет полностью проигнорировано.
Если скетч должен реагировать на события во время ожидания, используйте подход без блокировки. Он основан на функции millis(): программа запоминает время последнего события и в каждом цикле loop() проверяет, прошло ли нужное время. Это позволяет параллельно читать кнопки, обновлять дисплей, принимать данные по Serial и выполнять другие задачи.
Опытные разработчики, как правило, избегают delay() для пауз длиннее 10 мс, если только скетч Arduino не выполняет одну-единственную задачу и никакой параллельной работы не требует.
Что происходит во время задержки
delay() не отключает прерывания, поэтому часть механизмов платы продолжает работать в штатном режиме:
- Последовательный порт (RX) — входящие байты по-прежнему принимаются и буферизируются.
- PWM (analogWrite()) — сигналы на соответствующих выводах не прерываются.
- Состояния выводов — сохраняются без изменений.
- Прерывания (attachInterrupt()) — продолжают срабатывать как обычно.
Иными словами, delay() блокирует только основной поток выполнения кода, но не аппаратную периферию.
Практические замечания
- Если нужна пауза меньше миллисекунды, используйте
delayMicroseconds()вместоdelay(). - Не передавайте в
msотрицательное число: типunsigned longинтерпретирует его как очень большое положительное значение, и программа зависнет на неожиданно долгое время. - Для дебаунсинга кнопок 20–50 мс обычно достаточно; большие значения только замедляют отклик.
- Если скетч использует несколько задержек подряд, их суммарное время может незаметно вырасти до сотен миллисекунд — это частая причина «тормозящего» поведения устройства.
- При отладке удобно временно уменьшить задержку до минимума и смотреть вывод в Serial Monitor — это ускоряет проверку логики без долгого ожидания.