I need to know how I can write integer values in EEPROM and retain the value on power on.
char *Red = strstr(myTestUrl, "/R");
if (Red) {
int RedValue = atoi(Red + 2);
analogWrite(12, RedValue);
Serial.println("Red :");
Serial.println(RedValue);
}
I want to write RedValue
in EEPROM. How can it be done?
-
1Have a look in the EEPROM sample sketches that are installed when you add ESP8266 support to the arduino ideJaromanda X– Jaromanda X2016年07月03日 02:47:45 +00:00Commented Jul 3, 2016 at 2:47
-
1having a question if there are any flash dependencies using the EEPROM. Can I flash with 1 MB (no SPIFFS) and have access to EEPROM? Thanks Triker1– riker12019年06月21日 13:44:25 +00:00Commented Jun 21, 2019 at 13:44
5 Answers 5
While EEPROM.read
and EEPROM.write
are valid methods, it's like mopping the floor with a toothbrush. Use EEPROM.put
and EEPROM.get
instead.
For example:
#include <EEPROM.h>
void setup()
{
Serial.begin(9600);
uint addr = 0;
// fake data
struct {
uint val = 0;
char str[20] = "";
} data;
// commit 512 bytes of ESP8266 flash (for "EEPROM" emulation)
// this step actually loads the content (512 bytes) of flash into
// a 512-byte-array cache in RAM
EEPROM.begin(512);
// read bytes (i.e. sizeof(data) from "EEPROM"),
// in reality, reads from byte-array cache
// cast bytes into structure called data
EEPROM.get(addr,data);
Serial.println("Old values are: "+String(data.val)+","+String(data.str));
// fiddle with the data "read" from EEPROM
data.val += 5;
if ( strcmp(data.str,"hello") == 0 )
strncpy(data.str, "jerry",20);
else
strncpy(data.str, "hello",20);
// replace values in byte-array cache with modified data
// no changes made to flash, all in local byte-array cache
EEPROM.put(addr,data);
// actually write the content of byte-array cache to
// hardware flash. flash write occurs if and only if one or more byte
// in byte-array cache has been changed, but if so, ALL 512 bytes are
// written to flash
EEPROM.commit();
// clear 'data' structure
data.val = 0;
strncpy(data.str,"",20);
// reload data for EEPROM, see the change
// OOPS, not actually reading flash, but reading byte-array cache (in RAM),
// power cycle ESP8266 to really see the flash/"EEPROM" updated
EEPROM.get(addr,data);
Serial.println("New values are: "+String(data.val)+","+String(data.str));
}
void loop()
{
delay(1000);
}
UPDATE: If you want to understand how the "EEPROM" is emulated in the ESP8266, you might want to reference https://github.com/esp8266/Arduino/tree/master/libraries/EEPROM, specifically, EEPROM.h
.
Also, EEPROM.end
is not needed, it simply clears the local byte-array cache of the flash/EEPROM from RAM. It serves on other function.
-
1you have saved my day, I was searching for more than five hours for a solution and you have gave it !nonozor– nonozor2018年05月09日 15:12:05 +00:00Commented May 9, 2018 at 15:12
-
1The actual Arduino documentation is really lacking here and the sources do not really help either. Is EEPROM.end() still needed? Why is begin(512) needed? Plus a get()/put() combination or using update() would help to prevent EEPROM wear. Maybe you could update the answer.Bim– Bim2018年07月13日 10:00:00 +00:00Commented Jul 13, 2018 at 10:00
-
2I did a copy/paste of this exact code for a NodeMCU v3 and it's not retrieving the written value after a power cycle (I commented out the "write portion for the second run").WhiskerBiscuit– WhiskerBiscuit2018年10月27日 18:15:31 +00:00Commented Oct 27, 2018 at 18:15
-
1@WhiskerBiscuit, are you seeing ANY output in serial console? are you sure baud rate is set correctly? i don't have v3, just v0.9, so can't help if this is a forwards compatibility problem.codechimp– codechimp2018年10月29日 00:17:40 +00:00Commented Oct 29, 2018 at 0:17
-
4from reference "EEPROM.write does not write to flash immediately, instead you must call EEPROM.commit() whenever you wish to save changes to flash. EEPROM.end() will also commit, and will release the RAM copy of EEPROM contents."2018年10月29日 08:15:04 +00:00Commented Oct 29, 2018 at 8:15
EEPROM.write(pos, val)
writes one byte (val
) at the address giving by pos
. An "int" in ESP8266 takes 4 bytes, so it's a little more complicated, because EEPROM works in bytes, not ints.
Here is a code for writing one int val
at some position pos
in the EEPROM:
void eeWriteInt(int pos, int val) {
byte* p = (byte*) &val;
EEPROM.write(pos, *p);
EEPROM.write(pos + 1, *(p + 1));
EEPROM.write(pos + 2, *(p + 2));
EEPROM.write(pos + 3, *(p + 3));
EEPROM.commit();
}
and, of course, you need to read it back:
int eeGetInt(int pos) {
int val;
byte* p = (byte*) &val;
*p = EEPROM.read(pos);
*(p + 1) = EEPROM.read(pos + 1);
*(p + 2) = EEPROM.read(pos + 2);
*(p + 3) = EEPROM.read(pos + 3);
return val;
}
In Arduino you call EEPROM.begin()
, but in ESP8266 you have to call EEPROM.begin(n)
, where n
is the total number of bytes you will need.
And remember that EEPROM have a short life span (by number of writes). You must minimize the number of writes!
EEPROM is permanent; you don't need to do nothing.
-
1I did some searching and it seems EEPROMs can handle many more write cycles than flash storage but then flash storage also has a controller to stop using bad sections and keep working with the remaining working ones.Qwertie– Qwertie2017年07月04日 02:01:11 +00:00Commented Jul 4, 2017 at 2:01
-
2UPVOTED because of the life cycle alert. 100k cycles, some say.tony gil– tony gil2019年05月28日 20:06:16 +00:00Commented May 28, 2019 at 20:06
Method using the number of letters.
#include <ESP8266WiFi.h>
const char* SSID = "R360"; //MAX 32
const char* PASSWORD = "HFDYUK64323246"; //MAX 32
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
EEPROM_ESP8266_GRABAR(SSID, 0); //Primero de 0 al 32, del 32 al 64, etc
EEPROM_ESP8266_GRABAR(PASSWORD, 32); //SAVE
Serial.println();
Serial.println(EEPROM_ESP8266_LEER(0, 32));//Primero de 0 al 32, del 32 al 64, etc
Serial.println(EEPROM_ESP8266_LEER(32, 64));
WiFi.begin(EEPROM_ESP8266_LEER(0,32).c_str(), EEPROM_ESP8266_LEER(32,64).c_str());
}
//
void loop() {}
//
void EEPROM_ESP8266_GRABAR(String buffer, int N) {
EEPROM.begin(512); delay(10);
for (int L = 0; L < 32; ++L) {
EEPROM.write(N + L, buffer[L]);
}
EEPROM.commit();
}
//
String EEPROM_ESP8266_LEER(int min, int max) {
EEPROM.begin(512); delay(10); String buffer;
for (int L = min; L < max; ++L)
if (isAlphaNumeric(EEPROM.read(L)))
buffer += char(EEPROM.read(L));
return buffer;
}
I use 2 separate functions in my code on ESP8266 - one with EEPROM.put()
, one with EEPROM.get()
.
I had EEPROM.begin(sizeof...);
only in EEPROM.put()
function and put
worked.
But it took me quite a while, until I found out, that it must be used before EEPROM.get()
as well.
Use #include <EEPROM.h>
EEPROM.begin(size); //Size can be anywhere between 4 and 4096 bytes.
EEPROM.write(0, RedValue); // To store in 0th Location
EEPROM.commit();