Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Understanding how example code works #9

Open
krupis opened this issue Jan 27, 2021 · 14 comments
Open

Understanding how example code works #9

krupis opened this issue Jan 27, 2021 · 14 comments

Comments

@krupis
Copy link

krupis commented Jan 27, 2021

Hello. I am very interested to learn how to save EEPROM life expectancy. I have slightly changed the example code "basic" but whenever I write to EEPROM and try to read back from it, I always read 0. .

My full code:

/*
 *  This sketch shows sector hoping across reboots
 */

#include <EEPROM32_Rotate.h>

EEPROM32_Rotate EEPROMr;

void setup() {

    // Init DEBUG --------------------------------------------------------------

    Serial.begin(115200);
    delay(2000);
    Serial.println();
    Serial.println();

    // Init EEPROM32_Rotate ----------------------------------------------------

    // You can add partitions manually by name
    EEPROMr.add_by_name("eeprom");
    EEPROMr.add_by_name("eeprom2");

    // Or add them by subtype (it will search and add all partitions with that subtype)
    //EEPROMr.add_by_subtype(0x99);

    // Offset where the magic bytes will be stored (last 16 bytes block)
    EEPROMr.offset(0xFF0);

    // Look for the most recent valid data and populate the memory buffer
    EEPROMr.begin(4096);

    // -------------------------------------------------------------------------

    uint8_t data;
    uint8_t quantity;
    quantity = 10;
    Serial.printf("Position 0: 0x%02X\n", EEPROMr.read(0));
    Serial.printf("Position 1: 0x%02X\n", EEPROMr.read(1));
    Serial.printf("Position 2: 0x%02X\n", EEPROMr.read(2));
    Serial.printf("Position 5: 0x%02X\n", EEPROMr.read(5));
    Serial.printf("Position 6: 0x%02X\n", EEPROMr.read(6));
    Serial.printf("Data      : 0x%02X\n", data = EEPROMr.read(5));

    Serial.println();
    Serial.printf("Writing 0x%02X to data\n", quantity);
    //EEPROMr.write(0, data + 1);
    EEPROMr.writeUShort(5, 10);

    Serial.println();
    Serial.printf("Commit %s\n", EEPROMr.commit() ? "OK" : "KO");
    Serial.printf("Position 0: 0x%02X\n", EEPROMr.read(0));
    Serial.printf("Position 1: 0x%02X\n", EEPROMr.read(1));
    Serial.printf("Position 2: 0x%02X\n", EEPROMr.read(2));
    Serial.printf("Position 5: 0x%02X\n", EEPROMr.read(5));
    Serial.printf("Position 6: 0x%02X\n", EEPROMr.read(6));
    Serial.printf("Data      : 0x%02X\n", data = EEPROMr.read(5));

    Serial.println("2ND TIME WRITING TO EEPROM");
    quantity = quantity +5;

    Serial.printf("Position 0: 0x%02X\n", EEPROMr.read(0));
    Serial.printf("Position 1: 0x%02X\n", EEPROMr.read(1));
    Serial.printf("Position 2: 0x%02X\n", EEPROMr.read(2));
    Serial.printf("Position 5: 0x%02X\n", EEPROMr.read(5));
    Serial.printf("Position 6: 0x%02X\n", EEPROMr.read(6));
    Serial.printf("Data      : 0x%02X\n", data = EEPROMr.read(6));
    
    
    Serial.printf("Data      : 0x%02X\n", data = EEPROMr.read(0));

    Serial.println();
    Serial.printf("Writing 0x%02X to data\n", quantity);
    //EEPROMr.write(0, data + 1);
    EEPROMr.writeUShort(6, quantity);

    Serial.println();
    Serial.printf("Commit %s\n", EEPROMr.commit() ? "OK" : "KO");
    Serial.printf("Position 0: 0x%02X\n", EEPROMr.read(0));
    Serial.printf("Position 1: 0x%02X\n", EEPROMr.read(1));
    Serial.printf("Position 2: 0x%02X\n", EEPROMr.read(2));
    Serial.printf("Position 5: 0x%02X\n", EEPROMr.read(5));
    Serial.printf("Position 6: 0x%02X\n", EEPROMr.read(6));
    Serial.printf("Data      : 0x%02X\n", data = EEPROMr.read(6));
    Serial.printf("Data      : 0x%02X\n", data = EEPROMr.read(0));

}

void loop() {}

I am doing 2 write cycles, first I write 10 to address 5, then I write 15 to address 6, during the read operation, I am not able to read back any of the values that I have set.

@xoseperez
Copy link
Owner

xoseperez commented Jan 27, 2021 via email

@krupis
Copy link
Author

krupis commented Jan 28, 2021

Thanks for the response!

Okay, that is quite strange! I have now ran another example script that is provided by this library. Unfortunately, I dont think it recongnizes the EEPROM partitions.

However, I sucessfully ran simple EEPROM examples on the same device without any issues.
image

I assume my settings for the device are also correct:
image

@krupis
Copy link
Author

krupis commented Jan 28, 2021

Running my code above, the values that I get :
image

@xoseperez
Copy link
Owner

xoseperez commented Jan 28, 2021 via email

@krupis
Copy link
Author

krupis commented Jan 29, 2021

Are none of the preset partition tables correct?
image

Also, I am not sure whether that makes any difference but as I mentioned above, I am able to use original EEPROM without any problems. If you are using the same API as the original EEPROM, it should work the same right?

The code I tested for original EEPROM and it worked:

/*
   EEPROM Write

   Stores random values into the EEPROM.
   These values will stay in the EEPROM when the board is
   turned off and may be retrieved later by another sketch.
*/

#include "EEPROM.h"

// the current address in the EEPROM (i.e. which byte
// we're going to write to next)
int addr = 0;
#define EEPROM_SIZE 64
void setup()
{
  Serial.begin(115200);
  Serial.println("start...");
  if (!EEPROM.begin(EEPROM_SIZE))
  {
    Serial.println("failed to initialise EEPROM"); delay(1000000);
  }

  Serial.print("Value in EEPROM 0 before writing =");
  Serial.println(EEPROM.read(0));
  Serial.println("Writing value 10 to EEPROM 0 address");
  EEPROM.write(0,10);
  EEPROM.commit();
  
  Serial.print("Value in EEPROM 0 after writing =");
  Serial.println(EEPROM.read(0));

  Serial.println("Writing value 19 to EEPROM 0 address");
  EEPROM.write(0,19);
  EEPROM.commit();
  
  Serial.print("Value in EEPROM 0 after second writing =");
  Serial.println(EEPROM.read(0));

  
}

void loop()
{
  // need to divide by 4 because analog inputs range from

}

image

@krupis
Copy link
Author

krupis commented Jan 29, 2021

Okay I might have confused myself. Do I need to manually create partitions for eeprom1 and eeprom2 as suggested here?:

image

If so, I have created a new .csv file as suggested by your previous links:

image

and saved it under partitions folder.

In the boards.txt I have also added 3 lines:

esp32.menu.PartitionScheme.test=rotate_eeprom
esp32.menu.PartitionScheme.test.build.partitions=test
esp32.menu.PartitionScheme.test.upload.maximum_size=1310720

image

When I try to compile the code using this new partition I am getting an error:
image

Traceback (most recent call last):
  File "gen_esp32part.py", line 524, in <module>
  File "gen_esp32part.py", line 471, in main
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 0: ordinal not in range(128)
Failed to execute script gen_esp32part
exit status -1
Error compiling for board ESP32 Dev Module.

@krupis
Copy link
Author

krupis commented Jan 29, 2021

I figured out what was the problem. The CSV that I have saved in the excell was not correct format. I must make sure that it does not have a border between different rows/collums as shown here:

image

I now able to compile the code and read/write from flash

image

@xoseperez
Copy link
Owner

xoseperez commented Jan 29, 2021 via email

@krupis
Copy link
Author

krupis commented Jan 29, 2021

Yes thanks for clarifying! I did not properly understood the part that you manually have to define your own custom partition. Also, could you clarify something for me...

In my project when the reset is initiated, I use:

        EEPROM.writeUShort(eeprom_counter, item_inside.quantity);               // 2^16 - 1
        eeprom_counter += sizeof(unsigned short);
        Serial.print("address after quantity=");
        Serial.println(eeprom_counter);
        
        EEPROM.writeString(eeprom_counter, item_inside.serial);
        eeprom_counter = eeprom_counter + 10;
        Serial.print("address after string=");
        Serial.println(eeprom_counter);
        
        //UPDATE THE eeprom counter
        EEPROM.write(0,eeprom_counter);
        EEPROM.commit();

And then when the program starts up one function is being called up:

void initial_eeprom_values(){
  eeprom_counter = EEPROM.read(0);
  Serial.print("Initial eeprom values = ");
  Serial.println(eeprom_counter);
  if(eeprom_counter >= 12)
    prev_eeprom_counter = eeprom_counter -12;
    
  EEPROM.get(prev_eeprom_counter,item_inside.quantity);
  Serial.print("quantity inside initial=");
  Serial.println(item_inside.quantity);
  if(item_inside.quantity == 65535){
    item_inside.quantity=0;
  }
  
  prev_eeprom_counter += sizeof(unsigned short);
  EEPROM.get(prev_eeprom_counter,item_inside.serial);
  prev_eeprom_counter = prev_eeprom_counter +10;
  Serial.print("serial isnide initial=");
  Serial.println(item_inside.serial);
}

This was my initial implementation of wear leveling but I soon realized that this is not going to do any good for me since its going to wear down Address 0 very fast since I save counter value there.

If I implement your EEPROM rotation code to my project where I have implemented 2 partitions "eeprom" and "eeprom2", does that mean that 1 reset cycle it is going to write values to "eeprom" and the second restart it will automatically write to "eeprom2". That should extend my EEPROM life cycle by 2 times right?

And since I do not use SPIFFS at all for my project, I could create as many partitions as possible and replace SPIFFS

@xoseperez
Copy link
Owner

xoseperez commented Jan 29, 2021 via email

@krupis
Copy link
Author

krupis commented Feb 1, 2021

Hey. Can you clarify me little bit regarding my project and use of rotate EEPROM? Perhaps I am still not fully understanding how to use it?

When the restart is initiated, I am executing this code:

        int addr=0;  
        Serial.printf("[EEPROM] Current partition   : %s\n", EEPROMr.current());
        EEPROMr.writeUShort(addr, item_inside.quantity);               // 2^16 - 1
        addr += sizeof(unsigned short);
        Serial.print("Quantity written=");
        Serial.println(item_inside.quantity);
        
        EEPROMr.writeString(addr, item_inside.serial);
        Serial.print("Serial written=");
        Serial.println(item_inside.serial);

        EEPROMr.commit();

        addr=0;

        EEPROMr.get(addr,item_inside.quantity);
        Serial.print("quantity inside after write initial=");
        Serial.println(item_inside.quantity);

        addr += sizeof(unsigned short);
        EEPROMr.get(addr,item_inside.serial);
        Serial.print("serial inside after write=");
        Serial.println(item_inside.serial);
        
        ESP.restart();

As you can see from the code above, I start from address 0, and write 2 variables to EEPROM. Quantity and serial. After EEPROMr.commit(), I read back the values that I have written just to confrim whether its correct and it looks fine
ESP.restart() will restart the ESP32 devices.

When the device start up again, I call this function:


void initial_eeprom_values(){
  int addr = 0;
  Serial.printf("[EEPROM] Current partition   : %s\n", EEPROMr.current());
 
    
  EEPROMr.get(addr,item_inside.quantity);
  Serial.print("quantity inside initial=");
  Serial.println(item_inside.quantity);
  
  if(item_inside.quantity == 65535){
    item_inside.quantity=0;
  }
  
  addr += sizeof(unsigned short);
  EEPROMr.get(addr,item_inside.serial);
  Serial.print("serial isnide initial=");
  Serial.println(item_inside.serial);
}

The function above supposed to read back the last values that have been saved in EEPROM before the erase but it does not work. Also, it does not look like partition 2 of EEPROM is ever reached, it is always first partition:

image

@krupis
Copy link
Author

krupis commented Feb 2, 2021

Perhaps I havent properly understood the working principle of this library. I have also noticed some strange behaviour of that program I have shown you before where we write to EEPROM 2 times to position 5 and position 6. When I write these values I can read them back correctly, however, when I restart the device, I expect the position5 and position6 have some values saved from the previous time, but it reads back 0xFF from both? Surely that is not correct behaviour right?

flash

@xoseperez
Copy link
Owner

xoseperez commented Feb 3, 2021 via email

@krupis
Copy link
Author

krupis commented Feb 3, 2021

I have swapped the ESP32 device, and added your sketch:

image

As you can see, I have both partitions recognized. Its weird why I am not able to read back the data that I have written after the restart

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants