Главная chevron_right Функции chevron_right Время chevron_right millis()

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() чтения — избегайте этого, если вам важна точность времени.