Обновление/коррекция времени
- Войдите на сайт для отправки комментариев
Доброго дня (ночи) всем. Помогите кто чем может - что то я уже четвертый день не могу время победить. Кристалл ESP32. Время обновляю с NTP по WIFI. Отдельного модуля RTC нету. Изначально думал время обновлять раз в сутки (пилю часы), но увидел что на сутки время уходит сильно. С целью понять на сколько уходит время, и обновляется ли оно вообще выделил в рабочем скетче вот такую подпрограмму:
void UpdateTime1()
{
//setTime(1500000000); //тут я время перед обновлением пытаюсь испортить так...
//adjustTime(100000); // и эдак, чтобы ошибку увидеть
getLocalTime(&timeinfo);
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); //время до обновления
oldTime1= time(nullptr);
Serial.print(1);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.print(2);
getLocalTime(&timeinfo);
Serial.print(3);
newTime1= time(nullptr);
Serial.print(4);
DiffTime= newTime1 - oldTime1; // Тут я надеялся погрешность времени увидеть
Serial.print(5);
numupt= numupt+1;
Serial.println(timeStatus());
}
Стал обновлять время ею раз в 5 минут, пробовал и раз в час, результат тот же. Циферки там в сериал выводятся потому что вчера еще контроллер ребутился как то странно при обновлении времени - хотел увидеть в каком месте обрывается программа - а он ребутиться перестал ))) . Если раскоментированы "setTime" или "adjustTime" то результат в сериале абсолютно тот же.
Раз в секунду в сериал вывожу вот такой колхоз:
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Serial.println("Секунд: " + String(nowtime) + " ; Ошибка: " + String(DiffTime) + "; Обновление: " + String(numupt) + "; UppTick: " + String(UpdateTick));
Serial.println("...");
В результате в сериале даже при раскоментированом "setTime" и даже если обновляюсь через час - когда отставание видно уже на глаз, вижу вот такое (после "///" - мои коменты):
...
уже четвертый день не могу время победить.
Люди столетиями и тысячелетиями пытались - никому ещё не удалось.
---------
Хотите нормальной помощи, давайте полнофункциональный скетч. Как можно короче, но чтобы работал и показывал проблему.
Скетч весь дать не жалко, но он большой и страшный - там время показывается на адресуемых светодиодах, вывод на экран, вывод в сериал, обновление времени и это все в виде кучи моих попыток сделать все разными способами. Давать ТАКОЙ скетч, я счел неуважением к сообществу, а как под спойлер его сунуть не разобрался. Но одну идею я из вашей реплики возьму - нужно мне проблемный код вынести в отдельный скетч, и посмотреть: может я проблемму не там вообще ищу.
А уважаемое сообщество я все же спрошу совета: как мне програмно высчитать погрешность хода часов, и как эту погрешность скоректировать. Ато мои потуги (как первом посте) ни какого видимого эффекта не производят.
З.Ы. Вот и спойлер "нашел" . Код под спойлером. Но это мусорка, несущая в себе все следы моих экспериментов.
#include <WiFi.h> #include "time.h" #include "SSD1306.h" #include <TimeLib.h> #include "FastLED.h" #define DATA_PIN 27 #define LED_TYPE WS2812B #define COLOR_ORDER GRB #define NUM_LEDS 60 #define BRIGHTNESS 50 CRGB leds[NUM_LEDS]; int mPause = 500; int cT; int ii =0; int oldsecond; unsigned long kk =0; SSD1306 display(0x3c, 4, 15); const char* ssid = "CiscoH5497"; const char* password = "11111111"; const char* ntpServer = "ntp2.time.in.ua"; int offsmul = 3; long gmtOffset_sec = 3600*offsmul; const int daylightOffset_sec =0;// 7200; time_t nowtime; unsigned long oldTime1; unsigned long newTime1; long DiffTime; int numupt = 0; String currenttime; unsigned long UpdateTick = 0; const unsigned long UpdateInterval = 120; // 3600*1; struct tm timeinfo; void printLocalTime() { if(!getLocalTime(&timeinfo)){ Serial.println("Failed to obtain time"); // return; } nowtime = time(nullptr); Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); Serial.println("Секунд: " + String(nowtime) + " ; Ошибка: " + String(DiffTime) + "; Обновление: " + String(numupt) + "; UppTick: " + String(UpdateTick)); Serial.println("..."); // Serial.println(asctime(&timeinfo)); // Serial.println(String(hour(nowtime))+":"+String(minute(nowtime))+":"+String(second(nowtime))); // Serial.println(String(timeinfo.tm_hour)+":"+String(minute(nowtime))+":"+String(second(nowtime))); // Serial.println(UpdateTick); display.clear(); display.setFont(ArialMT_Plain_16); display.drawString(0, 5,String(timeinfo.tm_hour)+":"+String(timeinfo.tm_min)+":"+String(timeinfo.tm_sec) +" --"+String(numupt)+"/"+String(DiffTime)); display.setFont(ArialMT_Plain_24); if (timeinfo.tm_mon<9) { display.drawString(0, 30,String(timeinfo.tm_mday)+"/"+"0"+String(1+timeinfo.tm_mon)+"/"+String(1900+timeinfo.tm_year)); } else { display.drawString(0, 30,String(timeinfo.tm_mday)+"/"+String(1+timeinfo.tm_mon)+"/"+String(1900+timeinfo.tm_year)); } display.setFont(ArialMT_Plain_16); display.display(); } void ShowLocalTime() { // int secondsnow; // int minitnow; int hournow; int ht; int scolor=8; ht=timeinfo.tm_hour; if (ht > 12) { ht= ht-12; } hournow = (ht*60+timeinfo.tm_min)/12; if (hournow > 59) {hournow = hournow - 60;}; // minitnow = timeinfo.tm_min; // secondsnow = timeinfo.tm_sec; for (int jj=0; jj<NUM_LEDS; jj++) { leds[jj].setRGB( 0, 0, 0); } /* leds[0].setRGB( scolor, 0, 0); // подсветка leds[5].setRGB( scolor, 0, 0); leds[10].setRGB( scolor, 0, 0); leds[15].setRGB( scolor, 0, 0); leds[20].setRGB( scolor, 0, 0); leds[25].setRGB( scolor, 0, 0); leds[30].setRGB( scolor, 0, 0); leds[35].setRGB( scolor, 0, 0); leds[40].setRGB( scolor, 0, 0); leds[45].setRGB( scolor, 0, 0); leds[50].setRGB( scolor, 0, 0); leds[55].setRGB( scolor, 0, 0); */ leds[hournow].setRGB( 0, 120, 0); if (hournow == 59){leds[0].setRGB( 0, 10, 0);} else { leds[hournow+1].setRGB( 0, 10, 0); } if (hournow == 0){leds[59].setRGB( 0, 10, 0);} else { leds[hournow-1].setRGB( 0, 10, 0); } leds[timeinfo.tm_min].setRGB( 0, 0, 120); leds[timeinfo.tm_sec].setRGB( 120, 0, 0); FastLED.show(); } void UpdateTime() { //connect to WiFi display.clear(); display.drawString(0, 0, "Connecting"); display.drawString(0, 20, ssid); display.display(); Serial.printf("Connecting to %s ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" CONNECTED"); display.drawString(0, 40, " CONNECTED"); display.display(); oldTime1= time(nullptr); //init and get the time configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); getLocalTime(&timeinfo); newTime1= time(nullptr); DiffTime= newTime1 - oldTime1; numupt= numupt+1; // getLocalTime(&timeinfo); // printLocalTime(); // printWifiStatus(); //disconnect WiFi as it's no longer needed // WiFi.disconnect(true); // WiFi.mode(WIFI_OFF); } void UpdateTime1() { setTime(1500000000); //adjustTime(100000); getLocalTime(&timeinfo); Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); oldTime1= time(nullptr); Serial.print(1); //init and get the time configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); Serial.print(2); getLocalTime(&timeinfo); Serial.print(3); newTime1= time(nullptr); Serial.print(4); DiffTime= newTime1 - oldTime1; Serial.print(5); numupt= numupt+1; Serial.println(timeStatus()); } void setup() { delay(3000); // initial delay of a few seconds is recommended FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // initializes LED strip FastLED.setBrightness(BRIGHTNESS);// global brightness cT=millis(); pinMode(16,OUTPUT); digitalWrite(16, LOW); // set GPIO16 low to reset OLED delay(50); digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high display.init(); display.flipScreenVertically(); display.setFont(ArialMT_Plain_16); display.clear(); Serial.begin(115200); nowtime = time(nullptr); Serial.println(nowtime); UpdateTime(); } void loop() { getLocalTime(&timeinfo); if (timeinfo.tm_sec != oldsecond) { kk++; Serial.print(kk); Serial.print(" "); Serial.print(String(timeinfo.tm_sec)); Serial.println(" "); oldsecond = timeinfo.tm_sec; printLocalTime(); // to display ShowLocalTime(); UpdateTick += 1; if (UpdateTick > UpdateInterval) { UpdateTime1(); UpdateTick = 0; } } }А непробывали тупо заменить кварц? Многим помогало. И коррекцию не надо дописывать. :-)
У меня двое часов, собраны на на DS3231(одни на мтрицах, другие в метеостнции). За год я не заметил, что бы время начало отставать или спешить хоть на секунду.