Losing data from EEPROM after some hours

Hi !
I'm using EEPROM.get and EEPROM.put to write and read some datas from EEPROM.
The thing is that the programm works fine if I turn off the board for some minutes and later turn on the board. However, if the board is off for some hours I lose all the data that was save and read before.
Any ideas about why I have this problem?

What sort of Arduino do you have?
Is it a clone or a genuine Arduino product?

Often clones use chips from the reject bin.

It sounds to me like a faulty chip, having said that it could be that Arduino were shipped a faulty chip as well.

I have no idea to be honest.
I'm new at the arduino's world and do not know how to check this.

Post a link to where you bought it from and a photograph of it and we can tell you.

The retention of EEPROM memory should be in the region of 20 years.

Also, please show us your code - it could be that your code is the culprit.
C

unfortunately the board is not with me right now, but I send the picture as soon as possible.
I bought it from a web site in Brazil.

#include <EEPROM.h>

#include "EasyNextionLibrary.h"  



EasyNex myNex(Serial);
bool manual = LOW;
bool teste = LOW;
bool pedal ;
bool zeraMan = false;
bool zeraAut = LOW;
bool led = LOW;
bool zeraOff = LOW;
bool botao = LOW;
bool volta = LOW;
int potDisplay;
int tonDisplay;
int toffDisplay;
unsigned long tempAux;
unsigned long multTempo = 60l;


void setup() {
  myNex.begin(9600);  
  pinMode(3, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, INPUT_PULLUP);
  pinMode(13, LED_BUILTIN);
  EEPROM.get(0, potDisplay);
  myNex.writeNum("n1.val", potDisplay);
  delay(10);
  EEPROM.get(4, tonDisplay);
  myNex.writeNum("n2.val", tonDisplay);
  delay(10);
  EEPROM.get(8, toffDisplay);
  myNex.writeNum("n3.val", toffDisplay);
  delay(10);

  EEPROM.get(16, multTempo);
  if (multTempo = 1000l) {
    myNex.writeNum("bt2.val", 1);
    delay(10);
  }
}

void loop() {
  myNex.NextionListen();
  delay(10);
  pedal = digitalRead(10);


  if (pedal && manual) {
    digitalWrite(8, HIGH);
    digitalWrite(9, HIGH);
    analogWrite(3, map(potDisplay, 100, 0, 0, 255));
    zeraAut = false;
    myNex.writeNum("tm0.en", 1);
    delay(10);
    myNex.writeNum("bt0.val", 1);
    delay(10);
    botao = true;
    if (zeraMan == false) {
      tempAux = millis();
      zeraMan = true;
    }
  }
  if (zeraMan) {
    if (millis() - tempAux >= multTempo * tonDisplay) {
      digitalWrite(13, !led);
      digitalWrite(8, LOW);
      digitalWrite(9, LOW);
      analogWrite(3, 0);
      myNex.writeNum("tm0.en", 0);
      delay(10);
      myNex.writeNum("p0.pic", 0);
      zeraMan = false;
      myNex.writeNum("bt0.val", 0);
      delay(10);
      botao = false;
    }
  }
  if (botao && !manual && !volta) {
    digitalWrite(8, HIGH);
    digitalWrite(9, HIGH);
    analogWrite(3, map(potDisplay, 100, 0, 0, 255));
    volta = true;
    zeraMan = false;
    myNex.writeNum("tm0.en", 1);
    delay(10);
    if (zeraAut == false) {
      tempAux = millis();
      zeraAut = true;
    }
  }
  if (zeraAut) {
    if (millis() - tempAux >= multTempo * tonDisplay) {
      digitalWrite(13, !led);
      digitalWrite(8, LOW);
      digitalWrite(9, LOW);
      analogWrite(3, 0);
      myNex.writeNum("tm0.en", 0);
      delay(10);
      myNex.writeNum("p0.pic", 0);
      zeraAut = false;
      if (zeraOff == false) {
        tempAux = millis();
        zeraOff = true;
      }
    }
  }
  if (zeraOff) {
    if (millis() - tempAux >= multTempo * toffDisplay) {
      volta = false;
      zeraOff = false;
    }
  }
}


void trigger0() {
  botao = !botao;
}

void trigger1() {
  potDisplay = myNex.readNumber("n1.val");
  delay(10);
  EEPROM.put(0, potDisplay);

  tonDisplay = myNex.readNumber("n2.val");
  delay(10);

  EEPROM.put(4, tonDisplay);

  toffDisplay = myNex.readNumber("n3.val");
  delay(10);

  EEPROM.put(8, toffDisplay);
}

void trigger2() {
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  analogWrite(3, 0);
  zeraMan = false;
  myNex.writeNum("tm0.en", 0);
  delay(10);
  myNex.writeNum("p0.pic", 0);
}

void trigger3() {
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  analogWrite(3, 0);
  myNex.writeNum("tm0.en", 0);
  delay(10);
  myNex.writeNum("p0.pic", 0);
  delay(10);
  botao = !botao;
}
void trigger4() {
  manual = !manual;
  bool zeraMan = LOW;
  bool zeraAut = LOW;
  bool zeraOff = LOW;
  delay(10);
}
void trigger5() {
  multTempo = 1000l;
  EEPROM.put(16, multTempo);
}

void trigger6() {
  multTempo = 60000l;
  EEPROM.put(16, multTempo);
}

This is the code.
I'm using a nextion trigger command to write the data.

Are the nextion trigger commands interrupt-driven? If so, do you know how often they occur? Two things to note:

  • interrupt routines should be as short as possible, so writing an EEPROM location from within one should be avoided
  • interrupt routines are often triggered very frequently, and as such, would be prone to 'burning up' the EEPROM if writes happen from within the interrupts.
    Otherwise, I don't see anything inherently wrong with what you've done, but others may see something.
    Frankly, I was expecting to see something 'String' based, as we know String manipulation in the simpler Arduinos is prone to memory consumption and frequent failures.
    C

I don't think it use interrupt routines as I understand from the easy nextion library:
"As these commands are using the Serial port to read and write, it is more preferred not to run them in the loop() without delay();"

This routine will not change the data very frequently by the user, since it is used to store some recipes for the application. I mean, the user will try some datas, and once he knows the numbers he need to his reality , he will not change it.

Oops, I think you mean == here.

I can't see anywhere where the functions starting with the word trigger are called at all. So I can't see where you ever write to the EEPROM.

The delays you use are nether here more there,

I can't actually follow what your code is doing.

Oh you are right. Thanks.

I'll try to explain:
Once the user push the button at nextion HMI it will send a command through serial port.
Each buttom have an expecific command at the HMI. The easy nextion library will "read" this command and run the code at the same trigger line. I don't know if I am clear enough, but I think the Library info can help me :

""" This is the most important function of the library. And this is because, it gives you the ability to use the predefined functions and run your code from there. These predefined functions are named trigger0() , trigger1() , trigger2() ... up to trigger50() . You can use them as a simple void function out of the loop, in which you will have written a block of code to run every time it is called. You can call those trigger() functions and run the code they contain anytime by simply writing in a Nextion Event the command: printh 23 02 54 XX , where XX the id for the triggerXX() in HEX. """

I think you are running into the problem of doing too much in one go. I would have started things off simply. First off by writing something into the EEPROM, maybe in different locations just once in the setup function.

Then writing another short piece of code again in the setup function to see that this is recovered correctly. In both cases you should have a blank loop function.

Then you can test the retention of your EEPROM.

In your code I can't see where you have included the EEPROM library.
Also this bit:-

void trigger5() {
  multTempo = 1000l;
  EEPROM.put(16, multTempo);
}

Seems to be putting a long int into EEPROM, but EEPROM only works in bytes. Sure there are other libraries that allow multi byte numbers to be recorded into EEPROM but you don't seem to be using them.

You know that it is easy to ware out EEPROM by too many writes to it. That can happen with careless programming.

Using the Nextion library, does that stop you using serial print in the monitor window to help you debug a program?

@Grumpy_Mike First line,
#include <EEPROM.h>
From Reference, EEPROM.put description:

Write any data type or object to the EEPROM.

Syntax

EEPROM.put(address, data)

Parameters

address: the location to write to, starting from 0 (int)
data: the data to write, can be a primitive type (eg. float) or a custom struct

I don't think the OP has actually told us what Arduino he has, so we don't know how many serial ports he has. There's no sign of Software Serial, so if it's an Uno or Nano, his one port is talking to Nextion.
C

With some boards, e.g. ESP8266, it is necessary to issue an EEPROM.commit() to permanently write to the (emulated) EEPROM otherwise the data does not survive a power cycle.

Fair enough, but we'll only know when the OP replies. Until then, we're wasting electrons.
C

Hi everyone!
Sorry take too long to answer. I was out of my office.
Looks like the problem was my board.
I changed it to a new one and the program is working fine.
I,m using arduino uno by the way.
Thanks for the support, you guys are the best!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.