Почему плохо использовать delay() в Arduino и чем его заменить (millis)?
Сделал так, чтобы светодиод мигал через delay(1000). Но теперь хочу, чтобы одновременно ещё читалась кнопка. А пока идёт delay, плата как будто замирает и кнопку не видит. Как делать несколько вещей сразу?
2 ответа
Ты столкнулся с главным минусом delay(): пока он идёт, Arduino полностью замирает и ничего больше не делает — не читает кнопки, не опрашивает датчики. Для одной задачи это ок, но для нескольких — беда.
Решение — функция millis(). Она возвращает, сколько миллисекунд прошло с включения, и ты сам проверяешь «пора ли», не останавливая программу:
unsigned long prev = 0;
int state = LOW;
void setup() {
pinMode(13, OUTPUT);
pinMode(2, INPUT_PULLUP);
}
void loop() {
// мигаем без остановки программы
if (millis() - prev >= 1000) {
prev = millis();
state = !state;
digitalWrite(13, state);
}
// а это работает ПАРАЛЛЕЛЬНО, кнопка читается всегда
if (digitalRead(2) == LOW) {
// нажата
}
}
Идея: вместо «подожди секунду» ты говоришь «если с прошлого раза прошла секунда — сделай и запомни время». loop() крутится свободно, и кнопка опрашивается на каждом круге. Это базовый приём для всего, где нужно «несколько дел сразу».
millis() поначалу кажется сложнее, чем delay(), но это тот навык, который отличает «помигать диодом» от настоящего робота. Как только надо одновременно мигать, пищать и слушать датчик — delay() сразу мешает, а millis() спасает.