Tech Note 015 - How to Use ESP8266 EEPROM

Поделиться
HTML-код
  • Опубликовано: 7 янв 2025

Комментарии • 71

  • @deangreenhough3479
    @deangreenhough3479 6 лет назад +3

    This has been a fantastic help, thank you for the explanation and code of so many examples. Life saver.

  • @spacefolder
    @spacefolder 7 лет назад

    Thank you for such a well explained and easy to follow tutorial. I needed to store my central heating's state (0 or 1), just in case the ESP looses power, restarts etc. Super simple and working like a charm.. Cheers!

  • @EducationalTheatre
    @EducationalTheatre 2 года назад

    how to save last relay state in to esp8266 when there powercut or restart
    please tell me thank you

  • @nareshveda3290
    @nareshveda3290 5 лет назад +1

    a clear and elaborate explanation, Thanks a ton.

  • @msmadaram
    @msmadaram 5 лет назад +1

    is it possible for esp to change his code in eeprom and update himself to newer version from my server?

    • @G6EJD
      @G6EJD  5 лет назад +1

      Yes, see OTA process

    • @msmadaram
      @msmadaram 5 лет назад

      @@G6EJD what's OTA? please help me man

    • @msmadaram
      @msmadaram 5 лет назад +1

      @@G6EJD ththank you for your consideration and support

    • @G6EJD
      @G6EJD  5 лет назад +1

      DOS over the air (OTA) updates

  • @raymccoy9105
    @raymccoy9105 Год назад

    I'm not sure this works as advertised. EEaddress is initialized to zero but incremented by the "sizeof()" BEFORE being written in a few places. Example 4 increments by the size of the prior variable written (2 for type int) so that happens to match, though possibly confusing. However, at Examples 4 and 5, the increment is for the size of data TO BE written, not last written. Since you write and then read using the same EEaddress, the value returned is correct, however, it is NOT being stored in the positions indicated.
    Please explain if I am missing something.

    • @G6EJD
      @G6EJD  Год назад

      The examples are not sequential, they are merely individual examples, it was never meant to be an end-to-end result just single actions that work. You say ‘not sure’ of which element?

    • @raymccoy9105
      @raymccoy9105 Год назад +1

      @@G6EJDI mentioned examples 3 and 4. For the string example, the address is incremented by the string length BEFORE it is written. Should be incremented by the length of the last thing written.

  • @simonndungu1196
    @simonndungu1196 5 лет назад

    Excellent demonstration and explanation. Thanks a bunch, Sir. Cheers

  • @madhukeshnp
    @madhukeshnp 6 лет назад +1

    can we ? use EEPROM to store the last state of a relay , and when the device reboots it has to remember the last state in EEPROM and put that into action.

    • @G6EJD
      @G6EJD  6 лет назад +2

      Yes:
      #include byte Relay_State; // 0 = Off, > 0 = On
      void setup(){
      Serial.begin(9600);
      EEPROM.begin(32);
      Relay_State = Recover_Relay_State(0);
      }
      void loop(){
      {
      //Do some stuff here...
      }
      Relay_State = 1; // For example set it on
      Save_Relay_state(0, Relay_State);
      delay(1000);
      }
      void Save_Relay_state(int address, byte value ){
      EEPROM.write(address,value);
      EEPROM.commit();
      }
      int Recover_Relay_State(int address){
      return EEPROM.read(address);
      }

    • @madhukeshnp
      @madhukeshnp 6 лет назад

      G6EJD
      Will this apply for nodemcu as well ?

    • @G6EJD
      @G6EJD  6 лет назад +1

      yes, any ESP8266 or ESp32

    • @madhukeshnp
      @madhukeshnp 6 лет назад

      G6EJD
      Thank you so much for your quick reply. I will try and let you know. Thank you once again for your valuable time

    • @G6EJD
      @G6EJD  6 лет назад +1

      Happy to help

  • @winandd8649
    @winandd8649 4 года назад

    I struggling:
    i can't get your your example 9 to work correctly, after writing 2 values, only the first is read back correctly..
    What i dont get:
    - in all examples you end a write command with a EEprom.commit() , but in example you use a EEprom.end() ??
    - in all examples you end a read command with no special commens , but in example you use a EEprom.commit() after reading ??
    Does not make sense?

    • @G6EJD
      @G6EJD  4 года назад

      I've checked the examples and can see no problems with them. For an EEPROM WRITE or PUT they must be completed by a COMMIT function otherwise the values are not written. EEPROM.end() closes the EEPROM services and EEPROM.BEGIN needs to be issued again.

    • @winandd8649
      @winandd8649 4 года назад

      ​@@G6EJD Thanks for your quick reply!!
      It does not seem to work, at least not for the second variable.. :-(
      Only the first variable is written en read back succesfully, the second variable was never written, or read...
      Need to say that i'm using a Wemos D1 mini board, maybe it has something to do with that? (also uses a esp3266)
      My test sketch ends with " c1 = 1234 c2 = 0"
      My test sketch:
      #include
      int c1,c2;
      // FILL vars
      void initVariables(){
      c1=1234;
      c2=5678;
      Serial.println("--- Vars filled.. ---");
      }
      // CLEAR vars
      void clearVariables(){
      c1=0;
      c2=0;
      Serial.println("--- Vars cleared.. ---");
      }
      // PRINT vars
      void printVariables(){
      Serial.print("c1 = ");Serial.println(c1);
      Serial.print("c2 = ");Serial.println(c2);
      }
      void writeEeprom(){
      int EEaddress = 0;
      EEaddress += EEPROM.put(EEaddress, c1);
      EEaddress += EEPROM.put(EEaddress, c2);
      EEPROM.commit();
      Serial.println("--- Vars written.. ---");
      }
      void readEeprom(){
      int EEaddress = 0;
      EEaddress += EEPROM.get(EEaddress, c1);
      EEaddress += EEPROM.get(EEaddress, c2);
      Serial.println("--- Vars read.. ---");
      }
      void setup(void) {
      Serial.begin(9600);
      EEPROM.begin(128); //size in bytes
      Serial.println("/n");
      initVariables();
      delay(500 );
      printVariables();
      delay(500 );
      writeEeprom();
      delay(500 );
      clearVariables();
      delay(500 );
      printVariables();
      delay(500 );
      readEeprom();
      delay(500 );
      printVariables();
      }
      void loop(){
      delay(500);
      }

    • @G6EJD
      @G6EJD  4 года назад

      @@winandd8649, you've got the same address each time you read or write! You need to set the address for each variable on the ESP8266 each int takes 4-bytes hence +4 here:
      int EEaddress = 0;
      EEaddress += EEPROM.put(EEaddress, c1);
      EEaddress += EEPROM.put(EEaddress,+4 c2);
      EEPROM.commit();
      Serial.println("--- Vars written.. ---");
      }
      void readEeprom(){
      int EEaddress = 0;
      EEaddress += EEPROM.get(EEaddress, c1);
      EEaddress += EEPROM.get(EEaddress,+4 c2);

    • @winandd8649
      @winandd8649 4 года назад

      @@G6EJD i appreciate your help very much, thank you!
      But.. the change does not help, still the same issue.
      I was assuming that EEaddress was increasing by the size of the used var, by useing 'EEaddress +=" in every line. That's also how you did it in your example..
      It could be that there is an exception fot the ESP3266, but this is not the solution :-(
      btw, note the comma placing; i assume you mean "EEPROM.put(EEaddress+4, c2)" instead of "EEPROM.put(EEaddress,+4 c2)" ...

    • @G6EJD
      @G6EJD  4 года назад

      What’s going wrong is the addressing and function formatting plus it looks like the ESP8266 compiler has changed, are you using the latest 2.5.3? To save a value use this EEPROM.get(addr,data); to get a value back use this EEPROM.put(addr,data); you can no longer use them as a function that returns a value do try a simple test c1=22; EEPROM.put(0,c1); c1=0; and EEPROM.get(0,c1); serial.println(c1);

  • @patrickelliott6476
    @patrickelliott6476 7 лет назад

    Can you tell me why in your example code, the value of the stored EEPROM data is all zeroes on the second loop through besides the data from example 9?

    • @G6EJD
      @G6EJD  7 лет назад +2

      +Patrick Elliott Yes, it has since been found there is a error in the eeprom.committ() function, so replace it with eeprom.end() and you may need to restart eeprom usage with eeprom.begin() it’s a compiler issue.

    • @patrickelliott6476
      @patrickelliott6476 7 лет назад +1

      Thanks for the guidance! I got it working. It seems anytime eeprom.end() is called is completely turns off access to the eeprom until eeprom.begin(size) is called again. However, eeprom.commit() does work to store the values in the eeprom. So my method is to call eeprom.begin(size) whenever I was going to have to access eeprom for reading or writing, use eeprom.commit to store the value if writing and then call eeprom.end when I was done accessing it.
      This is now working reliably for an eeprom with size of 3044, which is all I need. Thank you again for the video and the additional help!

    • @G6EJD
      @G6EJD  7 лет назад +2

      There is some cranky behaviour with the .end and .commit functions though. My experience is .commit on the ESP8266 does not commit as per the documentation, but writing only happens when .end is issued. I now only .begin, then write then .end then .begin again to read it back.

    • @simonndungu1196
      @simonndungu1196 5 лет назад +1

      @@patrickelliott6476 This really saved my day. Cheers

  • @williammiller7543
    @williammiller7543 6 лет назад

    I have used the EEPROM on the ESP8266 to store values between reboots. It is very convenient and extremely usefull. BUT, I have moved over to an ESP32 and do NOT find anything like the eeprom on the ESP8266. Any ideas?

    • @G6EJD
      @G6EJD  6 лет назад

      Strange problem, I use EEPROM all the time with the ESP32 and it works ok, so #include "EEPROM.h" then eeprom.begin(size) and use put and get values. The code is identical between the ESP32 and ESP8266. github.com/espressif/arduino-esp32/tree/master/libraries/EEPROM/examples

    • @G6EJD
      @G6EJD  6 лет назад

      William Miller BTW the ESP32 implementation uses Flash memory so it’s a simulated EEPROM function.

    • @williammiller7543
      @williammiller7543 6 лет назад

      Thanks, I did try it again and it now works.

    • @G6EJD
      @G6EJD  6 лет назад

      OK good.

  • @JustTheBasicsJS
    @JustTheBasicsJS 5 лет назад

    TLDR; Would you be able to create an example of reading and writing a STRUCT to EEPROM?
    I'm struggling to figure out how to load a struct with individual variables, save that struct to EEPROM, load the object again at boot and extract the individual values to their respective variables. Can you show me how to do that with a simple struct object containing a string and an int?
    In my specific case, I have some 25-30 individual variables that my app requires. At this time they are defined in the setup() function and are loaded with dummy data. Through the web server on my ESP8266 I have a page where the user can edit these values. The idea is that when changes are submitted from the webpage, those variables need to be saved to EEPROM, the device needs to reboot, and upon boot pull those variables in from the EEPROM. But instead of writing out many many lines of code to save each individual variable (which is a LOT of extra coding), I would like to stuff all those variables into a single serialized object (STRUCT?), write that object to EEPROM, reset the device, on boot load that object from EEPROM and assign the individual values to their respective variable names. Thank you in advance!

    • @G6EJD
      @G6EJD  5 лет назад

      John. If you define your type say ‘address’ with members ‘name’ of type string and ‘housenumber’ as type integer then you’d reference the values like this address.name and address.housenumber and then you can use these to read/write the values to EEPROM. The most important thing to note is the EEPROM filing system has no file management facilities so your program has to manage all that for example a varying length of string or you have to create a memory map showing the size of all variables used and their locations and stick to it.

    • @G6EJD
      @G6EJD  5 лет назад

      John, you can’t write a structure to EEPROM you have to manage it object by object, this is a limitation of using EEPROM.

    • @JustTheBasicsJS
      @JustTheBasicsJS 5 лет назад

      Thanks for the replies. So if strict won’t work, is there a way to serialize my data into another type of object that can be stored in eeprom? JSON for example...JSON is basically a string right? Any other ideas how I can achieve this?

    • @JustTheBasicsJS
      @JustTheBasicsJS 5 лет назад

      Also, I don’t quite understand why a strict won’t work. Can you explain? Is a struct not an object in memory like string and int? Thanks

    • @G6EJD
      @G6EJD  5 лет назад +1

      John, yes your correct a struct would work, but you can’t write or read that type in one easy command, all you can do is write bytes, strings, integers or floats. But they all need to be fixed entities unless you employ what is in effect file management techniques when r/w to eeprom, a string of variable length would of course change all addresses, so writing a struct out requires it to be deconstructed to its component parts and types then each type written out appropriately and the same in reverse. Yes, converting the struct to a JSON and writing that string to eeprom and the same (read) for recovery would be much simpler to use. I haven’t checked if there’s a string length limit on writes, although the maximum string length is 16384 bytes.

  • @lolslim690
    @lolslim690 7 лет назад

    I am new to electronics, and hopefully this will make sense, lets say I have a pic microcontroller, and in my project I originally had a eeprom I wanted to write to a text file. Is it possible for pic microcontroller to write to esp 8266 eeprom? or no?

    • @G6EJD
      @G6EJD  7 лет назад

      Yes it is, the maximum EEPROM size in the ESP8266 is 4096 bytes you initialise that with the function EEPROM.begin(4096). You could also do the same thing with the SPI bus Flash (SPIFFS) which uses the on-board flash memory to save data, you have on most devices 3MB of Flash storage available.

    • @lolslim690
      @lolslim690 7 лет назад

      The pic I want to use is pic12F1822, and I can't program that in arduino AFAIK, I would have to use a pickit. The part scares/confuses me since I am not sure if what I say on one device will == what said on the other device. I may end up just keeping 1mb eeprom in there, and just have the esp read it, while my pic writes to it. I mainly was just trying to save on phyical space.

    • @G6EJD
      @G6EJD  7 лет назад

      PIC12F1822 not in the Arduino IDE.Well I guess unless your programming in C on the PIC, it depends on how proficient you are with C. I don't know what sort of data your collecting, analogue or digital sensor data, but I can't think of any PIC that would perform any better than the ESP32/8266 in-terms of package, Wi-Fi availability, number of inputs, ADC, DAC, etc. It all comes down to personal choice I guess. If you have EEPROM on one device, do you mean using a dual-port EEPROM like say the 24LC41A so that both devices can read/write to it?One advantage of the ESP / Arduino environment is the wealth of examples and support, less so with the PIC.

    • @lolslim690
      @lolslim690 7 лет назад

      You know, I wonder if I can achieve what I want just with the esp8266 by itself, I mean, maybe? Wouldn't hurt to by one by itself, and see before buying the other parts.

    • @G6EJD
      @G6EJD  7 лет назад

      For about £2/$3 you'd get a decent ESP8266 (www.aliexpress.com/item/ESP8266-ESP-12-USB-WeMos-D1-Mini-WIFI-Development-Board-D1-Mini-NodeMCU-Lua-IOT-Board/32788532951.html?spm=2114.search0104.3.8.kEQzZs&ws_ab_test=searchweb0_0,searchweb201602_4_10152_10151_10065_10344_10068_10130_10324_10342_10547_10325_10343_10340_10548_10341_10192_10190_10084_10083_10613_10615_10307_10614_10301_10303_10059_10314_10184_10534_100031_10604_10103_10142,searchweb201603_40,ppcSwitch_4&algo_expid=d68baa91-7777-4f9c-ade9-7a63abd24582-1&algo_pvid=d68baa91-7777-4f9c-ade9-7a63abd24582&priceBeautifyAB=0) and get 3MB of flash (data) storage and have all the tools you'd need unless in a very fast real-time environment.

  • @vwlowen
    @vwlowen 6 лет назад

    Thanks for the tutorial, very helpful. I have a problem saving a String as the first letter is chopped off. I noted a small error in your String example at line 91 in that you clear the floating point variable rather than the String.
    (floatingpoint_variable = 0; // To prove it read from EEPROM!).
    When I clear the String variable, the "get" value returned is "ello World". I wonder if you see the same problem?

    • @G6EJD
      @G6EJD  6 лет назад

      Yes the variable named ‘floating_pointvariabke’ should not be there. I suspect the compiler has gone through some changes and now counts 0 as an address such that 12 needs to be 11 as the start address. It’s actually easier to use the FS flash filing system as writing a d reading strings is so much easier than having to track eeprom locations and flash memory is near identical in storage life.

    • @vwlowen
      @vwlowen 6 лет назад

      @@G6EJD Thanks for the reply. I would expect the put and get addresses to be the same though so, if they are both hard-coded to 12, for example, I'd have expected them to both point to the same address. I'll have to research the FS flash filing system as I'm not familiar with it. (John g4vwl)

    • @G6EJD
      @G6EJD  6 лет назад

      John, the SD library has had a lot of recent changes and when I uploaded that example is was working ok, so I’m sure recent changes have altered the operation of the read/write, I’ll try it out later. 73

  • @ronaldforero938
    @ronaldforero938 5 лет назад +2

    Excelente Amigo

  • @user-pv7zv8pi5b
    @user-pv7zv8pi5b 7 лет назад

    nice video! is there a limit of write times to EEPROM in ESP like in Arduino?

    • @G6EJD
      @G6EJD  7 лет назад

      Espresso say 100,000 but typically 1,000,000 so best to read many write few. I have a data logger running using SPIFFS for over 1-year now and it writes every 5-mins and it’s still working.

    • @G6EJD
      @G6EJD  7 лет назад

      100,000 but 1,000,000 is typical

  • @emremuslu7763
    @emremuslu7763 2 года назад

    Thank you!