Корректировка частоты работы кварца DS3231
- Войдите на сайт для отправки комментариев
Всем Привет!
Как оказалось, продолжая мои эксперименты с синхронизацией 3х ардуино по времени. Перед этим пытался сделать секунду с помощью TimerOne, но как оказалось секунда уж слишком разная у каждого из модулей.
В новой реализации система работает в связке с DS3231 и ESP-201. Но к сожалению, как оказалось, DS3231 тоже сильно разбегаются во времени - 2 ардуино, у которых прерывание идет по 1 ножке от SQW (без использования i2c шины). Миллисекунду получаю таймерным прерыванием с помощью TimerOne.
Перед этим выполняю на другом модуле настройку ds3231, и записываю в него настройку SQW выхода. Код скетча-настройки:
#include "Wire.h" #include "wiring.c" void setup() { Wire.begin(); Wire.beginTransmission(0x68); Wire.write(0x0E); // Control Register Wire.write(B01000000); // 1 Hz Out Wire.endTransmission(); Serial.begin(9600); }
Затем, заливаю основной код:
#include <SoftwareSerial.h> #include <TimerOne.h> SoftwareSerial dbgSerial(3, 2); /* RX:D3, TX:D2 */ // объявляем пины для UART long time0=0; long timesumm, timesec; int receive; void setup() { Serial.begin(115200); Serial.setTimeout(15000); Timer1.initialize(999); // 1000000ms=1s Timer1.attachInterrupt(timer); // объявляем таймерное прерывание attachInterrupt(1, herz, FALLING); Serial.println("AT+RST"); // сброс и проверка, если модуль готов delay(3000); Serial.println("AT+UART=115200,8,1,0,0"); //установка соединения UART delay(1000); Serial.println("AT+CIPMODE=1"); // установка в режим моста delay(500); Serial.println("AT+CIPMUX=0"); // установка в режим одиночного соединения delay(500); Serial.println("AT+CIPSTART=\"UDP\",\"192.168.0.100\",10000,10010,0"); // открываем UDP-соединение delay(500); Serial.println("AT+CIPSEND"); // начинаем приём-передачу delay(500); Serial.println("Wi-Fi connected, UDP is opened."); Serial.flush(); } void loop() { } String addZeroes(const String& src, byte pad) { if(src.length() >= pad) return src; String result; byte add = pad - src.length(); while(add--) result += "0"; result += src; return result; } void timer() { time0++; // общее время } void herz() { time0=0; timesec=timesec+1000; } void serialEvent() { if (Serial.available()) { // если есть принятый символ, receive = Serial.read(); // то читаем его и сохраняем в val if (receive == 'S') { // если принят символ 'S' (Synx)... timesumm=time0+timesec; String timesync=String(timesumm,HEX); String timesync0=addZeroes(timesync,8); Serial.println(timesync0); } if (receive == 'R') { // если принят символ 'R'(Reset)... time0=0; timesec=0; } if (receive == 'P') { // если принят символ 'P' (Ping)... Serial.println("OK"); } } }
И далее, с помощью широковещательного запроса, обнуляю значения таймеров символом R, и спустя некоторое время посылом символа S узнаю значения всех таймеров. При этом получается беда - через примерно 60 минут получаю расхождение в 0,01 секунду, а это - 87секунд в год! В datasheet'е сооовсем другая цифра! Почему у точных часов такой расколбас?!
Также в datasheet'е нашёл некий регистр, отвечающий за правку частоты работы сигнала - 10H.
Вопрос следующий - кто либо правил его? И какие еще методы можно использовать для повышения точности ds3231?
Всем спасибо заранее!
Другая цифра -- это какая? По даташиту 2ppm или 63 секунды в год. Не такой уж и расколбас.
Антон,
вот я в прошлый раз Вас спрашивал, Вы не ответили, может сейчас ответите – Вы можете объяснить толком, зачем Вам городить такой сложный огород? Почему не сделать прямую синхронизацию, как её делают все нормальные люди?
Вот смотрите, одна Ардуина – главная щелкает своим таймером и раз в какое-то (нужное Вам) время даёт короткий сигнал (совсем короткий – можно в 1 такт) на один из своих пинов.
Этот пин соединён с пинами двух других ардуин, а на тех двух ардуинах на соответсвующие пины заведены прерывания. Получается. что прерывание случается всегда, когда главная ардуина «тикает» своим коротким сигналом.
Вот и всё – все три отлично синхронизированы – никуда не разбегутся.
Расходы – по одному пину на каждой ардуине, что значительно меньше, чем использовать часы.
Почему так не сделать?
Я лично о 52сек в год у Максим читал.
Все же 2ррм - это я так понимаю максимальное расхождение. А тут оно намного выше
ЕвгенийП, вы вероятно не поняли мою систему.
Все 3 ардуино работают автономно, совсем автономно! У каждой свой корпус, источник питания и свой модуль ESP-201 и DS3231. Передача данных идет через ESP-201 по Wi-Fi. Сами модули будут на разных частях площадки.
Проводная система у меня и так собрана, проблема сейчас сделать ее беспроводную реализацию, при который при случайном внепроектном обрыве связи данные о событии записались в память ардуино.
ЕвгенийП, вы вероятно не поняли мою систему.
Все 3 ардуино работают автономно, совсем автономно! У каждой свой корпус, источник питания и свой модуль ESP-201 и DS3231. Передача данных идет через ESP-201 по Wi-Fi. Сами модули будут на разных частях площадки.
Проводная система у меня и так собрана, проблема сейчас сделать ее беспроводную реализацию, при который при случайном внепроектном обрыве связи данные о событии записались в память ардуино.
Ну так для этого есть решение. Всё тоже, что и предлагает ЕвгенийП. С той разницей, что передча "синхронизации" идет не по проводу.
Так весь Инет работает. Сервера переодически соеденяются с Сервером Времени и получают от него ТОЧНОЕ время. Дальше делают расчет поправки для локальных "часиков", каждый под своё железо.
На площадке провайдера есть свой "Сервер Времени" (СВ), от которого синхронизируются его железки. А локальный - синхронизируется со глобальным СВ. Ну что бы все железяки чохом не ломились в глобальный СВ за временем.
Ведь даже кварцы на разных платах, в том числе и Ардуино, имеют разную точность. ;-)
Что и как - см. Network Time Protocol — протокол сетевого времени
Ну так для этого есть решение.
...
Так весь Инет работает.
...
Что и как - см. Network Time Protocol — протокол сетевого времени
А ничего, что точность не превышает одной секунды?
А ничего, что точность не превышает одной секунды?
- Где? ;-)
NTP обеспечивает точность синхронизации времени в диапазоне от 1 до 4 мс.
Если не устраивает, то есть Протокол PTP. Является чрезвычайно гибким и может быть использован в различных областях, где требуется временная синхронизация, обеспечивая точность до 10 нс.
В общем-то вопрос достаточно проработан, что бы взять наиболее подходящее решение за основу для разработки чего-то своего. Хотя бы методы и принципы.
hehehehehe. "NTP v4 with kernel mods to support it, is capable of much better than 1ms accuracy, possibly as good as 1ns."
Объясню просто - смотрите, есть 2 бегуна, которые совершенно одинаково бегут 100метровку. С помощью модулей замерим их. У одного будет 13,453, а у другого 12,988. Почему? А потому что таймеры синхронизовались и "съели" немного времени....
Система моя - хронометраж по лазерным датчикам. Поэтому не хотел бы я так поступать.
Почему?
- Патамушта! ;-)
Не правильно поставлена и реализованная задача.
С начала синхронизируем время. По готовности обоих "таймеров" даем старт бегуну.
Какая разница в измерении времени между 2-мя "таймерами" набежит за само время измерения? :-)
Объясню. Трасса у автомобиля занимает 4 минуты. Естественно 4 минуты ждать не целесообразно и совершенно не экономно. Поэтому участники стартуют через 1 минуту.
Надеюсь заезды мафынок идут не в режиме 24х7х365? ;-)
Извини, но "объяснение" ни чего не объясняет. А на оборот, только покзывает, что ты методически "видишь" только свое видение задачи.
1. Если хотя бы раз в сутки есть "дырка" для синхронизации времени, то можно расчитать индивидуальный "уход" времени каждого девайса между 2-х синхронизаций и вносить персональную поправку.
2. Если ушь требуется такая точность, то вопрос о термостабилизации кварцевых резонаторов имеет место быть. Даже в совковые времена в радиолюбительских частотомерах на К155 считалось хорошим тоном кварц на 10 мгц порместить в "термостат". Или хотя бы в пенопластовую корбочку из-под реле РЭС-49 или аналогичных. Сам кварц ставили не в метал. корпусе, а в стеклянной колбе. Вакуум хороший термоизолятор.
3. Кварц в модулях DS3231 не самый и точный, а из серии "самый ширпотреб". Но на основе его ты хочешь сделать супер точную систему. Тут вопрос уже о метрологии.
Это так, заметки на полях...
Ширпотреб -- это 20..50ppm. 2ppm -- это уже дорогие, высокоточные и стабилизированные кварцы.
Ширпотреб -- это 20..50ppm. 2ppm -- это уже дорогие, высокоточные и стабилизированные кварцы.
В даташите на саму мелкосхемку DS3132 указано:
Accuracy ±2ppm from 0°C to +40°C
Accuracy ±3.5ppm from -40°C to +85°C
Там же на 9-й странице указано:
"The TCXO providesa stable and accurate reference clock, and maintains the RTC to within ±2 minutes per year accuracy from -40°C to +85°C."
... с точностью ±2 минуты в год от -40°C до +85°C.
2х60х1000=120000 мСек/год. Или 120000/365=328 миллисекунды/сутки, или ±13.69 мСек/час. То есть через час работы разница в показаниях 2-х модулей может достигнуть 27.38 мСек или 0.02738 сек. Когда один "убежал" в плюс, а другой в минус.
О чем автор и начал топик, см. 1-й пост:
(выделение моё, если чё.)
Так что, ушь извини AntonM, но твой "результат" не так и плох для этих м/с. Укладывается в норму по даташиту.
За что нарыл, за то и запостил: Что такое ppm для частоты кварца?
В даташите на саму мелкосхемку DS3132 указано:
Accuracy ±2ppm from 0°C to +40°C
Accuracy ±3.5ppm from -40°C to +85°C
Там же на 9-й странице указано:
"The TCXO providesa stable and accurate reference clock, and maintains the RTC to within ±2 minutes per year accuracy from -40°C to +85°C."
Все правильно. Для полного диапазона температур расчетное отклонение составит 60*60*24*365*3,5/1000000, т.е. ±110 секунд или окло 2 минут.