Разница между delay() и циклом while с millis() в Arduino?

В чём практическая разница между использованием delay() и цикла while с millis() для отсчёта времени в проектах Arduino? Я предполагал, что оба метода блокирующие, но не совсем в этом уверен.

Пример использования цикла while:

unsigned long start = millis();
while (millis() - start <= interval) {
    DoSomething();
}

Пример использования delay():

StartSomething();
delay(interval);
StopSomething();

Как эти методы соотносятся с точки зрения блокирующего поведения, скорости реагирования и потенциальных компромиссов?

, 👍0

Обсуждение

они оба блокируют ... используйте if вместо while, @jsotola


2 ответа


0

В первом примере функция DoSomething() выполняется многократно, пока не истечет интервал.

Во втором примере выполняется StartSomething(), затем ничего не происходит до истечения интервала, а затем выполняется StopSomething один раз.

В написанном виде они оба блокируют. Но, заменив while в первом примере на if и включив его в другой цикл или в функцию loop(), вы сможете вставить другой, возможно, похожий код выше или ниже него, так что внешний цикл будет непрерывно проверять все интересующие вас условия и выполнять определённое действие каждый раз, когда одно из этих условий становится истинным. В основе неблокирующего кода лежит принцип никогда ничего не ждать, а продолжать проверять условия и выполнять определённое действие каждый раз, когда одно из условий становится истинным.

,

0

Да, оба метода являются блокирующими.

Использование delay() обычно приводит к написанию меньшего количества кода, а задержка более точным. Обычно погрешность составляет всего несколько микросекунд. Загруженный цикл который вызывает millis(), будет отставать на одну целую миллисекунду, если start равен инициализируется непосредственно перед увеличением счетчика millis().

Если вам нужна неблокируемость, вам нужно написать что-то вроде этого:

// Начинаем что-то, когда это уместно.
if (!something_started && maybe_another_condition) {
    StartSomething();
    something_started = true;
    time_stated = millis();
}

// Остановите что-нибудь, когда это уместно.
if (something_started && millis() - time_stated >= interval) {
    StopSomething();
    something_started = false;
}
,