Tempo fa ho realizzato un orologio NTP a matrici di LED. Funziona, ma il LED blu dell'ESP8266 lampeggia continuamente e una radio AM, avvicinata, fa "toc-toc-toc" con periodo di un secondo.
Ho letto che i server NTP possono bannare chi legge l'orario continuamente, più spesso di una volta ogni 64 secondi o qualcosa del genere. L'intervallo di lettura dell'NTP dovrebbe essere di default ogni 10 minuti. Ho anche inserito setSyncInterval (600); ma non ho notato differenze.
Avevo usato la libreria time.h. Non riuscendo a trovarla fra quelle presenti con il gestore delle librerie, pur venendo il programma compilato e caricato senza problemi, ho installato la TimeLib.h, che forse è solo la versione nuova della stessa, ma nulla è cambiato.
Qualcuno mi sa dire come stanno esattamente le cose?
Grazie
Gianluca
#include <ESP8266WiFi.h> // URL aggiuntivo per il gestore schede: http://arduino.esp8266.com/stable/package_esp8266com_index.json
#include <SPI.h> // Mi sembra che funzioni anche senza...
#include <Adafruit_GFX.h> // Usato da Max72xxPanel
#include <Max72xxPanel.h> // Installare da zip: https://github.com/markruys/arduino-Max72xxPanel
// #include <time.h>
#include <TimeLib.h>
void scrive_orario()
{
time_t now = time(nullptr); // Facendo now variabile globale, perdeva il fuso orario.
if (now!=t_prec)
{
t_prec=now;
matrix.fillScreen(LOW);
String time = String(ctime(&now));
time.trim();
time.substring(11,19).toCharArray(time_value, 10);
if(time_value[7]!=sec_prec) {t_prec=millis(); digitalWrite(D0, HIGH); sec_prec=time_value[7];/*GP16O|=1;*/} // Porta a livello alto la porta GPIO16 (D0).
// Visualizza lo '0' iniziale prima delle ore 9.00:
matrix.drawChar(P,0, time_value[0], HIGH,LOW,1); //
(...)
}
}
void setup()
{
//ESP.wdtDisable(); // Disabilita il watchdog software.
//hw_wdt_disable(); // Disabilita il watchdog hardware.
pinMode(D0, OUTPUT); // 1Hz.
pinMode(sys_pin,INPUT_PULLUP); // Chiudere a massa durante il loop per leggere sysinfo.
pinMode(D6,INPUT_PULLUP); // Chiudere a massa in qualsiasi momento per capovolgere il display.
// Serial.begin(9600);
setSyncInterval(600); // 600 secondi.
se_capovolto(); // Imposta la disposizione delle matrici di LED leggendo lo stato dell'ampollina al mercurio.
(...)
void loop()
{
if(millis()-t_display>200)
{
t_display=millis();
lum=map(analogRead(0),0,1023,0,15); matrix.setIntensity(lum); // Ogni 200ms legge il potenziometro (1023 con 3,3V).
se_capovolto();
}
scrive_orario();
(...)
Ancora non ho trovato una soluzione. Spesso, accendendo l'orologio, anziché indicare l'ora corrente, parte da 01:00:00 e va avanti. Potrebbe essere perché viene rifiutato da uno dei due server NTP che lo ha messo in blacklist?... No, non è per quello: se lascio uno solo dei due server, qualunque sia, qualche volta inizia con l'ora giusta e qualche altra no!
Allego il codice completo.
@cotestatnt e @steve-cr , ho visto una discussione in proposito in cui intervenivate. Potete aiutarmi?
Non conosco bene la libreria TimeLib.h (e francamente con ESP8266 mi sembra anche abbastanza inutile), ma solitamente l'esp - una volta connesso al WiFi - ci mette qualche secondo per instaurare la connessione con il server e sincronizzare il system time.
Ti parte da 01:00:00 perché aggiunge l'ora del fuso orario italiano come offset, altrimenti partirebbe da 00:00:00
Io mi sono fatto una funzioncina che aspetta la sincronizzazione in modo bloccante con un timeout da inserire nel setup.
Ho fatto un esempio sul solito wokwi, anche se è lentissimo nel simulare l'ESP32 (va al 5-10% della velocità reale!! )
Lo sketch ovviamente funziona anche su ESP8266.
#include <NTPClient.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP); // 2nd parameter: difference in seconds between TIME ZONE 0
etc..
.etc..
Serial.println ("Aggiornamento Ora Esatta da server NPT ");
timeClient.update();
delay (1000);
Hours = (timeClient.getHours());
Minutes = (timeClient.getMinutes());
Serial.print (Hours); Serial.print (":"); Serial.println(Minutes);
Succede anche a me che, quando accendo il Wemos o premo reset, le ore e minuti sono a ZERO.
E il mio sistema e il mio programma sono diversi dal tuo.
Ciò mi conferma che il problema è il collegamento con il server NTP.
Ho messo un semplice delay e penso di aver risolto il problema, ma potrei fare anche due chiamate al timeClientUpdate ().
Nel programma che trovai e ho adottato per il mio orologio veniva dichiarata una variabile time_t now, che è una variabile locale che va a sovrapporsi a quella già definita nella libreria!
Io, non capendo se e dove era installata la time.h, ho installato e usato la timeLib.b, che supporta anche setSyncInterval(600); . Non ho capito se quella libreria è una nuova versione della time.h...
Adesso uso nuovamente time.h, ma non digerisce il confronto
if (adesso<EPOCH_1_1_2019)
Di che tipo è EPOCH? E' una macro? Evidentemente non ce l'ho definita!
adesso l'ho dichiarata time_t... La dichiaro int32_t e la confronto con 3600000 (1000 ore)?
Il calcolo del fuso è già presente, senza usare timezone.h. Come sempre, il programma che presi come base sarà stato un impiastro di chissà quanta roba appiccicata insieme...
Comunque così funziona:
while(adesso<3600000) {adesso = time(nullptr);}
Non fallisce un colpo!
Resta da capire se legge il server ogni secondo e se i server NTP bannano in caso di letture troppo frequenti.