Корректировка частоты работы кварца DS3231

AntonM
Offline
Зарегистрирован: 22.10.2015

Всем Привет!

Как оказалось, продолжая мои эксперименты с синхронизацией 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?

Всем спасибо заранее!

a5021
Offline
Зарегистрирован: 07.07.2013

AntonM пишет:
получаю расхождение в 0,01 секунду, а это - 87секунд в год! В datasheet'е сооовсем другая цифра! Почему у точных часов такой расколбас?!

Другая цифра -- это какая? По даташиту 2ppm или 63 секунды в год. Не такой уж и расколбас.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Антон,

вот я в прошлый раз Вас спрашивал, Вы не ответили, может сейчас ответите – Вы можете объяснить толком, зачем Вам городить такой сложный огород? Почему не сделать прямую синхронизацию, как её делают все нормальные люди?

Вот смотрите, одна Ардуина – главная щелкает своим таймером и раз в какое-то (нужное Вам) время даёт короткий сигнал (совсем короткий – можно в 1 такт) на один из своих пинов.

Этот пин соединён с пинами двух других ардуин, а на тех двух ардуинах на соответсвующие пины заведены прерывания. Получается. что прерывание случается всегда, когда главная ардуина «тикает» своим коротким сигналом.

Вот и всё – все три отлично синхронизированы – никуда не разбегутся.

Расходы – по одному пину на каждой ардуине, что значительно меньше, чем использовать часы.

Почему так не сделать?

AntonM
Offline
Зарегистрирован: 22.10.2015

Я лично о 52сек в год у Максим читал.

Все же 2ррм - это я так понимаю максимальное расхождение. А тут оно намного выше

AntonM
Offline
Зарегистрирован: 22.10.2015

ЕвгенийП, вы вероятно не поняли мою систему.

Все 3 ардуино работают автономно, совсем автономно! У каждой свой корпус, источник питания и свой модуль ESP-201 и DS3231. Передача данных идет через ESP-201 по Wi-Fi. Сами модули будут на разных частях площадки.

Проводная система у меня и так собрана, проблема сейчас сделать ее беспроводную реализацию, при который при случайном внепроектном обрыве связи данные о событии записались в память ардуино.

di_mot
Offline
Зарегистрирован: 12.08.2016

AntonM пишет:

ЕвгенийП, вы вероятно не поняли мою систему.

Все 3 ардуино работают автономно, совсем автономно! У каждой свой корпус, источник питания и свой модуль ESP-201 и DS3231. Передача данных идет через ESP-201 по Wi-Fi. Сами модули будут на разных частях площадки.

Проводная система у меня и так собрана, проблема сейчас сделать ее беспроводную реализацию, при который при случайном внепроектном обрыве связи данные о событии записались в память ардуино.

Ну так для этого есть решение. Всё тоже, что и предлагает ЕвгенийП. С той разницей, что передча "синхронизации" идет не по проводу.

Так весь Инет работает. Сервера переодически соеденяются с Сервером Времени и получают от него ТОЧНОЕ время. Дальше делают расчет поправки для локальных "часиков", каждый под своё железо.

На площадке провайдера есть свой "Сервер Времени" (СВ), от которого синхронизируются его железки. А локальный - синхронизируется со глобальным СВ. Ну что бы все железяки чохом не ломились в глобальный СВ за временем.

Ведь даже кварцы на разных платах, в том числе и Ардуино, имеют разную точность. ;-)

Что и как - см. Network Time Protocolпротокол сетевого времени

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

di_mot пишет:

Ну так для этого есть решение.

...

Так весь Инет работает.

...

Что и как - см. Network Time Protocolпротокол сетевого времени

А ничего, что точность не превышает одной секунды?

di_mot
Offline
Зарегистрирован: 12.08.2016

andriano пишет:

А ничего, что точность не превышает одной секунды?

- Где? ;-)

NTP обеспечивает точность синхронизации времени в диапазоне от 1 до 4 мс.

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

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

a5021
Offline
Зарегистрирован: 07.07.2013

hehehehehe. "NTP v4 with kernel mods to support it, is capable of much better than 1ms accuracy, possibly as good as 1ns."

AntonM
Offline
Зарегистрирован: 22.10.2015

Объясню просто - смотрите, есть 2 бегуна, которые совершенно одинаково бегут 100метровку. С помощью модулей замерим их. У одного будет 13,453, а у другого 12,988. Почему? А потому что таймеры синхронизовались и "съели" немного времени....

Система моя - хронометраж по лазерным датчикам. Поэтому не хотел бы я так поступать.

di_mot
Offline
Зарегистрирован: 12.08.2016

AntonM пишет:

Почему?

 - Патамушта! ;-)

Не правильно поставлена и реализованная задача.

С начала синхронизируем время. По готовности обоих "таймеров" даем старт бегуну.

Какая разница в измерении времени между 2-мя "таймерами" набежит за само время измерения? :-)

AntonM
Offline
Зарегистрирован: 22.10.2015

Объясню. Трасса у автомобиля занимает 4 минуты. Естественно 4 минуты ждать не целесообразно и совершенно не экономно. Поэтому участники стартуют через 1 минуту.

di_mot
Offline
Зарегистрирован: 12.08.2016

AntonM пишет:
Трасса у автомобиля занимает 4 минуты.

Надеюсь заезды мафынок идут не в режиме 24х7х365? ;-)

Извини, но "объяснение" ни чего не объясняет. А на оборот, только покзывает, что ты методически "видишь" только свое видение задачи.

1. Если хотя бы раз в сутки есть "дырка" для синхронизации времени, то можно расчитать индивидуальный "уход" времени каждого девайса между 2-х синхронизаций и вносить персональную поправку.

2. Если ушь требуется такая точность, то вопрос о термостабилизации кварцевых резонаторов имеет место быть. Даже в совковые времена в радиолюбительских частотомерах на К155 считалось хорошим тоном кварц на 10 мгц порместить в "термостат". Или хотя бы в пенопластовую корбочку из-под реле РЭС-49 или аналогичных. Сам кварц ставили не в метал. корпусе, а в стеклянной колбе. Вакуум хороший термоизолятор.

3. Кварц в модулях DS3231 не самый и точный, а из серии "самый ширпотреб". Но на основе его ты хочешь сделать супер точную систему. Тут вопрос уже о метрологии.

Это так, заметки на полях...

a5021
Offline
Зарегистрирован: 07.07.2013

di_mot пишет:
3. Кварц в модулях DS3231 не самый и точный, а из серии "самый ширпотреб". Но на основе его ты хочешь сделать супер точную систему. Тут вопрос уже о метрологии.

Ширпотреб -- это 20..50ppm. 2ppm -- это уже дорогие, высокоточные и стабилизированные кварцы.

di_mot
Offline
Зарегистрирован: 12.08.2016

a5021 пишет:

Ширпотреб -- это 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 пишет:
... При этом получается беда - через примерно 60 минут получаю расхождение в 0,01 секунду, а это - 87секунд в год! В datasheet'е сооовсем другая цифра! Почему у точных часов такой расколбас?!

(выделение моё, если чё.)

Так что, ушь извини AntonM, но твой "результат" не так и плох для этих м/с. Укладывается в норму по даташиту.

За что нарыл, за то и запостил: Что такое ppm для частоты кварца?

a5021
Offline
Зарегистрирован: 07.07.2013

di_mot пишет:

В даташите на саму мелкосхемку 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 минут.