Корректировка частоты работы кварца 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 минут.