How to remember int when power shuts off

Hello, i made a project where it counts the time when pin 3 is high. The only thing i wanna add is saving the time (int) to EEPROM. I tried it with a EEPROM code but i dont fully understand it. Anyone who can help me with this? Here is my project code, i will add the EEPROM code i think would work aswell (working in other project with the EEPROM code converted in my project but it looks messy). I am trying to save the int hour to eeprom, and if the power shuts off. I can read it back and start counting again. Any tips?

project code:

// deze constante veranderen niet
const int  buttonPin = 3;    // waar de button op aangesloten is
//   the button moet aangesloten zijn vanaf pin naar ground, pinmode is een input_pullup

// Deze variabelen veranderen 
bool buttonState;         // momentele status van de button
bool lastButtonState;     // vorige status van de button

unsigned long buttonBecamePressedAt;
unsigned long buttonHasBeenPressedForTotal = 0;
unsigned long buttonHasBeenPressedForThisTime = 0;
int hour;


void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println(".... Hoe lang is de button ingedrukt? ....");
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  // Initializa de button pin als een input with pullup active low.
  // verzeker dat de button van PIN naar GROUND
  pinMode(buttonPin, INPUT_PULLUP);

  //initialize button states
  buttonState = digitalRead(buttonPin);
  lastButtonState = buttonState;

  Serial.println("Setup done");
  Serial.println(" ");
}

void loop()
{
  // lezen van de pushbutton buttonpin:
  buttonState = digitalRead(buttonPin);

  // vergelijkt de buttonstaat naar de vorige staat
  if (buttonState != lastButtonState) // betekend dat hij veranderd is, welke kant nog onduidelijk
  {
    if (buttonState == LOW)  // veranderd naar ingedrukt
    {
      // als de momentele staat is LOW dan was de button ingedrukt
      Serial.print("Newly pressed at ");
      Serial.print(millis());
      Serial.print(" ms");
      buttonBecamePressedAt = millis();

    }
    else  // changed to released
    {
      // als de huidige staat HIGH dan was de button released
      Serial.print(", newly released at ");
      Serial.print(millis());
      Serial.println(" ms");

      buttonHasBeenPressedForThisTime = millis() - buttonBecamePressedAt;
      buttonHasBeenPressedForTotal = buttonHasBeenPressedForTotal + buttonHasBeenPressedForThisTime;
      Serial.print("   This press: ");
      Serial.print(buttonHasBeenPressedForThisTime);
      Serial.print(" ms");

      Serial.print(", Total: ");
      Serial.print(buttonHasBeenPressedForTotal);
      Serial.println(" ms");
      
      hour = buttonHasBeenPressedForTotal / 1000;
      Serial.println(hour);

      
    }
    // Delay om "stuiteren" te voorkomen
    delay(50);
  }
  // Verander de huidige staat als de vorige staat, voor de volgende keer door de loop
  lastButtonState = buttonState;

} 

EEPROM code:

#include <EEPROM.h>

void write2BytesInIntoEEPROM(intx address, int number)
{
  byte byte1 = (number >> 8) & 0xFF;
  byte byte2 = number & 0xFF;

  EEPROM.write(address, byte1);
  EEPROM.write(address +1, byte2);
}

int read2BytesIntFromEEPROM(int address)
{
  byte byte1 = EEPROM.read(address);
  byte byte2 = EEPROM.read(address +1);

  int result = (byte1 << 8) + byte2;
  return result;
}

void setup() {
  Serial.begin(9600);
  write2BytesInIntoEEPROM(12, 18404);
  Serial.println(read2BytesIntFromEEPROM(12));

}

Why not use EEPROM.put() and EEPROM.get() to save and load the int with a single command ?

1 Like

Instead of inventing EEPROM related functions yourself, you can use EEPROM.put() and eeprom.get() to read and write any type of data.

So that would e.g. result in below to save it

      hour = buttonHasBeenPressedForTotal / 1000;
      Serial.println(hour);
      EEPROM.put(12, hour);

So if i get it correct, this should work? but when i plug it out and in again. It starts at 0 again. What am i doing wrong? I wrote the EEPROM room 5 to value 0 in de setup. Than in the loop i updated 5 to the new value of "hour" . It still resets to 0 when i disconnect and connect the power, it doesnt remember the value it was at....

void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  **EEPROM.write(5, 0);**
  Serial.println(".... Hoe lang is de button ingedrukt? ....");
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  // Initializa de button pin als een input with pullup active low.
  // verzeker dat de button van PIN naar GROUND
  pinMode(buttonPin, INPUT_PULLUP);

  //initialize button states
  buttonState = digitalRead(buttonPin);
  lastButtonState = buttonState;

  Serial.println("Setup done");
  Serial.println(" ");
}

void loop()
{
  // lezen van de pushbutton buttonpin:
  buttonState = digitalRead(buttonPin);

  // vergelijkt de buttonstaat naar de vorige staat
  if (buttonState != lastButtonState) // betekend dat hij veranderd is, welke kant nog onduidelijk
  {
    if (buttonState == LOW)  // veranderd naar ingedrukt
    {
      // als de momentele staat is LOW dan was de button ingedrukt
      Serial.print("Newly pressed at ");
      Serial.print(millis());
      Serial.print(" ms");
      buttonBecamePressedAt = millis();


    }
    else  // changed to released
    {
      // als de huidige staat HIGH dan was de button released
      Serial.print(", newly released at ");
      Serial.print(millis());
      Serial.println(" ms");

      buttonHasBeenPressedForThisTime = millis() - buttonBecamePressedAt;
      buttonHasBeenPressedForTotal = buttonHasBeenPressedForTotal + buttonHasBeenPressedForThisTime;
      Serial.print("   This press: ");
      Serial.print(buttonHasBeenPressedForThisTime);
      Serial.print(" ms");

      Serial.print(", Total: ");
      Serial.print(buttonHasBeenPressedForTotal);
      Serial.println(" ms");
      
      hour = buttonHasBeenPressedForTotal / 1000;
        
      Serial.println(projectnummer);
      
      **EEPROM.update(5, hour);**
**      Serial.println(EEPROM.read(5));**
   

      
    }
    // Delay om "stuiteren" te voorkomen, delay van 50ms is genoeg hiervoor
    delay(50);
  }
  // Verander de huidige staat als de vorige staat, voor de volgende keer door de loop
  lastButtonState = buttonState;
}

Do you get a warning that the power is going to be shut off? If not, how will you know when to store the value?

No i might be doing that later. For now i just wanna update the value to EEPROM when the value is different.

What data type is hour ?

If it is an int then you are saving an int with EEPROM.update(), which takes 2 bytes, but only reading back one of them with EEPROM.read()

hour is an int. How am i able to readback the 2 bytes?

Use the EEPROM.put() and .get() methods. They only change data which has been changed and use .update() behind the scenes.

But if i use the put, it will always re-write to the EPROOM, if i use update it won't change unless the variable is different right? How should i implement it into my code?

You did not read the library documention or its source code.
https://docs.arduino.cc/learn/built-in-libraries/eeprom

https://github.com/PaulStoffregen/EEPROM

.put() function uses the update method to write its data, and therefore only rewrites changed cells.

Okay so what i see i just read it needs to be like this? But it still wont work...

#include <EEPROM.h>

// deze constante veranderen niet
const int  buttonPin = 3;    // waar de button op aangesloten is
//   the button moet aangesloten zijn vanaf pin naar ground, pinmode is een input_pullup

// Deze variabelen veranderen 
bool buttonState;         // momentele status van de button
bool lastButtonState;     // vorige status van de button

unsigned long buttonBecamePressedAt;
unsigned long buttonHasBeenPressedForTotal = 0;
unsigned long buttonHasBeenPressedForThisTime = 0;
int hour;
int AdressRoom = 15;
unsigned long projectnummer = 78125412;
if (buttonState != lastButtonState) // betekend dat hij veranderd is, welke kant nog onduidelijk
  {
    if (buttonState == LOW)  // veranderd naar ingedrukt
    {
      // als de momentele staat is LOW dan was de button ingedrukt
      Serial.print("Newly pressed at ");
      Serial.print(millis());
      Serial.print(" ms");
      buttonBecamePressedAt = millis();


    }
    else  // changed to released
    {
      // als de huidige staat HIGH dan was de button released
      Serial.print(", newly released at ");
      Serial.print(millis());
      Serial.println(" ms");

      buttonHasBeenPressedForThisTime = millis() - buttonBecamePressedAt;
      buttonHasBeenPressedForTotal = buttonHasBeenPressedForTotal + buttonHasBeenPressedForThisTime;
      Serial.print("   This press: ");
      Serial.print(buttonHasBeenPressedForThisTime);
      Serial.print(" ms");

      Serial.print(", Total: ");
      Serial.print(buttonHasBeenPressedForTotal);
      Serial.println(" ms");
      
      hour = buttonHasBeenPressedForTotal / 1000;
        
      Serial.println(projectnummer);

      
      EEPROM.put(AdressRoom, hour);
      Serial.println(EEPROM.read(AdressRoom));
Serial.println(EEPROM.read(AdressRoom));

You are still only reading a byte. Why did you not use EEPROM.get() as advised ?

Even when i put:

  EEPROM.put(AdressRoom, hour);
  Serial.println(EEPROM.get(AdressRoom, hour));

The time still resets whenever i close the seriële monitor, or power off / on the arduino....
I am new to using EEPROM so i am not sure what else is wrong...

this is the full code now:

#include <EEPROM.h>

// deze constante veranderen niet
const int  buttonPin = 3;    // waar de button op aangesloten is
//   the button moet aangesloten zijn vanaf pin naar ground, pinmode is een input_pullup

// Deze variabelen veranderen 
bool buttonState;         // momentele status van de button
bool lastButtonState;     // vorige status van de button

unsigned long buttonBecamePressedAt;
unsigned long buttonHasBeenPressedForTotal = 0;
unsigned long buttonHasBeenPressedForThisTime = 0;
int hour;
int AdressRoom = 15;
unsigned long projectnummer = 78125412;


void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println(".... Hoe lang is de button ingedrukt? ....");
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  // Initializa de button pin als een input with pullup active low.
  // verzeker dat de button van PIN naar GROUND
  pinMode(buttonPin, INPUT_PULLUP);

  //initialize button states
  buttonState = digitalRead(buttonPin);
  lastButtonState = buttonState;

  Serial.println("Setup done");
  Serial.println(" ");
}

void loop()
{
  // lezen van de pushbutton buttonpin:
  buttonState = digitalRead(buttonPin);
   

  // vergelijkt de buttonstaat naar de vorige staat
  if (buttonState != lastButtonState) // betekend dat hij veranderd is, welke kant nog onduidelijk
  {
    if (buttonState == LOW)  // veranderd naar ingedrukt
    {
      // als de momentele staat is LOW dan was de button ingedrukt
      Serial.print("Newly pressed at ");
      Serial.print(millis());
      Serial.print(" ms");
      buttonBecamePressedAt = millis();


    }
    else  // changed to released
    {
      // als de huidige staat HIGH dan was de button released
      Serial.print(", newly released at ");
      Serial.print(millis());
      Serial.println(" ms");

      buttonHasBeenPressedForThisTime = millis() - buttonBecamePressedAt;
      buttonHasBeenPressedForTotal = buttonHasBeenPressedForTotal + buttonHasBeenPressedForThisTime;
      Serial.print("   This press: ");
      Serial.print(buttonHasBeenPressedForThisTime);
      Serial.print(" ms");

      Serial.print(", Total: ");
      Serial.print(buttonHasBeenPressedForTotal);
      Serial.println(" ms");
      
      hour = buttonHasBeenPressedForTotal / 1000;
        
      Serial.println(projectnummer);

      
      EEPROM.put(AdressRoom, hour);
      Serial.println(EEPROM.get(AdressRoom, hour));
      
      
   

      
    }
    // Delay om "stuiteren" te voorkomen, delay van 50ms is genoeg hiervoor
    delay(50);
  }
  // Verander de huidige staat als de vorige staat, voor de volgende keer door de loop
  lastButtonState = buttonState;
  
}

What Arduino are you using?

If you run the library examples for .put() and .get() do you get persistent storage?

I am using a arduino ethernet shield 2, clicked onto an arduino uno. I can open the examples for .put() and .get() and run them correctly.

image

What does EEPROM.get() return? Check the reference page.

Try

EEPROM.get(AdressRoom, hour);
Serial.println(hour);

If i try:

EEPROM.get(AdressRoom, hour);
Serial.println(hour);

i get this in return:

8551