Stuct and EEPROM

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’:

  1. It is only used to store variables of different types, correct?
  2. What is the ‘config_t’ for? I read somewhere that it is optional(?) but if I remove it the code does not compile.
  3. 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);”
  4. Why does this if statement not need brackets after it?
  5. 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?

Thanks in advance,

Dustin

  1. Yes.
  2. 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;
  1. 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.

TwoChain:
2) What is the ‘config_t’ for? I read somewhere that it is optional(?) but if I remove it the code does not compile.

This compiles fine for me:-

struct
{
    long alarm;
    int mode;
} configuration;

It's useful if you only want one instance of the struct, named 'configuration'. You then access the variables in your code:-

configuration.alarm=1000;

etc
But you can't create multiple instances, whereas with the method that includes the tag, you can.

struct config_t
{
    long alarm;
    int mode;
}configuration;

void setup()
{
    Serial.begin(115200);
    configuration.alarm = 1000;
    
    config_t cfg;
    cfg.alarm = 500;
}

void loop(){}

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

Hi All,

Thank you for the very helpful replies!

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() {}

The error I get is:

Arduino: 1.6.5 (Windows 8.1), Board: "Arduino/Genuino Uno"

In file included from basic_test.ino:3:0:
C:\Users\Dustin\Documents\Arduino\libraries\EEWrap/EEWrap.h:71:113: error: 'char16_t' was not declared in this scope
value = is_number::value || is_bool::value || is_same< T, wchar_t >::value || is_same< T, char16_t >::value
^
C:\Users\Dustin\Documents\Arduino\libraries\EEWrap/EEWrap.h:71:122: error: template argument 2 is invalid
value = is_number::value || is_bool::value || is_same< T, wchar_t >::value || is_same< T, char16_t >::value
^
Error compiling.

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.

Do you have any idea why this is not compiling?

Thanks!

Dustin

I just downloaded the library, then copied and pasted the code above into an empty sketch, and it compiled fine for me. (UNO and Mega2560, IDE V1.6.9)

At that point, I did a quick search. It appears to be your IDE version. I found this:- EEWrap.h won't compile in Arduino Script

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. :slight_smile:

Thanks for looking into this for me Steve!

Dustin

TwoChain:
Thanks for looking into this for me Steve!

Dustin

You were quick. :slight_smile:
Anyway, no problem. Glad to help. Sorry I didn't find an easier fix. :frowning:

TwoChain:
Hi All,

Thank you for the very helpful replies!

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.

@TwoChain

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.

@OldSteve

Thanks for point out the newer IDE issue.

pYro_65:
@OldSteve

Thanks for point out the newer IDE issue.

No problem. Happy to help. :slight_smile: