Emulated EEPROM stopped working

I have been using emulated EEPROM on the Photon for a while now without any problems but today it stopped working.

I have tested it with the following code and the number printed out never changes from 0. This code works on another Photon I have.

void setup() 
{
    Serial.begin(115200);
    Particle.function("eeprom", updateEEPROM);
}

void loop() 
{
    Serial.println(EEPROM.read(0));
    delay(1000);
}

int updateEEPROM(String val)
{
    int i = val.toInt() % 256;
    uint8_t b = i;
    
    EEPROM.update(0, b);

    return i;
}

I think this is either because I have exceeded the rated number of write cycles or some other hardware issue?

I have been writing an object (shown below) using PUT about once every 10 seconds for the last 4 days so roughly 34,560 writes.
What is the rated number of write cycles on the Photon emulated EEPROM?

My object is the struct shown below:

struct Settings
{
    RegistrationStatus registrationStatus;
    char accessKey[10];
    int dataEepromAddress;
    Parameters parameters;
    long timeInterval;
    bool sdMessageLoggingEnabled;
    bool sdFrameLoggingEnabled;
    bool staging;
};

struct Parameters
{
    int16_t threshold;
    int16_t deadTime;
    int16_t aliveTime;
    int16_t doorPosition;
    int16_t distanceThreshold;
    int16_t scalingFactor;
    int16_t filterRadius;
    int16_t sigma;
    int16_t minDoor;
    int16_t maxDoor;
};

enum RegistrationStatus
{
    NOT_REGISTERED,
    REGISTERED,
    SETUP
};

The number of write cycles are in the order of 10,000 to 100,000. It’s not a hard number but you’re definitely in that range already.

I wouldn’t recommend writing such a large block of data to the EEPROM every 10s. Can you find a way to change your algorithm so you write less frequently?

Do you know how to use the DFU tool? If so you can dump the emulated EEPROM content on the device that doesn’t work properly and post it here. Put the device in DFU mode then run

dfu-util -d 2b04:d006 -a 0 -s 0x800C000:0x18000 -U eeprom.bin

I didn’t realise the number of cycles was so low.
Even saving once per hour gets up to 8736 writes in a year.

I’ve got some external EEPROM that I could use to store the settings on but I’m not sure how to serialise the object to bytes so I can save it. Is it possible to use PUT and GET to external EEPROM?

While it is true that the write (better erase) cycles for flash are in the range of 10,000 to 100,000 this should not really be the case here, since the emulated EEPROM uses (AFAIK) two pages (2x1024 byte) to spread the possible 100byte across them before a page erase should be required.
But @mdma would know more about that, as he has implemented the logic for it :wink:

Having said this, it’d be still better to limit the write frequency to that storage, as it is irreplacable without replacing the whole device.
You might like to consider retained memory or an external (replacable) storage (e.g. SD, FRAM) or even storing it in the cloud/net.

I have external EEPROM (24LC1025) on my PCB that I am using to store collected senor data so I could use this for my settings.

Is there an easy/accepted away to serialise/deserialise an object to a byte array so I can save it to my EEPROM?

The easiest way is to cast the pointer to your array/struct from (Settings*) to (uint8_t*) - but you have to be careful to calculate the size correctly, since you are dealing with a 32bit system, which aligns your variables to four byte boundaries (or you use #pragma pack(1))

If you have a lot of back and forth conversion between two ways of seeing your data, you might consider using union.

For serialization of an object, you should provide a serialization/deserialization method set inside that object and a constructor that will accept the serialized data “stream” as input.
Here you could find some pointers
http://stackoverflow.com/questions/26336414/serializing-object-to-byte-array-in-c
http://www.cplusplus.com/forum/general/47446

1 Like