Обновление/коррекция времени

Proshka
Offline
Зарегистрирован: 02.03.2018

Доброго дня (ночи) всем. Помогите кто чем может - что то я уже четвертый день не могу время победить. Кристалл 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" и даже если обновляюсь через час - когда отставание видно уже на глаз, вижу вот такое (после "///" - мои коменты):

  ...

242    32  
Sunday, April 15 2018 22:45:32                                                          ///Время перед обновлением
Секунд: 1523821532 ;    Ошибка: 0;  Обновление: 2; UppTick: 120
...
Sunday, April 15 2018 22:45:32                /// должно быть испорченое функцией "setTime"время
123452                          /// тут "2" в конце говорит что timeStatus()= Время обновлено, но я ему не очень верю
243    33  
Sunday, April 15 2018 22:45:33                 /// Это время после обновления
Секунд: 1523821533 ;    Ошибка: 0;  Обновление: 3; UppTick: 0      /// Ошибка времени тут "0" как же, если я 
                                                                                                      /// вносил погрешность в 100000 секунд
 
Извините за много букв. Воюю я с этими часами давно, но вот за последние 4 дня вообще не продвинулся.
Вопрос мой собственно ЧЯДНТ. Как мне убедиться что время с NTP получено выставилось верно. Как мне посчитать погрешность. И как мне эту погрешность скоректировать.
  Птому что не умея проделать вышесказаное я могу только несколько раз в день на NTP сервер "ходить", и наверное , лучше каждый раз на разный, чтобы не забанили - но это как ломом дверь открывать. вместо ключа...
Буду раз любой помощи. подсказке, идее. Спасибо.
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Proshka пишет:

уже четвертый день не могу время победить. 

Люди столетиями и тысячелетиями пытались - никому ещё не удалось.

---------

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

Proshka
Offline
Зарегистрирован: 02.03.2018

Скетч весь дать не жалко, но он большой и страшный - там время показывается на адресуемых светодиодах, вывод на экран, вывод в сериал, обновление времени и это все в виде кучи моих попыток сделать все разными способами. Давать ТАКОЙ скетч, я счел неуважением к сообществу, а как под спойлер его сунуть не разобрался. Но одну идею я из вашей реплики возьму - нужно мне проблемный код вынести в отдельный скетч, и посмотреть: может я проблемму не там вообще ищу. 

А уважаемое сообщество я все же спрошу совета: как мне програмно высчитать погрешность хода часов, и как эту погрешность скоректировать. Ато мои потуги (как первом посте) ни  какого видимого эффекта не производят.

З.Ы.  Вот и спойлер "нашел" . Код под спойлером. Но это мусорка, несущая в себе все следы моих экспериментов.

#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;
    }    

  }
}

 

Genri5
Offline
Зарегистрирован: 31.05.2016

А непробывали тупо заменить кварц? Многим помогало. И коррекцию не надо дописывать. :-)

У меня двое часов, собраны на на DS3231(одни на мтрицах, другие в метеостнции). За год я не заметил, что бы время начало отставать или спешить хоть на секунду.