Как я могу получить точное время?

16

Я сделал часы, используя Arduino, но время кажется дрейфующим. Я знаю о проблеме пролонгации ; часы, кажется, дрейфуют примерно на 15 минут в течение недели.

Я использую собственную плату с этим резонатором от Digi-key. Код читает функцию millis () в начале каждого цикла и работает с этим значением.

Мой вопрос: как я могу измерить время с Arduino, достаточно точно, чтобы сделать сносные настольные часы?

Джон Валтур
источник
3
Функция миллисекунды снабжается данными от прерывания, для запуска которого требуется пара тактов. Это добавляет крошечное количество времени каждому тику.
TheDoctor
3
@TheDoctor: это неверно. Прерывание не замедляет аппаратный таймер, который управляет millis().
Эдгар Бонет

Ответы:

15

Примечание: хотя мой ответ был принят и получил более высокий балл, обязательно прочитайте отличный ответ Эдгара Бонета о том, как заставить Arduino проводить время без RTC.

Я довольно успешно использовал часы реального времени DS1307. Вот ссылка на его таблицу данных .

Ниже приведены некоторые из его особенностей:

  • Он использует интерфейс IC для связи с Arduino, что облегчает программирование с использованием нужных библиотек (доступных в сети).

  • Он подключен к Arduino через контакты SCL и SDA (аналог A4 и A5 соответственно), используя только 2 контакта.

  • Для работы требуется очень мало внешних компонентов.

  • Он может быть подключен к батарейке типа «таблетка», поэтому он будет работать даже при выключенном Arduino. В режиме низкого энергопотребления батарея типа «таблетка» работает в течение многих лет.

  • Это дрейфует очень мало (в моем случае это дрейфует только несколько секунд в неделю).

  • Это не очень дорого.

Если вы не намерены использовать RTC, вы можете заменить кристалл, который обычно используется для предоставления тактовых импульсов для Arduino, для модуля кварцевого генератора, такого как этот от Farnel или этот другой . Они входят в 4-контактные пакеты, как на рисунках ниже. Они будут генерировать гораздо более точные часы для вашего Arduino.

Изображение кварцевого генератора Изображение кварцевого генератора Изображение кварцевого генератора

Оба упомянутых модуля имеют допуски 50 ppm и работают при 5 В.

Опять же, для ясности, эти модули кварцевого генератора не следует путать с обычным 2-контактным кристаллом, как показано ниже. Это, например, часть схемы внешних часов для микроконтроллеров.

Кварцевый генератор

Рикардо
источник
Достаточно ли хорош DS1302 или мне следует перейти на DS1307?
Келли С. Френч
14

Для создания часов вам не нужен RTC: чип ATmega имеет все оборудование, необходимое для выполнения функций самого RTC. Вот как:

  1. Получите часовой кристалл на 32768 Гц: либо купите его, либо разберите старые часы. Эти кристаллы, специально предназначенные для выдерживания времени, имеют очень маленький температурный дрейф. Вам также понадобится один из них, если вы хотите использовать чип RTC.

  2. Сконфигурируйте предохранители вашего ATmega для запуска 8-МГц RC генератора. Это сделает вашу millis()функцию ужасно неточной, а также освободит контакты XTAL1 и XTAL2.

  3. Подключите часовой кристалл к контактам TOSC1 и TOSC2. Это те же контакты, что и XTAL1 и XTAL2 (9 и 10 на 328P). Разные имена используются для обозначения разных функций.

  4. Сконфигурируйте Таймер / Счетчик 2 для асинхронной работы, нормального режима подсчета, предварительного масштабирования, установленного на 128, и включите прерывание переполнения таймера.

Теперь вы получите прерывание TIMER2_OVF с очень постоянной частотой один раз в секунду. Вам нужно только продвинуть показ часов на одну секунду в ISR. В промежутках между прерываниями вы можете поместить MCU в очень глубокий режим сна (режим ожидания с энергосбережением: ничего не работает, кроме таймера / счетчика 2) и годами работать на паре ячеек АА. Если, конечно, дисплей потребляет много энергии.

Я сделал именно это, чтобы построить свои 24-часовые настенные часы с одной рукой . Эта ссылка указывает теперь на английский перевод оригинальной документации на французском языке.

Кварцевая калибровка

Если вы не откалибруете свой кварц, вы можете ожидать значительного дрейфа, обычно несколько секунд в неделю . Скорость дрейфа зависит от паразитной емкости следов, которые соединяют кристалл с MCU. В принципе, это может быть удалено добавлением некоторой дополнительной, точно настроенной емкости. Стоит отметить, что у вас будет та же проблема с дрейфом с RTC.

Если вы удовлетворены такой точностью, то живите ею и будьте счастливы. Однако, если вы захотите измерить дрейф, вы заметите, что он очень стабилен. Затем вы можете легко компенсировать это с помощью программного обеспечения и достичь точности в несколько секунд в год .

Алгоритм коррекции дрейфа очень прост. Из измеренного дрейфа вы вычисляете точную задержку между прерываниями, которая должна быть очень близка к 10 9  наносекундам, затем:

#define ONE_SECOND    1000000000  // in nanoseconds
#define ONE_INTERRUPT  999993482  // for example

ISR(TIMER2_OVF_vect)
{
    static uint32_t unaccounted_time;

    unaccounted_time += ONE_INTERRUPT;
    while (unaccounted_time >= ONE_SECOND) {
        advance_display_by_one_second();
        unaccounted_time -= ONE_SECOND;
    }
}

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

Этот тип калибровки также может быть выполнен для RTC, но он будет значительно более сложным, потому что RTC сообщает время в разбивке, что, естественно, не подходит для арифметических операций.

Эдгар Бонет
источник
Вау, это действительно отличный дизайн! Мне очень нравится, как вы выложили достаточно фотографий, чтобы прояснить дизайн, даже для нас, глупых американцев-моноглотов :) Мне очень нравится видеть подробную проектную документацию, подобную этой!
Джон Валтур
2
@JohnWalthour: Спасибо! Теперь вы предлагаете мне написать перевод. :-)
Эдгар Бонет
2
@JohnWalthour: Готово! Ссылка теперь указывает на английский перевод.
Эдгар Бонет
Просто для ясности, когда вы говорите: «Чип ATmega имеет все необходимое оборудование», это не совсем верно, когда вам нужно получить новый кристалл. Я думаю, что ваше решение гладкое и не заменит кристалл, но я был немного озадачен, когда вы говорите, что мне не нужно аппаратное обеспечение, а затем оборачиваетесь и говорите, что мне нужно заменить аппаратное обеспечение.
Келли С. Френч
@ KellyS.French: Мое предложение было «у микросхемы ATmega есть все оборудование, необходимое для выполнения обязанностей самого RTC » (выделение добавлено). Но тогда важно отметить, что большинству RTC, включая вездесущий DS1307, нужен внешний кристалл для работы. ATmega ничем не отличается: в нем есть все, что нужно для замены самого RTC , но не для замены кристалла, который вам все равно придется подключить к RTC. Обратите внимание, что модуль RTC - это больше, чем просто RTC, поскольку он включает в себя кристалл.
Эдгар Бонет
6

Резонатор, который вы указали, имеет стабильность 0,3%, где кристалл или кварцевый генератор (как упомянуто Рикардо) составляет 50 частей на миллион. Во много раз стабильнее. Не говоря уже о температурном дрейфе резонатора, это ужасно. Нагрев солнечным светом изменит это. Следовательно, резонатор не должен использоваться для хранения времени в течение длительных периодов.

Следовательно, используя кристалл или кварцевый генератор, вы получите то, что вам нужно. Либо используйте его на ATmega и установите предохранители соответственно, либо используйте подключенный к RTC.

mpflaga
источник
Где 50 промилле это 0,005% стабильности?
Мэтью Г.
Я обобщаю эту спецификацию, чтобы кратко ответить. Обратите внимание на стабильность в сторону Res. имеют гораздо большую толерантность и могут быть совсем выключены. Как Джон W переживает. "правильная часть для правильной работы"
mpflaga
О, мне просто интересно узнать терминологию @mpflaga ... новость для меня.
Мэтью Г.
4

Если вы не хотите использовать дополнительное оборудование, такое как часы реального времени (например, DSDS1307), вы можете значительно повысить точность синхронизации, отключив все неиспользуемые прерывания. По умолчанию в набросках Arduino включены различные подпрограммы прерывания, и зачастую они не используются в действительности для вашего эскиза. Самый быстрый способ узнать, если вы можете обойтись без него, чтобы попытаться отключить их, выполнивnoInterrupts();

jippie
источник
3
-1 (хотя это заслуживает −4), потому что: 1. Если они вам действительно не нужны, все прерывания по умолчанию отключены, за единственным исключением TIMER0_OVF, который необходим для отсчета времени. 2. Точность синхронизации Arduinos ограничена главным образом качеством резонатора. 3. Не Прерывания делать не влияют на точность , millis()если не удается провести более одной миллисекунды в то время их обслуживания, в этом случае у вас есть другие проблемы ... 4. Отключение прерываний с noInterrupts()помешают millis()от отсчитывает время на всех!
Эдгар Бонет
2

Я понимаю, что дух Arduino во многом скромен и иногда перебирает проблему. Я использую Arduino (а теперь и chipKIT, так как он имеет 10-кратную оперативную память и 10-кратную тактовую частоту) для своего рабочего места, и мне нужны «периферийные функции», чтобы быть в курсе и работать как можно быстрее.

Я использую часы реального времени sparkfun в одном из своих проектов и очень им доволен. У них также есть вариант «Dead on» .

Крис К
источник