estrarre l'ora

Buongiorno a tutti,
ho trovato questo codice che visualizza correttamente l'ora legale;

#include <WiFi.h>
#include "time.h"
const char* ssid = "xxxxxx";
const char* password = "xxxxxx";
const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;
void printLocalTime()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
void setup()
{
  Serial.begin(115200);

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}

void loop()
{
  printLocalTime();
  if ((&timeinfo, %M) == 10) Serial.println("adesso"); //  qui non riesco ad estrapolare i minuti, come posso fare ?
  delay(1000);
}

ma non riesco a visualizzare/estrapolare i valori di timeinfo dove l'ho indicato nel loop, potete aiutarmi ?
grazie

Per come è scritto, può scrivere solo "adesso"...

E infatti per questo ho chiesto aiuto

edit- scusa ma ci sto ripensando come i cornuti (come sai si dice a Roma, e non solo credo), ma seriamente hai risposto ad un post di aiuto dicendo che il codice che ho postato (con il commento che quella riga è sbagliata ) non funziona ?

ATTILA666999:
non riesco a visualizzare/estrapolare i valori di timeinfo dove l'ho indicato nel loop, potete aiutarmi ?

Scusa, ma timeinfo è una struct, per sapere quali sono gli elementi ti basta vedere nel time.h ossia:

struct tm
{
  int	tm_sec;
  int	tm_min;
  int	tm_hour;
  int	tm_mday;
  int	tm_mon;
  int	tm_year;
  int	tm_wday;
  int	tm_yday;
  int	tm_isdst;
#ifdef __TM_GMTOFF
  long	__TM_GMTOFF;
#endif
#ifdef __TM_ZONE
  const char *__TM_ZONE;
#endif
};

Quindi intanto devi rendere globale la timeinfo (la definizione "struct timeinfo tm;" va messa fuori dalla funzione), quindi puoi fare ad esempio:

...
  printLocalTime();
  if (timeinfo.tm_min == 10) 
    Serial.println("adesso");
  delay(1000);
}

Io invece vorrei sapere cosa ottieni da questa riga: "Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");" perché NON mi sembra una sintassi utilizzabile ... ::slight_smile:

La stai mia confondendo con la printf() ? ? ?

Guglielmo

@docdoc,
Grande (come al solito dopotutto :slight_smile: )
Grazie e karma per te

@gpb01
Non capisco, comunque stampa a schermo questo: "Wednesday, April 01 2020 13:47:00"

Edit. anche staccando il wifi l'orario resta aggiornato, quindi lo memorizza internamente ma sapete se e ogni quanto si aggiorna ?

ATTILA666999:
@gpb01
Non capisco, comunque stampa a schermo questo: "Wednesday, April 01 2020 13:47:00"

... strano, se funziona è una novità introdotta non so quando ... ::slight_smile: ... ma sei su Arduino o su ESP ? ? ?

Guglielmo

Scusa Guglielmo, sono su esp32, avrei dovuto dirlo prima :confused:

ATTILA666999:
Scusa Guglielmo, sono su esp32, avrei dovuto dirlo prima :confused:

... ahhhh ... ecco, perché quella sintassi NON è implementata sul "core" ufficiale Arduino, quindi, se non usi ESP, dimenticala.

Guglielmo

ATTILA666999:
Edit. anche staccando il wifi l'orario resta aggiornato, quindi lo memorizza internamente ma sapete se e ogni quanto si aggiorna ?

sapete qualcosa su questa domanda ?

Dal codice che hai postato non mi pare possa aggiornarsi se non spegnendo e riaccendendo.
L'update dell'ora via ntp è solo nel setup. Dovresti metterlo nel loop() e farlo eseguire solo ogni tot tempo (conti un millis che scatti ogni 3600 sec (1 ora) )

ATTILA666999:
Edit. anche staccando il wifi l'orario resta aggiornato, quindi lo memorizza internamente ma sapete se e ogni quanto si aggiorna ?

Non si aggiorna, se non lo aggiorni tu. Devi usare un RTC (Real Time Clock) esterno tipo QUESTO, quindi con ntp (o alla partenza o periodicamente, diciamo anche una volta al giorno al massimo basta) sincronizzi una volta quello, poi lo usi per impostare l'ora dell'RTC, e resta anche dopo spento (gli RTC hanno anche una batteria tampone, quelle a bottone tipo CR3032).

@nid69ita
ok questo codice dovrebbe effettuare l'aggiornamento ogni ora;

#define Aggiornamento 3600000
long start_time;


start_time = millis();
if (millis() - start_time) >= Aggiornamento)
{
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  start_time = millis();
}

@docdoc,
invece qui ho un po di problemi a capire come passare il valore (data/ora) all'RTC
praticamente questa linea;

RTC.adjust(DateTime(__DATE__, __TIME__));

aggiorna l' RTC ma come devo formattare/passargli il valore generato dalla lettura dell' NTP in base al codice nel primo post ??

La DateTime() esiste anche in versione dove gli passi i singoli elementi
RTC.adjust( DateTime(_year, _month, _day, _hour, _min, _sec) );

ci sto provando da stamane (purtroppo, visto il tempo libero che ho ha disposizione)ma non riesco a passargli i singoli elementi, (non allego tutte le prove che ho fatto per non farti ridere) ma credo mi manca qualche base per capire/integrare quel link che mi hai proposto :frowning:

Non posti tutto il codice, quindi posso solo darti delle imbeccate.

timeinfo dovrebbe essere per te la struttura che contiene i "pezzi" della data/ora
timeinfo.tm_sec contiene i secondi, a te le altre sostituzioni

RTC.adjust( DateTime(_year, _month, _day, _hour, _min, timeinfo.tm_sec) );

ATTILA666999:
ok questo codice dovrebbe effettuare l'aggiornamento ogni ora;

Ma non c'è bisogno, gli RTC sono abbastanza precisi per cui anche aggiornarla una volta al giorno è fin troppo, basterebbe una volta a settimana o anche meno.

Se lo usi anche/soprattutto per adattarti all'ora solare/legale puoi fargli fare la sincronizzazione ogni giorno diciamo alle 3:05 di notte (visto che l'ora legale inizia e termina alle 2:00 che diventano le 3:00 e alle 3:00 che diventano le 2:00).

Alla fine ci sono riuscito e condivido il risultato;

#include <NTPClient.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <RTClib.h>

const char *ssid     = "xxxx";
const char *password = "xxxx";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 7200;
const int   daylightOffset_sec = 3600;
int giorno;
DateTime now;
int x = 0;
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer, gmtOffset_sec, daylightOffset_sec);
RTC_DS3231 RTC;

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  Serial.print("Connesso");
  timeClient.begin();
  RTC.begin();

}

void loop() {
  now = RTC.now();
  x = x + 1;
  Serial.println(x);
  if (x == 10) RTC_Update(); // aggiorna dopo 10 interazioni
  stampa_rtc();
  delay(1000);
  if (now.second() == 10) Serial.print("sono 10 secondi");
  Serial.println("-");
  Serial.println(giorno);
  Serial.println("-");
}

void stampa_rtc() {
  //legge del modulo RTC
  now = RTC.now();
  Serial.print("Tempo RTC = ");
  Serial.print(now.hour());
  Serial.write(':');
  Serial.print(now.minute());
  Serial.write(':');
  Serial.print(now.second());
  Serial.println();

  Serial.print("Data RTC = ");
  Serial.print(now.day());
  Serial.write('/');
  Serial.print(now.month());
  Serial.write('/');
  Serial.print(now.year());
  Serial.println();
}

void RTC_Update() {
  time_t rawtime;
  struct tm * ti;
  timeClient.update();
  rawtime = timeClient.getEpochTime();
  ti = localtime (&rawtime);
  int _year = ti->tm_year + 1900;
  int _month = ti->tm_mon + 1;
  int _day = ti->tm_mday;
  int _hour = ti->tm_hour;
  int _min = ti->tm_min;
  int _sec = ti->tm_sec;
  RTC.adjust(DateTime(_year, _month, _day, _hour, _min, _sec));
  now = RTC.now();
  giorno = now.dayOfTheWeek();
  x = 0;
}

questo codice prende l'orario da internet e lo inserisce nell' RTC (devo rifinire la parte di aggiornamento usando mills() invece di un ciclo) comunque il test è andato a buon fine, ovviamente accetto critiche/consigli.

docdoc:
basterebbe una volta a settimana o anche meno.

si hai ragione infatti pensavo di aggiornarlo ogni settimana utilizzando now.dayOfTheWeek invece di usare mills()

@nid69ita
grazie per la disponibilità :slight_smile:

Purtroppo per l'ora legale devo lavorare sul parametro gmtOffset_sec = 7200; devo inserire qualche if che cambi il valore in base al periodo.

ATTILA666999:
Purtroppo per l'ora legale devo lavorare sul parametro ....

.... se fai una ricerca qui sul forum, più volte è stata pubblicata una funzione che, data la data, ti indica se sei nel periodo dell'ora legale o meno :slight_smile:

Guglielmo