Save and Retrieve values from EEPROM

Hi all,

Im trying to store my Auth token in my NodeMCU (EP12) EEPROM so that it will just reload it if restarted. I think the code is generally right and I’ve successfully been able to save the value into EEPROM and retrieve from EEPROM. But I’m not able to use the Auth Token after retrieve of the values.

I’m able to retrieve the value from EEPROM and it looks as expected, but when I use it in my Blynk.config, it doesn’t connect as if it’s the wrong code. Can you see anything wrong or missing from the below?

    struct { //value to store into EEPROM
	  uint val = 0;
	  char str[33] = "";
	} blynkAuth;

	uint addr = 0; //Start of my value

    //Save the string into EEPROM
    // first clear 'blynkAuth' structure
    blynkAuth.val = 0; 
    strncpy(blynkAuth.str,"",33);
    // Now save the new value
    strncpy(blynkAuth.str,custom_blynk_token.getValue(),33);
    EEPROM.begin(512);
    EEPROM.put(addr,blynkAuth);
    EEPROM.commit();  
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Get the string from EEPROM
    // first clear 'blynkAuth' structure
    blynkAuth.val = 0; 
    strncpy(blynkAuth.str,"",33);
    //Now get the value from eeprom
    EEPROM.begin(512);
    EEPROM.get(addr,blynkAuth);
    Serial.println("Stored Blynk Value: " + String(blynkAuth.str));

There is a library called WiFi Manager which does exactly that using SPIFFs. Otherwise if you want to know about EEPROM …
EEPROM can only write from 0 - 255. What i use to write longs to EEPROM is the following code

//EEPROM_LONG//
void EEPROMWritelong(int address, unsigned long value)
{
  //Decomposition from a long to 4 bytes by using bitshift.
  //One = Most significant -> Four = Least significant byte
  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);
  
  //Write the 4 bytes into the eeprom memory.
  EEPROM.write(address, four);
  EEPROM.write(address + 1, three);
  EEPROM.write(address + 2, two);
  EEPROM.write(address + 3, one);
  EEPROM.commit();
}

//This function will return a 4 byte (32bit) long from the eeprom
//at the specified address to adress + 3.
unsigned long EEPROMReadlong(long address)
{
  //Read the 4 bytes from the eeprom memory.
  long four = EEPROM.read(address);
  long three = EEPROM.read(address + 1);
  long two = EEPROM.read(address + 2);
  long one = EEPROM.read(address + 3);
  
  //Return the recomposed long by using bitshift.
  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

//END//

To write a long use

EEPROMWritelong(0, MinFlow);
EEPROMWritelong(5, MaxFlow);
EEPROMWritelong(10, Flow1Time);
EEPROMWritelong(15, Flow2Time);

NOTE the EEPROM memory allocations to allow for the unsigned long.
To read the EEPROM

svMinFlow = EEPROMReadlong(0);
  svMaxFlow = EEPROMReadlong(5);
  svFlow1Time = EEPROMReadlong(10);
  svFlow2Time = EEPROMReadlong(15);

i normally the create a function which reads all the EEPROM values stored which is updated only when a write function has been called. Then in my actual function which will need these values i save the EEPROM reads to anothe variable to avoid continuous reads from the EEPROMReadLong functions

void SINE2P_N_B()
{
  unsigned long MinF = svMinFlow;
  unsigned long MaxF = svMaxFlow;
  unsigned long F1T = svFlow1Time;
  unsigned long F2T = svFlow2Time;
//ACTION HERE//
}

Is there any reason why you don’t just hard code it into your sketch like most people do?

Pete.

Thanks Proietti. Actually I found my problem was a typo. While the auth token was stored in blynkAuth.str I was using blynkAuth.val in the next call.

Although I’m now facing a different issue… The value is stored and retrieved correctly even when I press the reset button. But if I unplug my Wemos D1 mini and plug it back in, it seems to lose the value from EEPROM. Any idea what’s going on there?

Mostly because this is a poor way to implement code?

It rather depends what you are trying to achieve.
If you want to be able to change the Auth code without re-loading the sketch then simply storing the Auth code in EEPROM is only part of the answer. You then need a interface (which does not rely on Blynk) to edit that value without connecting your device to a computer and using software to overwrite the stored Auth code value.
This is exactly what WiFiManager and @khoih’s alternative to WiFiManager do, so you’re simply re-inventing the wheel. Whilst that can be somewhat satisfying, it’s not actually an efficient way to implement code.

Also, the use of EEPROM is now a very outdated approach. With the hardware that you’re using, the use of SPIFFS is a far better way to handle the storage of non-volatile data. I won’t go into the SPIFFS versus EEPROM analysis here, but Google will provide more information on the subject than you’ll ever need.

Personally, rather than using a WiFiManager type of solution for projects that are designed for personal use, I prefer to hard code the Blynk auth code, WiFi credentials, MQTT server address etc and use OTA as a simple way to update devices. I find this much faster to use - direct from the desktop, rather than going around with a mobile device connecting to each MCU in turn and re-configuring them via WiFiManager.

If you’re making devices that you’re going to send out to non-technical users then WiFiManager is a great way for these people to configure those devices without the need to mess around with uploading a new version of the firmware that contains the credentials.
This approach also allows you to use HTTP OTA that allows the devices to ‘phone home’ every so often to see if there is a new version of the firmware available from you, to fix software bugs.

Pete.

1 Like

Also we have not seen your entire code…but if you are starting from boot your programme will go through the setup again and you need to have a read action from either the SPIFFS or EEPROM