Hello,
I have a question about the use of ‘struct’. I came across while learning about how to use EEPROM. Ultimately my goal is to simply store the value of a soil RH probe in EEPROM. I wanted to store an int (which I don’t believe is difficult to do), but after looking into this some more, I am interested in learning how to use EEPROMAnything. I think I generally can see how this is used, but in the example on the Arduino website (Arduino Playground - EEPROMWriteAnything), the following code is used:
struct config_t
{
long alarm;
int mode;
} configuration;
I have a few questions about the use of ‘struct’:
It is only used to store variables of different types, correct?
What is the ‘config_t’ for? I read somewhere that it is optional(?) but if I remove it the code does not compile.
In the example on the Arduino website (see link above), there is a line of code that says:
“if (digitalRead(13) == HIGH)
EEPROM_writeAnything(0, configuration);”
Why does this if statement not need brackets after it?
How would I define ‘configuration’ in the actual code? I assume that in this code, a button is pressed, and this causes new variables to be stored in ‘configuration’. However, I’m not sure how you would do this. Would you just have something like “alarm = XXX”, and “mode = YYY” then when you later write “EEPROM_writeAnything(0, configuration)”, it would write both the alarm and mode values?
config_t is a tag, it is optional if the struct defines real object like the 'configuration' is but if you want do define structure and want to use later and more times you have to have some identification and tag is used for it.
struct config_t aaa;
struct config_t bbb;
The brackets are needed if more command belongs to the 'if' or others (for, while, do while), otherwise only first next command is under if.
Next 1. I think, it is answered in 3.
Next 2. Struct is a bunch of bytes and they are stored one by one as string.
EEPROM_writeAnything is a template and the compiler creates function version according the type of variable passed in parameter, but it treats it like string of bytes.
You can do this with out additional code, the EEPROM library has two functions get() & put(), these will accept anything as a parameter.
struct config_t
{
long alarm;
int mode;
} ;
#define CFG_ADDR 0 //Address of data in EEPROM.
void func(){
config_t cfg;
//Read
EEPROM.get( CFG_ADDR, cfg );
//Write
EEPROM.put( CFG_ADDR, cfg );
}
I also have a library which makes EEPROM access super easy (higher level than what I wrote the EEPROM lib).
The EEPROM access is completely done in the background. Just use the variables as if they reside in RAM.
#include <EEPROM.h>
#include <EEWrap.h>
struct config_t{
int32_e alarm;
int16_e mode;
} ;
config_t cfg EEMEM; //EEMEM will cause the var to reside in EEPROM.
void setup(){
cfg.alarm = 4; //Write the EEPROM
if( cfg.mode > 0 ){ //Read the EEPROM
}
}
This lib is available from the library manager, and some details are here: EEWrap Library
Pyro, I looked into your EEWraw Library. It looks perfect for what I need. However, after installing the library, I opened the "basic_test" example, and it will not compile. Here is what I am getting:
#include <EEPROM.h>
#include <EEWrap.h>
//Use the xxx_e types rather than the standard types like uint8_t
struct Foo{
uint8_e a;
int16_e b;
float_e c;
};
Foo foo EEMEM; //EEMEM tells the compiler that the object resides in the EEPROM
void setup(){
//Write to values stored in EEPROM
foo.a = 45;
foo.b = 12345;
foo.c = 3.1415;
//Print values from EEPROM
Serial.begin(9600);
Serial.println(foo.a);
Serial.println(foo.b);
Serial.println(foo.c);
}
void loop() {}
So I tried it on my other machine which has IDE V1.6.5 installed, and got the same error that you did.
Might be time for an IDE upgrade.
V1.6.9 is stable like 1.6.5, V1.6.10 is a pig, V1.6.11 sounds like it's not bad.
Take your pick if you decide to upgrade.
Pyro, I looked into your EEWraw Library. It looks perfect for what I need. However, after installing the library, I opened the "basic_test" example, and it will not compile. Here is what I am getting:
You do not need to use that library, the Arduino EEPROM put and get functions can already read and write any arbitrary data type.
Also, you should never write anything to address 0. If the processor gets reset in the middle of a EEPROM write, the address registers will be reset to it will finish the write into address 0, not wherever it was supposed to be.
I'm sure that is true, but I found the EEWrap library to be very user friendly. Thank you Pyro for making this painfully simple library that even I could figure out!
Jiggy-Ninja:
You do not need to use that library, the Arduino EEPROM put and get functions can already read and write any arbitrary data type.
I already mentioned that, as I wrote both the EEPROM and EEWrap libraries, I can assure you they have very different functionality. The EEPROM lib is low-level (and has some interesting undocumented features), whereas the EEWrap lib is a very high-level approach.
Sorry for the issues, I had implemented a fix to work with C++98, however, it does not seem to be working. I'll get onto that and fix it. For future reference, I also have the PROGMEM equivalent PGMWrap which is pretty much the same usage (except the data is read-only).
Cheers.