Breixo
October 22, 2023, 4:03pm
1
Hi to all. I've this sketch, surely simple for the vast majority of you but it doesn't work for me.
// Storing struct variables in EEPROM
// Sequential read / write of variables.
#include <EEPROM.h>
#define BUTTON_TEST 5
#define EEADDR 0 // Start location to write EEPROM data.
// Put variables into structure.
struct Settings_s {
char SSID[21]; // Always number of characters + 1 (null)
char PASS[21];
float BlrPWR;
float maxSuppTemp;
float minOutdTemp;
float SetPoint;
float SetBack;
};
Settings_s Settings = { "SSID012345678", "01234567890123456789", +20000.00, +60.00, -5.00, +21.00, +19.00 };
void show_vars(Settings_s *p) {
Serial.print("SSID :"); Serial.println(p->SSID[21]);
Serial.print("PASS :"); Serial.println(p->PASS[21]);
Serial.print("BlrPWR :"); Serial.println(p->BlrPWR);
Serial.print("maxSuppTemp: "); Serial.println(p->maxSuppTemp);
Serial.print("minOutdTemp: "); Serial.println(p->minOutdTemp);
Serial.print("SetPoint :"); Serial.println(p->SetPoint);
Serial.print("SetBack :"); Serial.println(p->SetBack);
}
void setup() {
pinMode(BUTTON_TEST, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(115200);
Serial.println("EEPROM struct read and write.");
// Read EEPROM
EEPROM.get(EEADDR, Settings);
show_vars(&Settings);
}
void loop() {
static unsigned long timeWas, timeNow;
int a = 0;
Settings.SSID[21] = a++;
Settings.PASS[21] = a++;
Settings.BlrPWR = a++;
Settings.maxSuppTemp = a++;
Settings.minOutdTemp = a++;
Settings.SetPoint = a++;
Settings.SetBack = a++;
Serial.println("Press button to write struct to EEPROM");
if (digitalRead(BUTTON_TEST) == 0) {
digitalWrite(LED_BUILTIN, HIGH);
timeWas = micros();
EEPROM.put(EEADDR, Settings);
timeNow = micros();
Serial.println("EEPROM Written");
show_vars(&Settings);
Serial.print("EEPROM Write time (us) :"); Serial.println(timeNow - timeWas);
Serial.print("EEPROM Write time per byte (us) :"); Serial.println((timeNow - timeWas) / (sizeof(Settings)));
delay(500);
digitalWrite(LED_BUILTIN, LOW);
}
delay(500);
}
The serial monitor presents these data:
EEPROM struct read and write.
SSID :ÿ
PASS :ÿ
BlrPWR :nan
maxSuppTemp: nan
minOutdTemp: nan
SetPoint :nan
SetBack :nan
Press button to write struct to EEPROM
EEPROM Written
SSID :
PASS :
BlrPWR :2.00
maxSuppTemp: 3.00
minOutdTemp: 4.00
SetPoint :5.00
SetBack :6.00
EEPROM Write time (us) :64152
EEPROM Write time per byte (us) :1034
I ask for your suggestions, thanks and regards,
Breixo:
Settings.PASS[21] = a++;
What do you get when put an integer into the last slot of an array of characters?
Try setting the components of your structure to sensible values.
Also and BTW, since you declare
int a = 0;
a will be recreated and set to zero every time you loop
Also, you read eeprom into the struct variable right away in setup (). Call show _vars () first. At least then you would see your initial values.
a7
char SSID[21];
char PASS[21];
Settings.SSID[21] = a++;
Settings.PASS[21] = a++;
The elements of the array are zero indexed, and the index numbers for an array of size 21 are 0-20. You are writing out of bounds.
1 Like
There is no reason to give an index to a null-terminated char array, especially when you are indexing past the end of the array:
void show_vars(Settings_s *p) {
Serial.print("SSID :"); Serial.println(p->SSID);
Serial.print("PASS :"); Serial.println(p->PASS);
You need to convert the integer to text when storing to a char array.
int a = 0;
itoa(a++, Settings.SSID, DEC);
itoa(a++, Settings.PASS, DEC);
< edit >
Getting an accurate time measurement for put() is going to be difficult. The EEPROM is read first, compared with the value being written, and only written to EEPROM if the value differs (this is done for each byte of the struct). To get the maximum write time, you will need to read the data from EEPROM, then alter the value of every byte, before doing the write. If you just read the data from EEPROM, and immediately write back to EEPROM with no changes, then no actual writes will be done.
Breixo
October 22, 2023, 4:56pm
5
Thanks to the three of you, alto777 , cattledog and david_2018 , I understand that I have at least 3 errors but I have not been able to understand any of them.
Could you give me the line or lines with the corrected code? Please excuse my ignorance.
Once again, thank you for your time and attention.
Yes, good eye.
@Breixo , first, move
int a = 0;
to outside the loop, or change it where it is to
static int a;
this will give you an a that will remember and grow as you increment it, not start over every loop.
Next, using @david_2018 's suggestion for the character arrays, write
static int a = 0; // or make a global
itoa(a++, Settings.SSID, DEC);
itoa(a++, Settings.PASS, DEC);
Settings.BlrPWR = a++;
Settings.maxSuppTemp = a++;
Settings.minOutdTemp = a++;
Settings.SetPoint = a++;
Settings.SetBack = a++;
HTH
forum tip : we get notified if you proceed out user names with an at sign '@', @alto777 <- like that, so you can scare someone up who may have turned his attention to the grill and lost interest in other things…
a7
Single character variable names are bad form.
(Searching for 'a' will highlight every instance of a in your sketch - not helpful.)
1 Like
Breixo
October 22, 2023, 5:55pm
8
Thanks, @alto777 , something has improved but...
EEPROM struct read and write.
SSID :0 (It should appear: SSID012345678 )
PASS : (It should appear: 01234567890123456789 )
BlrPWR :20000.00
maxSuppTemp: 60.00
minOutdTemp: -5.00
SetPoint :21.00
SetBack :19.00
Press button to write struct to EEPROM
EEPROM Written
SSID :1 (? )
PASS : (? )
BlrPWR :16.00 (? )
maxSuppTemp: 17.00 (? )
minOutdTemp: 18.00 (? )
SetPoint :19.00 (? )
SetBack :20.00 (? )
EEPROM Write time (us) :80144
EEPROM Write time per byte (us) :1292
Breixo:
something has improved
Please post your latest code.
Breixo
October 22, 2023, 6:01pm
10
Here it is (I followed @runaway_pancake 's recommendation to avoid single char as a var).
// Storing struct variables in EEPROM
// Sequential read / write of variables.
#include <EEPROM.h>
#define BUTTON_TEST 5
#define EEADDR 0 // Start location to write EEPROM data.
// Put variables into structure.
struct Settings_s {
char SSID[21]; // Always number of characters + 1 (null)
char PASS[21];
float BlrPWR;
float maxSuppTemp;
float minOutdTemp;
float SetPoint;
float SetBack;
};
Settings_s Settings = { "SSID012345678", "01234567890123456789", +20000.00, +60.00, -5.00, +21.00, +19.00 };
void show_vars(Settings_s *p) {
Serial.print("SSID :"); Serial.println(p->SSID[21]);
Serial.print("PASS :"); Serial.println(p->PASS[21]);
Serial.print("BlrPWR :"); Serial.println(p->BlrPWR);
Serial.print("maxSuppTemp: "); Serial.println(p->maxSuppTemp);
Serial.print("minOutdTemp: "); Serial.println(p->minOutdTemp);
Serial.print("SetPoint :"); Serial.println(p->SetPoint);
Serial.print("SetBack :"); Serial.println(p->SetBack);
}
void setup() {
pinMode(BUTTON_TEST, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(115200);
Serial.println("EEPROM struct read and write.");
// Read EEPROM
show_vars(&Settings);
EEPROM.get(EEADDR, Settings);
//show_vars(&Settings);
}
void loop() {
static unsigned long timeWas, timeNow;
/*int a = 0;
Settings.SSID[21] = a++;
Settings.PASS[21] = a++;
Settings.BlrPWR = a++;
Settings.maxSuppTemp = a++;
Settings.minOutdTemp = a++;
Settings.SetPoint = a++;
Settings.SetBack = a++;
*/
static int eeaddress;
itoa(eeaddress++, Settings.SSID, DEC);
itoa(eeaddress++, Settings.PASS, DEC);
Settings.BlrPWR = eeaddress++;
Settings.maxSuppTemp = eeaddress++;
Settings.minOutdTemp = eeaddress++;
Settings.SetPoint = eeaddress++;
Settings.SetBack = eeaddress++;
Serial.println("Press button to write struct to EEPROM");
if (digitalRead(BUTTON_TEST) == 0) {
digitalWrite(LED_BUILTIN, HIGH);
timeWas = micros();
EEPROM.put(EEADDR, Settings);
timeNow = micros();
Serial.println("EEPROM Written");
show_vars(&Settings);
Serial.print("EEPROM Write time (us) :"); Serial.println(timeNow - timeWas);
Serial.print("EEPROM Write time per byte (us) :"); Serial.println((timeNow - timeWas) / (sizeof(Settings)));
delay(500);
digitalWrite(LED_BUILTIN, LOW);
}
delay(500);
}
You are still incorrectly using an index on the arrays in the show_vars function.
The values you see are going to depend on how many times loop() has executed at the time you press the button
Breixo
October 22, 2023, 6:18pm
13
Thanks, david_2028, I'm sorry but what should the sentence be?
kolaha
October 22, 2023, 6:21pm
14
// Storing struct variables in EEPROM
// Sequential read / write of variables.
#include <EEPROM.h>
#define BUTTON_TEST 5
#define EEADDR 0 // Start location to write EEPROM data.
// Put variables into structure.
struct Settings_s {
char SSID[21]; // Always number of characters + 1 (null)
char PASS[21];
float BlrPWR;
float maxSuppTemp;
float minOutdTemp;
float SetPoint;
float SetBack;
};
Settings_s Settings = { "SSID012345678", "01234567890123456789", +20000.00, +60.00, -5.00, +21.00, +19.00 };
void show_vars(Settings_s *p) {
Serial.print("SSID :"); Serial.println(Settings.SSID);
Serial.print("PASS :"); Serial.println(Settings.PASS);
Serial.print("BlrPWR :"); Serial.println(p->BlrPWR);
Serial.print("maxSuppTemp: "); Serial.println(p->maxSuppTemp);
Serial.print("minOutdTemp: "); Serial.println(p->minOutdTemp);
Serial.print("SetPoint :"); Serial.println(p->SetPoint);
Serial.print("SetBack :"); Serial.println(p->SetBack);
}
void setup() {
pinMode(BUTTON_TEST, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(115200);
Serial.println("EEPROM struct read and write.");
// Read EEPROM
show_vars(&Settings);
//
//show_vars(&Settings);
}
void loop() {
static unsigned long timeWas, timeNow;
static int eeaddress = 0;
Serial.println("Press button to write struct to EEPROM");
digitalWrite(LED_BUILTIN, HIGH);
timeWas = micros();
EEPROM.put(EEADDR, Settings);
timeNow = micros();
Serial.println("EEPROM Written");
Serial.print("EEPROM Write time (us) :"); Serial.println(timeNow - timeWas);
Serial.print("EEPROM Write time per byte (us) :"); Serial.println((timeNow - timeWas) / (sizeof(Settings)));
Serial.print("EEADDR :"); Serial.println(eeaddress);
EEPROM.get(EEADDR, Settings);
show_vars(&Settings);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
eeaddress += sizeof(Settings_s);
delay(5000);
}
alto777
October 22, 2023, 6:33pm
15
Breixo:
static int eeaddress;
That's a better name than a for sure, but a bad name as it is not in any way associate with the eeprom or addresses.
It's just an integer that you change (increment) every time you use it, just so you can see different data getting read and written.
@kolaha makes a half step towards writing and reading successive areas large enough for you struct, viz:
eeaddress += sizeof(Settings_s);
and doesn't increment it otherwise. Left using the defined constant EEADDR, however, are the actual calls to the eeprom library.
a7
1 Like
kolaha
October 22, 2023, 6:37pm
16
yes, that's typical me. better i make it proper.
// Storing struct variables in EEPROM
// Sequential read / write of variables.
#include <EEPROM.h>
#define BUTTON_TEST 5
#define EEADDR 0 // Start location to write EEPROM data.
// Put variables into structure.
struct Settings_s {
char SSID[21]; // Always number of characters + 1 (null)
char PASS[21];
float BlrPWR;
float maxSuppTemp;
float minOutdTemp;
float SetPoint;
float SetBack;
};
Settings_s Settings = { "SSID012345678", "01234567890123456789", +20000.00, +60.00, -5.00, +21.00, +19.00 };
void show_vars(Settings_s *p) {
Serial.print("SSID :"); Serial.println(Settings.SSID);
Serial.print("PASS :"); Serial.println(Settings.PASS);
Serial.print("BlrPWR :"); Serial.println(p->BlrPWR);
Serial.print("maxSuppTemp: "); Serial.println(p->maxSuppTemp);
Serial.print("minOutdTemp: "); Serial.println(p->minOutdTemp);
Serial.print("SetPoint :"); Serial.println(p->SetPoint);
Serial.print("SetBack :"); Serial.println(p->SetBack);
}
void setup() {
pinMode(BUTTON_TEST, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(115200);
Serial.println("EEPROM struct read and write.");
show_vars(&Settings);
}
void loop() {
static unsigned long timeWas, timeNow;
static int eeaddress = EEADDR;
Serial.println("Press button to write struct to EEPROM");
while (digitalRead(BUTTON_TEST)) {
digitalWrite(LED_BUILTIN, HIGH);
timeWas = micros();
EEPROM.put(eeaddress, Settings);
timeNow = micros();
Serial.println("EEPROM Written");
Serial.print("EEPROM Write time (us) :"); Serial.println(timeNow - timeWas);
Serial.print("EEPROM Write time per byte (us) :"); Serial.println((timeNow - timeWas) / (sizeof(Settings)));
Serial.print("EEADDR :"); Serial.println(eeaddress);
EEPROM.get(eeaddress, Settings);
show_vars(&Settings);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
eeaddress += sizeof(Settings_s);
while (!digitalRead(BUTTON_TEST));
}
}
Breixo
October 22, 2023, 6:52pm
17
Many thanks to everyone and, in particular to kolala, the sketch already works!.
alto777
October 22, 2023, 6:57pm
19
You could put in some of those lines that change the struct values, then see them go in and out of eeprom with those changes.
To sorta prove you are writing differently to different addresses in the eeprom.
a7
Breixo
October 22, 2023, 7:15pm
20
I will adapt and debug the sketch, as soon as I have something more serious, I will put the sketch to serve many others. I have seen that there is quite a demand for a solution like the one you have provided me. Thanks @runaway_pancake , @cattledog , @david_2018 , @kolaha and @alto777