Timestamp dopo deepsleep

ciao,

brevemente:

  1. leggo il time da ntp server.
void XGetTime() {
  initWiFi();
  configTime(3600, 3600, ntpServer);
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Could not obtain time info");
    XTimeOK = false;
    return;
  }
  else {
    Serial.println("GOT TIME -----------");
    Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
    XTimeOK = true;
  }
  1. entro in deepsleep
  2. ogni ora mi risveglio, salvo in memoria rtc i valori di un sensore, assieme al timestamp della rilevazione, SENZA riallinearmi con ntp per risparmiare batteria e non invocare il wifi e rientro in deepsleep.
  3. dopo TOT ore, esco dal deepsleep, mi connetto ad DB e scarico i valori letti nelle ore precedenti.

PROBLEMA: Ottengo sempre lo stesso timestamp iniziale, per tutte le rilevazioni.
Pensavo di conservare anche timeinfo in rtc e cosi' ho fatto, ma come l'aggiorno senza tornare a collegarmi all'NTP?

grazie

Ma se hai un RTC ... dopo il primo aggiornamento e settaggio ... perchè non usi il RTC per avere il timestamp corretto? ... us RTC basato su DS3231 costa nulla ed offre un'eccellente precisione.

Guglielmo

sto usando un wemos lolin32 lite . Niente circuiteria esterna. Con la progettazione elettronica sono praticamente a zero. Per me un 'semplice' voltage divider comincia ad essere qualcosa da 'studiare' bene....
Mi chiedevo se non ci fosse il modo di ripristinare su &timeinfo il valore corrente (anche se impreciso) di uno dei timer interni, anche dopo il deep sleep.
Poi magari, quando mi collego al DB, colgo l'occasione di aggiornare il timer, ma lo farei ogni 6 ore...

Ah, ok ... quindi devi usare il RTC interno del ESP32, che continua a funziinare anche in alcune modalità di deep-sleep (occhio, NON in tutte, alcune lo fermano ... devi verificare esattamente), impostare l'ora all'inizio e poi il RTC interno andrà avanti da solo ... ovviamente la precisione è data dalla sorgente di clock scelta che, a sua volta; è funzione del deep-sleep che usi. :roll_eyes:

QUESTE informazioni di Espressif potrebbero esserti utili ...

Guglielmo

grazie do un'occhiata :slight_smile:

rieccomi.....

c'e' una cosa che mi sta facendo ammattire da 2 giorni (e 2 notti)....
Brevemente:
Si tratta di riportare su un vettore, la struttura di temp che sara' usata piu' in la', (dopo il deep sleep) per redigere una email con 6 righe....

imposto :

`typedef struct
{
  int SoilMostx100;
  char Hod[3];
  char Mod[3];
  char Dom[3];
  char Moy[3];
  char Year[5];
} record_type;

RTC_DATA_ATTR int XCiclo = 0;
RTC_DATA_ATTR record_type XRecord[5];

poi, dal loop, chiamo questa:

void ReadSensor() {
  soilMoistureValue = analogRead(33);
  soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);
  if (soilmoisturepercent >= 100) {
    soilmoisturepercent = 100;
  } else if (soilmoisturepercent <= 0) {
    soilmoisturepercent = 0;
  }
  Serial.println("ESTRAZIONE");
  Serial.print(XCiclo);
  XRecord[XCiclo].SoilMostx100 = soilmoisturepercent;
  Serial.print(XCiclo);
  strftime(XRecord[XCiclo].Hod, 3, "%H", &timeinfo);
  Serial.print(XCiclo);
  strftime(XRecord[XCiclo].Mod, 3, "%M", &timeinfo);
  Serial.print(XCiclo);
  strftime(XRecord[XCiclo].Dom, 3, "%d", &timeinfo);
  Serial.print(XCiclo);
  strftime(XRecord[XCiclo].Moy, 3, "%m", &timeinfo);
  Serial.print(XCiclo);
  strftime(XRecord[XCiclo].Year, 5, "%Y", &timeinfo);
  Serial.println("XCiclo READSENSOR CICLO ");
  Serial.print(XCiclo);
}

ovviamente timeinfo e' gia' valorizzata col timestamp da ntp.
In questo modo , speravo di su XRecord, tutti i campi per ricomporre in stampa la data al momento dell'emissione della email.

Perche' cosi' tanti print? per capire come mai, XCiclo , che va da 0 a 5 , quando arriva a 5 e assegno a XRecord il primo valore,(soilmoisturepercent) esce dall'operazione, con il valore 100 !
ma solo quando arrivo a 5.
Quindi la riga seguente, quella con strftime, mi assegna la riga 100..... e non la 5.
Mi pare fantascienza dell'assurdo. Non PUO' essere, eppure il serial monitor, quando il programma gira, me lo mostra chiaramente.....

Potete illuminarmi per favore? Non ne vengo piu' fuori, ho provato di tutto.... grazie

In quello spezzone di codice XCiclo non viene mai modificata... difficile fare ipotesi.
Posta tutto il codice.

Porca miseria ci cascano tutti, però due giorni per questa stupidaggine. Se la vista non mi inganna quello è un 5, 5 elementi numerati a partire da 0, 1, 2, 3, 4 stop sono 5 elementi.

Se gli XCiclo va da 0 a 5 allora al posto del [5] ci devi mettere [6].
Come del resto avevi fatto nell'altro post.
Ciao.

Penso proprio che hai ragione! Cavolo 5 indica il numero degli elementi, non e' un indice!!!!
Ma e' cosi' anche in altri linguaggi? in fondo sto dichiarando un array di strutture, si parte da zero.
Boh forse ormai dovrei comprarmi un set da bocciofilo e fare qualcos'altro nel tempo libero.....

provo subito!

grazie a Fratt e a Maurotec

P.S. : Ho provato. 'ovviamente' funziona! Vado a rileggermi per bene la dichiarazione di strutture , array e stringhe.....
2 giorni che ero in 'guru meditation'.... :wink: grazie 1000

Il numero tra quadre che metti quando DICHIARI un qualche cosa (array, matrice, ecc.) indica il numero totale degli elementi, quindi N indica N elementi.

Il numero tra quadre che metti quando USI un qualche cosa (array, matrice, ecc.) indica il numero dell'elemento che si conta a partire dall'elemento zero, quindi 0, 1, 2, 3, ... N-1.

Basta ricordasi questo :wink:

Guglielmo

grazie Gugliemo. Vediamo se trovo ancora qualche neurone buono per ricordare la cosa :slight_smile:

Quando accadono cose strane come ad esempio la scritta: Lancia Razzi si trasforma in ... :smile:come descritto qui, la colpa è sempre degli indici, dei terminatori di C string ed in generale di mezzo ci sono sempre puntatori e array e la responsabilità è tutta del programmatore. In c/c++ non ci sono infrastrutture software tra la richiesta di scrittura in ram e l'effettiva scrittura.
Specie in embedded, puoi trasformare un numero in indirizzo di memoria e scriverci direttamente, come descritto qui.

Mi dispiace dirlo ma il C/C++ per essere messo a frutto richiede competenze ad ampio spettro legate principalmente alla piattaforma e molto esercizio, ma anche in questo caso prima o poi ti frega.

Se non sbaglio sei su ESP e puoi usare le librerie C++ quasi standard, come gli algoritmi vector, string ecc molto più sicuri da usare a cuor leggero.

Ciao.

Si e no, in altri linguaggi ma anche in C++ su piattaforme che possono permetterselo ci sono i contenitori di alto livello che fanno capo alla libreria standard C++, brevemente STL C++, che sta per Standard Templete Library.

Si e no, vuole dire anche che lo zero è un numero, ma siamo abituati a contare a partire da 1, diversamente il primo giorno dell'anno nuovo sarebbe il giorno 0, poi 1, 2 ecc. :grinning:

https://cplusplus.com/reference/stl/

si, vengo dai vecchi mainframe IBM (RPG, PL1,Cobolo) qualche esperienza di assembler (su commodore !) clipper , etc. Devo dire che avevo preso sottogamba questi 'aggeggini' , ma vedo che finalmente avro' l'occasione di imparare un po' di sano C per come si deve....
Mi sono perso un po' anche con le varie librerie. Su internet c'e' di tutto nei vari progetti e sto imparando a valutarne i pro e i contro di quelle che sto usando.
C'e' un mare da sapere e' stimolantissimo :slight_smile: grazie

T'ho già dato QUESTO link? E' liberamente scaricabile :wink:

Guglielmo

grazie Guglielmo. no non lo avevo ancora.

Leggo che ESPR32 ha un timer interno che non risente del deep sleep, finche ovviamente non si toglie l'alimentazione...
Benche' sia influenzato dalla temperatura e dai cicli del processore, mi basterebbe andare a sincronizzarlo ogni tanto....
Ho visto le varie librerie , parliamo della classica temp.h adesso.
Una volta aver letto il tempo collegandomi con un ntp server, il conto dei millisecondi (opportunamente trasformato in formato 'umano') , sopravvive ai vari deep sleep? A quanto leggo sembrerebbe di si, ma da prove sul campo , usando getlocaltime() , la data si resetta ad ogni risveglio.... Sbaglio qualcosa ovviamente, oppure...non ho capito....
In giro, non ho visto uno straccio di sketch che faccia il get del time da ntp, poi vada in deep sleep e poi utilizzi l'orario senza ricollegarsi.....

Ho cancellato il mio post qui sopra ... le informazioni sono effettivamente piuttosto frammentarie.

Il clock source per il RTC dovrebbe essere di base l'oscillatore a 150 KHz ... il guaio è che una cosa fissata al momento in cui sono compilati i vari moduli del "core" Arduino e le varie librerie ESP e quindi difficile da verificare, però ... non vedo perché dovrebbero aver cambiato quello che dovrebbe essere il default.

Dato quindi per scontato che tutto sia configurato di default ... il RTC dovrebbe sempre fornire l'ora recuperabile con le chiamate indicate QUI nella loro documentazione :roll_eyes:

Guglielmo

grazie. ci riprovo stasera appena torno a casa.... ti aggiorno, perche' in giro su internet, non l'ho trovato chiarito in linguaggio 'umano' per neofiti come me :slight_smile: , neanche in inglese. Spero di chiarirlo definitivamente anche a vantaggio di chi si trovasse nella stessa situazione.
Sarebbe un bel vantaggio poter disporre del timer rtc anche dopo il deep sleep, cosi' come riportato da espressif. (anche se impreciso e bisognoso di riallineamenti ogni tanto)

Scusa, hai visto QUESTA? Sembrerebbe fare al caso tuo ... :roll_eyes:

Guglielmo