Насколько точно Arduino отсчитывает время?
Я хочу использовать Arduino, чтобы выключить свет на 16 часов и включить на 8 часов. Я знаю общий код, использую только задержки и код релейного шилда. Хочу узнать, насколько это будет точно? (Я отметил теги uno и leonardo, так как у меня есть доступ к обоим)
@Peter, 👍2
Обсуждение1 ответ
Как уже отмечалось, это зависит от генератора, используемого в основном микроконтроллере, и необходимо отличать его от любой микросхемы, обеспечивающей USB-связь на платах, таких как UNO R3. Для двух упомянутых вами плат генераторы для основного микроконтроллера следующие:
- UNO R3: керамический генератор;
- Леонардо: кварцевый генератор.
Недавно я провёл тестирование на нескольких (оригинальных) платах Arduino. Полные результаты можно посмотреть в разделе Instructables: Подробное сравнение Arduino: UNO R3, Leonardo, UNO R4 Minima и UNO R4 WiFi. На графике ниже показано, что UNO R3 теряет 90 секунд, а Leonardo — 2 секунды (и две платы R4) в день. Последняя с кварцевым резонатором явно лучше. Эти значения зависят от температуры и могут различаться в зависимости от платы из-за разных генераторов.

После измерения этих отклонений их можно использовать для расчета простого линейного поправочного коэффициента, который значительно улучшит часы и позволит удерживать суточную погрешность менее 1 секунды.

Другой вариант — часы реального времени (RTC). Я тестировал Microchip MCP7940N, полные результаты можно увидеть в статье Instructables: Making an Accurate Stylish Clock With the Kitronik ZIP Halo HD and BBC Micro:bit in MicroPython. Это было для платы Kitronik ZIP Halo HD V1.0. Сейчас у меня пять V1.1, и их кварцы работают гораздо ближе к 32,768 кГц. (Оригинальный) Analog Devices DS3231 RTC кажется хорошим выбором для Arduino.
Примечание: следует проявлять осторожность при выборе функций синхронизации. В документации описывается реализация функции mills() на микросхемах AVR (например, UNO R3 и Leonardo). Ниже представлен фрагмент.
Значение millis() увеличивается (для микросхем AVR с частотой 16 МГц и некоторых других) каждые 1,024 миллисекунды, а затем увеличивается на 2 (а не на 1) каждые 41 или 42 такта для восстановления синхронизации; таким образом, некоторые значения millis() пропускаются. Для точного измерения времени на коротких интервалах рекомендуется использовать micros().
- Получение BPM из данного кода
- Проблемы с передачей данных через RF24
- Как читать данные аналогового датчика с помощью разных таймеров в Arduino
- Как использовать SPI на Arduino?
- Какова работа pulseIn?
- Сколько датчиков может поддерживать один модуль Arduino?
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
Функция delay() в Arduino на самом деле не предназначена для измерения времени. При *однократном* использовании на средней длительности она может в лучшем случае приближаться к точности часов, но её *повторное* использование для получения более длительного периода времени — ошибка, поскольку начальная/конечная погрешность и детализация будут накапливаться. Вместо этого следует использовать функцию, которая учитывает совокупное количество тактов часов, прошедших за *весь* интересующий интервал., @Chris Stratton