millis()
millis() возвращает количество миллисекунд с момента старта скетча — незаменима для неблокирующих таймеров. Результат сохраняйте в unsigned long.
Полная статья
Описание
millis() — одна из самых часто используемых функций в Arduino-скетчах. Она возвращает количество миллисекунд, прошедших с момента начала выполнения программы на плате Arduino. Главное её преимущество перед delay() — она не блокирует выполнение кода. Это позволяет строить таймеры и расписания, не останавливая работу всего скетча.
Счётчик переполняется и сбрасывается в ноль примерно через 50 дней непрерывной работы.
Синтаксис
millis()
Параметры
Функция не принимает никаких параметров.
Возвращает
Количество миллисекунд с момента старта программы. Тип возвращаемого значения — unsigned long.
Важно сохранять результат именно в переменную типа unsigned long. Если использовать int или даже long, значение быстро выйдет за допустимый диапазон и арифметика с таймером начнёт давать неверные результаты.
Пример кода
Скетч ниже каждую секунду выводит в Serial Monitor количество миллисекунд, прошедших с момента запуска программы на плате Arduino.
unsigned long myTime;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Time: ");
myTime = millis();
Serial.println(myTime); // выводит время с момента запуска программы
delay(1000); // пауза в секунду, чтобы не отправлять слишком много данных
}
Где применяется
- Неблокирующие задержки — вместо
delay()проверяют, прошёл ли нужный интервал, и продолжают выполнять другой код в это время. - Антидребезг кнопок — фиксируют момент первого срабатывания и игнорируют повторные сигналы в течение нескольких миллисекунд.
- Периодические задачи — отправка данных по Serial, опрос датчиков, мигание светодиодом с заданным периодом без блокировки.
- Измерение длительности событий — вычисляют разницу между двумя вызовами
millis(), чтобы узнать, сколько времени прошло между двумя состояниями.
Практические замечания
- Всегда объявляйте переменную для хранения результата как
unsigned long. Дажеlongсо знаком вдвое меньше по максимальному значению, что приводит к ошибкам уже через ~24 дня. - Разность двух значений
millis()корректно работает даже при переполнении счётчика — благодаря беззнаковой арифметике. Поэтому паттернif (millis() - previousMillis >= interval)надёжен и не требует специальной обработки переполнения. - На платах с AVR-микроконтроллером (16 МГц)
millis()увеличивается каждые ~1,024 мс, а не ровно каждую миллисекунду. Чтобы компенсировать накопленную погрешность, счётчик периодически увеличивается на 2 вместо 1 — каждые 41 или 42 тика. Из-за этогоmillis()некоторые значения пропускаются. Для точного измерения коротких интервалов используйтеmicros(). millis()сбросится в ноль примерно через 50 дней (для сравнения:micros()— примерно через 70 минут).- Изменение конфигурации аппаратных таймеров микроконтроллера напрямую влияет на точность
millis()чтения — избегайте этого, если вам важна точность времени.