esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
16.02k stars 13.34k forks source link

Arduino 1.6.4 - ESP12 - EEPROM Data Getting ERASED #650

Closed abhishek-dixit closed 8 years ago

abhishek-dixit commented 9 years ago

Hi,

My EEPROM data survives normal power down and soft resets. Works always. But for some reason on quickly powering down and powering up in quick succession the eeprom data disappears.

Below are 4 methods:

  1. Write to EEPROM.
  2. Read from EEPROM.
  3. Restore End Point (i.e GPIO pin states) States.
  4. Read default configuration settings like access point, password.

Example case: .... /Reading Gateway:/ const int SECTION_SIZE_GATEWAY = 15 + 1; const int START_INDEX_GATEWAY = 0;//Size (15 + 1) : (192.168.123.321 + '\0')

printSerial("Reading device gateway"); deviceGateway = eepromRead(START_INDEX_GATEWAY, SECTION_SIZE_GATEWAY); printSerial(deviceGateway);

My entire home automation is up and running. Finding difficult to resolve this issue. Any help will be highly appreciated.

I am using Arduino 1.6.4

Thank You Guys.. //------------------------------------------------------- Code Below -----------------------------------------------------

-----------EEPROM - WRITE ----------- void eepromWrite(int startPos, String data, int sectionSize) { EEPROM.begin(512); int i = startPos; int index = 0; String trimmedData = data.substring(0, sectionSize - 1); //If section size = 5 then value should be 5 - 1 for data array as last place will be occupied by the '\0' char int charBufLengthWithLastChar = trimmedData.length() + 1; char charBuf[charBufLengthWithLastChar]; trimmedData.toCharArray(charBuf, charBufLengthWithLastChar) ; char dataByte; while (index < charBufLengthWithLastChar) { dataByte = charBuf[index]; EEPROM.put(i, dataByte); String indexMsg = "Writing for index"; indexMsg += index; indexMsg += " / val="; indexMsg += dataByte; indexMsg += "=";

printSerial(indexMsg);
i += 1;
index += 1;
yield();
delay(1);

} // turn the LED on when we're done printSerial("Done!"); EEPROM.end(); }

-----------EEPROM - READ -----------

String eepromRead(int startPos, int sectionSize) { EEPROM.begin(512);

int i = startPos; int index = 0; String data; byte readChar = -1; while (readChar != '\0' && index < sectionSize) { EEPROM.get(i, readChar); if (readChar != '\0') { data += (char)readChar; } i += 1; index += 1; yield(); delay(1); }

String dataRead = "="; dataRead += data; dataRead += "="; printSerial(dataRead);

//30th July 2015 : Read operation need not commit. //EEPROM.commit(); //EEPROM.end(); return data; }

-----------Read PIN Status COde -------------

void restoreEPStates() { printSerial("Restoring End Points Status");

String ep1 = eepromRead(START_INDEX_EXT_EP1, SECTION_SIZE_EXT_EP1); delay(10); String ep2 = eepromRead(START_INDEX_EXT_EP2, SECTION_SIZE_EXT_EP2); delay(10); String ep3 = eepromRead(START_INDEX_EXT_EP3, SECTION_SIZE_EXT_EP3); delay(10); String ep4 = eepromRead(START_INDEX_EXT_EP4, SECTION_SIZE_EXT_EP4); delay(10);

byte val1 = ep1.toInt(); turnExtensionPoint(val1, "1");

byte val2 = ep2.toInt(); turnExtensionPoint(val2, "2");

byte val3 = ep3.toInt(); turnExtensionPoint(val3, "3");

byte val4 = ep4.toInt(); turnExtensionPoint(val4, "4");

delay(10); }

----------- Turn Entension Point -------

void turnExtensionPoint(byte val, String pinStr) { int pinNum = pinStr.toInt(); String valStr = ""; valStr += val; switch (pinNum) { case 1: pinNum = OUTPUT_PIN1; digitalWrite(pinNum, val); eepromWrite(START_INDEX_EXT_EP1, valStr, SECTION_SIZE_EXT_EP1); break; case 2: pinNum = OUTPUT_PIN2; digitalWrite(pinNum, val); eepromWrite(START_INDEX_EXT_EP2, valStr, SECTION_SIZE_EXT_EP2); break; case 3: pinNum = OUTPUT_PIN3; digitalWrite(pinNum, val); eepromWrite(START_INDEX_EXT_EP3, valStr, SECTION_SIZE_EXT_EP3); break; case 4: pinNum = OUTPUT_PIN4; digitalWrite(pinNum, val); eepromWrite(START_INDEX_EXT_EP4, valStr, SECTION_SIZE_EXT_EP4); break; default: break; }


marvinroger commented 8 years ago

It does happen for me too. I am on NodeMCU 1.0 (nodemcuv2 - ESP-12E).

gordonthree commented 8 years ago

Was a solution ever found for this? I'm working with an ESP-12F (Gizwits board) and the eeprom contents are being lost after reset, despite trying EEPROM.commit() and/or EEPROM.end()

egrabhishek commented 8 years ago

It does happen with me even now. Do not know the exact solution. Planning to put external EEPROM like AT24c02 or something

gordonthree commented 8 years ago

After much reading, looks like the FS library supercedes the eeprom library. Rewrote my code using SPIFFS and it's cleaner and simpler than ever. Especially combined with ArduinoJson library 😀

arihantdaga commented 6 years ago

I am facing the same issue.. found no solutions.. I am using EEPROM library, and storing user settings into ESP EEPROM and Embedis Library i am not doing too many write operations also. Write operations are used only rarely.. But suddenly sometimes i wake up and see that ESP settings are gone. We are releasing a product for use in market and we have built huge infra for that, Everything is done, but now this problem is coming, Sometimes, randomly EEPROM is resetting and settings are lost... Any help would be very appreciated.. @marvinroger , @igrr

OmarAlkassab commented 5 years ago

I am facing the same issue.. and also no found solutions. Anyone solved the problem?

arihantdaga commented 5 years ago

@OmarAlkassab Try using this library https://github.com/xoseperez/eeprom_rotate. This is a wrapper around eeprom library which spread use of eeprom into multiple sectors and increase reliability. EDIT: Just make sure that while building always keep some portion for spiffs. (for example 4Mb flash, 1 Mb SPIFFS etc. ). Because this library uses sectors which falls under reserved section of spiffs. So if you are not keeping space for spiffs, during OTA some of your settings may erase.

OmarAlkassab commented 5 years ago

@arihantdaga, Sometimes the entire code got erased, not only the EEPROM content! Do you believe that this library can solve this issue also? Please note also, that I make a lot of read and write operations in the EEPROM.

arihantdaga commented 5 years ago

@OmarAlkassab Never faced issue of code getting erased. Did it happen randomly ? or on some event like OTA ? This library will definitely increase reliability for cases where there is lot of Read and Write. But still since EEPROM in esp has number of writes limitations (Around 10,000 as i recall), use it with caution.

OmarAlkassab commented 5 years ago

@arihantdaga It happened randomly not on the OTA, I noticed that this is happens after some rapid power down / power up for the ESP-12F. The number of 10,000 writes is enough for me for now.

arihantdaga commented 5 years ago

@OmarAlkassab Yeah, Its very much possible to loose eeprom during power fluctuations. A solution could be to use better/stable power supply or maybe adding a capacitor at the vcc(in general scenarios, thats what i try to do).

OmarAlkassab commented 5 years ago

@arihantdaga I added 0.1uF ceramic capacitor in parallel with 10uF tantalum capacitor at the VCC pin of the ESP-12F module, and connect VCC to Enable pin directly (without resistor). Is that enough or not?

gordonthree commented 5 years ago

@OmarAlkassab There's already a 0.1 or smaller decoupling resistor on the module itself, in front of the SOC. I would add a 100-220uF tantalum capacitor as a "tank" to provide energy for when the SOC switches modes, like doing a tx on the radio.

Suraj151 commented 5 years ago

@arihantdaga what if we use empty sector as backup sector rather to use eeprom rotate ( which uses multiple sectors ). for example 4mb flash esp has empty sector of minimum size around 4112 bytes available which resides immediate after sketch block i.e. around 255th sector may be its neither utilised by spiff nor ota in most cases. we can store copy of eeprom sector there ( while committing eeprom sector ) and will check at begin for safe sector to start with.

arihantdaga commented 5 years ago

@Suraj151 I dont think that'll be a good idea. Because those sectors will be erased if code size is changing in the OTA as far as i understand. Thats why we keep the last sectors (Not exactly last, but sectors after the SPIFFS)for the eeprom. And EEPROM Rotate is not just good solution for data backup but also reduces flash wear by spreading the writes to multiple sectors.

gpsolarco commented 1 year ago

Abhishek, what did you finally implement to solve this issue?

abhishek-dixit commented 1 year ago

Hi gpssolarco,

I used SPIFFS instead my own eeprom thing.

Also note that if you change SPIFFS configuration during upload or if you switch between IDs then the SPIFFS gets cleared.