Hi, I'm buiding a project where I need to log some data in NVR for laters uses. As is suggested I'm using Preferences instead of EEPROM library but I'm stuck with how to make it right with the preferences library.
This is my project:
Once a day, the device will make a measure of alkalinity. And it will record two pair of values for each measure: Timestamp in unix format and the Alkalinity value.
But, it will keep just the last 255 records, in order to keep the memory usage under control.
There is need to store an index number too, Because I will use a circular array in NVR in order to minimize the read/write cycles. The index number will be cycling between 0 and 254. This index is important to let the device know what log record have to be writed or updated.
In order to make a prototype, I made a sketch to test how the NVR storage work. But It doesn't work properly. I can see just the record for the measure is stored properly, but the record index isn't. Then each new record is stored in the same position on the array.
According to how I understand preferences work, I need to use two namespaces, one for the array of data records and another to keep the index number.
For some unknown reason (for me), the index record in not being stored. ¿What I'm doing wrong?
This is my test sketch:
#include <Preferences.h>
#include <SimpleTimer.h>
#include "TimeLib.h"
tmElements_t te; //Time elements structure
time_t unixTime; // a time stamp
unsigned int indice;
Preferences registro;
SimpleTimer timer;
typedef struct { // data structure for each record
unsigned long unix = 0;
float kH = 0;
} Log_kh;
Log_kh Log_kh_[255]; //Size of the record array in memory
void bitacora(){
registro.begin("Settings", false); //opens the namespace "Settings" to store a new record in the next position according the indice
Serial.println("Inicia Bitacora " + String(indice)); //prints the actual indice *** it shows allways 0!!
//Now it will create a new record with some variable data just to test it is actually stored in NVR
te.Second = indice*60/255;
te.Hour = 18; //11 pm
te.Minute = random(60);
te.Day = 7 ;
te.Month = 2;
te.Year = 2023 - 1970; //Y2K, in seconds = 946684800UL
unixTime = makeTime(te);
Log_kh_[indice].unix = unixTime;
Log_kh_[indice].kH = 7 + random(2);
registro.putBytes("Log_kh", &Log_kh_, sizeof(Log_kh_)); //Stores the data in NVR
registro.getBytes("Log_kh", &Log_kh_, sizeof(Log_kh_)); // get the data to check
//It will print the data it got from memory.
Serial.print(Log_kh_[indice].unix);
printf(" Fecha: %4d-%02d-%02d %02d:%02d:%02d\n ", year(Log_kh_[indice].unix), month(Log_kh_[indice].unix), day(Log_kh_[indice].unix), hour(Log_kh_[indice].unix), minute(Log_kh_[indice].unix), second(Log_kh_[indice].unix));
Serial.println(Log_kh_[indice].kH);
registro.end(); //close the namespace "Settings"
//now the indice used is printed, incremented (with condition to cycle between 0 and 254), and printed again
Serial.println("registra indice " + String(indice));
indice = indice + 1;
Serial.println("Siguiente indice "+ String(indice));
if (indice = 255) indice = 0;
registro.begin("puntero", false); //open the name space "puntero" to store the new indice
registro.putUInt("index", indice);// stores the new indice in memory
Serial.println("registro guardado: " +String(registro.getUInt("index", 0))); //prints the value actually stored*** it allways shows 0!!
registro.end(); // close the namespace "puntero"
}
void setup() {
Serial.begin(115200);
registro.begin("puntero", false); //open namespace "puntero" to recover the last index number stored
indice = registro.getUInt("index", 0);// put the index on indice, if there no first entry, will assume 0
registro.end(); //close the name space "puntero"
Serial.println("Indice after reset: "+String(indice)); //Prints the indice got from memory
registro.begin("Settings", false); //open namespace "Settings" to recover the full array of measure records stored
Serial.print("sizeof(Log_kh_) = "); Serial.println(String(sizeof(Log_kh_)));//prints the size of the record array
registro.end(); //close the namespace "Settings"
// next lines prints the data records from 0 to indice
for (int i = 0 ; i < indice ; i++) {
Serial.print(Log_kh_[i].unix);
printf(" Fecha: %4d-%02d-%02d %02d:%02d:%02d\n ", year(Log_kh_[i].unix), month(Log_kh_[i].unix), day(Log_kh_[i].unix), hour(Log_kh_[i].unix), minute(Log_kh_[i].unix), second(Log_kh_[i].unix));
Serial.println(Log_kh_[i].kH);
}
timer.setInterval(10000, bitacora); //bitacora will run every 10 seconds. This function will have to create a new data record in memory.
}
void loop() {
timer.run();
}