5

In my current project I need to store the current elapsed time in hours to retrieve it in case of power loss. Since I am using a Arduino Nano I would ideally like to use the built in EEPROM without additional hardware.

The written values and their order will always be:

0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 0 -> ....

If I write that on EEPROM per 0->0 full cycle the last bit will change 7 times and the other bits are pretty much idle. That's why I thought of distributing the changes more evenly by using instead the sequence

0 -> 1 -> 3 -> 7 -> 15 -> 31 -> 63 -> 0 -> ....

This would change every bit only once during a full 0->0 cycle. Does this improve EEPROM life expectancy or is the life expectancy linked to updating full bytes rather than individual bits?

edit: Since the question was closed for being off-topic, I altered the introduction a little bit. I am sorry if some of the comments are no longer fully valid. Since I don't fully understand why the question was closed (especially since there is EEPROM-tag), I would be grateful for a tip where on stackexchange the question would be best suited.

9
  • 4
    Good question! You may consider adding zeros instead of ones (255 → 254 → 252 → 248 → 240 → 224 → 192 → 255), as for an EEPROM, a pure “write” operation only turns ones into zeros. On AVR, you could also try to use the “write only” mode of the EEPROM (see the datasheet) instead of the “Erase and Write in one operation” mode, which is the one used by the Arduino EEPROM library. Mar 25, 2022 at 9:27
  • Thank you for your comment. If I understand it correctly if i go from 00000001 to 00000011 what will actually happen is 00000001->11111111->00000011. So in order for my strategy to even have the hope to make sense I need to work with zeros instead of ones?
    – maxmilgram
    Mar 25, 2022 at 9:40
  • 2
    That's my understanding, but I am far from being an expert in EPPROM. I am eager to see the answers you get. ;-) Mar 25, 2022 at 9:49
  • The more practical solution is to store data to EEPROM only when you really need it - when power goes out.
    – gbg
    Mar 25, 2022 at 10:59
  • 1
    Because EEPROMS are (always) written byte-wise, I pretty much doubt this will change anything in the life expectancy.
    – tofro
    Mar 25, 2022 at 22:42

2 Answers 2

2

On your next design consider using FRAM, it is non volatile and supports almost unlimited (10 - 14th) read write cycles. The library I use or EEPROM supports the update function where it reads the memory first and does not write to it if it is to remain unchanged.

1

It is possible to write to ATmega EEPROM address without clearing its previous value. The write mode is set with the EEPMx bits in the EECR register.

The avr-libc eeprom.h write functions only use the erase and write mode and the Arduino EEPROM library only uses avr-libc eeprom.h write function.

I modified the EEPROM_write example function from the datasheet to write without erase.

#include <EEPROM.h>

void setup() {

  Serial.begin(115200);

  int address = 0;

  EEPROM.write(address, 0b11111111);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11111110);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11111101);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11101111);
  Serial.println(EEPROM.read(address), BIN);

}

void loop() {

}

void EEPROM_write_no_erase(unsigned int uiAddress, unsigned char ucData) {
  /* Wait for completion of previous write */
  while (EECR & (1 << EEPE))
    ;
  /* Set up address and Data Registers */
  EEAR = uiAddress;
  EEDR = ucData;
  /* Write only */
  EECR |= (1 << EEPM1);
  EECR &= ~(1 << EEPM0);
  /* Write logical one to EEMPE */
  EECR |= (1 << EEMPE);
  /* Start eeprom write by setting EEPE */
  EECR |= (1 << EEPE);
}

the output is as expected:

11111111
11111110
11111100
11101100

I don't know if use of this feature improves the lifetime of the ATmega EEPROM.

2
  • 1
    It would be safer to set EEMPE and EEPE with interrupts disabled, as recommended by the datasheet. Mar 27, 2022 at 18:43
  • @EdgarBonet this code is from the datasheet. I guess it expects the function to be called with interrupts disabled if a conflict is possible
    – Juraj
    Mar 27, 2022 at 19:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.