float from counter to eeprom

hi
i am trying since days to write a float number, that is generatet by a counter, to eeprom and after power off - read it out again and continue to count.
i could handel it to write the float to eeprom - but i cannot read it out anymore after power off.
if power ist on again, it begins to count by zero instead of the last float that was written into eeprom.
what do i do wrong? thanks for help :confused:
here is my code

// include the library code:
#include <LiquidCrystal.h>
#include <EEPROM.h>


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);

// set pin numbers:
const int switchPin =2; // choose the input pin (for a pushbutton)
const int ledPin = 13; // choose the pin for the LED


int val = LOW; // variable for reading the pin status
int tasterGedrueckt = 0;      	// abfragen ob Taster gedrückt war
float counter = 0;
int ledStatus = LOW; 

int entprellZeit = 200;       	// Zeit für Entprellung, anpassen!

unsigned long tasterZeit = 0; 	// Zeit beim drücken des Tasters
unsigned long ledMillis = 0;  	// Zeit für den Blinkrythmus der LED


float f = 0.00f;   //Variable to store data read from EEPROM.
  int eeAddress = 0; //EEPROM address to start reading from


void setup() {
 
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.  
  lcd.print("m done "); 
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(switchPin, INPUT);
  Serial.begin(9600);

while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  
 //read the float data from the EEPROM at position 'eeAddress'

 // value = EEPROM.read(eeAddress);
 EEPROM.read(eeAddress);
  
  Serial.println("read float from EEPROM: ");
  Serial.println(EEPROM.read(eeAddress));
   
   Serial.print(eeAddress);Serial.println(" eeAddresse");
   Serial.print(f,3);
 

 lcd.print(EEPROM.read(eeAddress));
  
  lcd.setCursor(0, 1);
  

}

void loop() {
   
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  val = digitalRead(switchPin); // read input value

 EEPROM.read(eeAddress);
 

  if (val == HIGH) { // check if the input is HIGH (button released)
	tasterZeit = millis();  	// aktualisiere tasterZeit
	tasterGedrueckt = 1;    	// speichert, dass Taster gedrückt wurde
  }
  // Wenn die gewählte entprellZeit vergangen ist und der Taster gedrückt war...
  if ((millis() - tasterZeit > entprellZeit) && tasterGedrueckt == 1)
	{

     counter = counter + 100.732 ; 
    tasterGedrueckt = 0;    // setzt gedrückten Taster zurück

     f = counter;
  
     eeAddress = eeAddress + 1;
  if (eeAddress == EEPROM.length()) {
    eeAddress = 0;
  }

    EEPROM.write(eeAddress, counter);

        lcd.print(counter,3);lcd.print(" m ");
        Serial.print(counter,3);Serial.println(" m aus counter");

         Serial.print(f,3);Serial.println(" eeprom f");
        
         lcd.print(f,3);lcd.print(" ee");
       
      Serial.print(eeAddress);Serial.println(" eeAddress");
	} 

}

A float is more than one byte, you need to use the EEPROM.get() & EEPROM.put() functions to read data types longer than a byte.

See the link in my signature for some infor and links to examples, or look at the get and put examples in you IDE

Why not store the number of events, which is what counter implies, rather than some value computed from the number of events? That would require only two bytes, which can be extracted from the int using highByte() and lowByte().

counter = counter + 100.732 ;

That's unusual. It's pretty rare to count things like that. It's more common to count with an integer and then multiply by 100.732 when formatting for output.

But okay, lets assume you need to store and retrieve floating point values in the EEPROM. There is an EEPROMWriteAnything library which can be used to read and write all data types to the EEPROM. But for just one float, it's instructive to do it yourself.

A floating point number is 6 bytes but we don't need to remember that. The compiler already knows that, so let's use the compiler's knowledge via the sizeof() operator. Then we just need to do a bit of pointer casting and addition to allow us to push bytes into a float.

float GetFloatFromEEPROM(int EEAddress) {
  //load a floating point value from the bytes in the EEPROM
  int bytenum;
  byte* ptr;
  float returnVal;
  for (bytenum = 0; bytenum < sizeof(float); bytenum++) {
    ptr = (byte *)(&returnVal) + bytenum;
    *ptr = EEPROM.read(EEAddress + bytenum);
  }
  return returnVal;
}

The opposite task of storing a float into the EEPROM is left as an exercise.

and where do i put this peace of code? and how do i have to chance my script, so that it works?
i am a beginner and not very talented in coding :confused:
so i really need help to put this together.

i am a beginner and not very talented in coding :confused:

Rather than confuse yourself, you should be using EEPROM.put() and EEPROM.get() (available in IDE 1.62 and later) in place of EEPROM.read() and EEPROM.write() as reply #1 indicates.

A floating point number is 6 bytes

4 bytes, according to the IDE I use.

i tried it with put and get - but it doesn't work. i am doing something wrong - but have no idea what...
maybe you would write it into my code, for that i have a chance to understand?

i read somewhere, that a float needs 4 bytes but i have no idea how to write my float from the counter into these bytes - as i said - i am a beginner

I suspect that you did not read about EEPROM.put() and EEPROM.get(), as suggested in reply #1. It is a good idea to do so, as it can save you a lot of time posting on the forum and waiting for an answer.

This documentation includes an example of reading and writing a floating point number.

I did read it - but when i try to put it together with my script, then it does not work.
everything is wirtten in the setup - but i need for example EEPROM.put(eeAddress, customVar); in the loop so that i can write the result of the counter. but then i get an error - it sais, that customVar was not declared in this scope.

Post the code, using code tags.

here it is...

// include the library code:
#include <LiquidCrystal.h>
#include <EEPROM.h>

struct MyObject {
  float field1;
  byte field2;
  char name[10];
};

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);

// set pin numbers:
const int switchPin =2; // choose the input pin (for a pushbutton)
const int ledPin = 13; // choose the pin for the LED


int val = LOW; // variable for reading the pin status
int tasterGedrueckt = 0;      	// abfragen ob Taster gedrückt war
float counter = 0;
int ledStatus = LOW; 

int entprellZeit = 200;       	// Zeit für Entprellung, anpassen!

unsigned long tasterZeit = 0; 	// Zeit beim drücken des Tasters
unsigned long ledMillis = 0;  	// Zeit für den Blinkrythmus der LED


float f = 0.00f;   //Variable to store data read from EEPROM.
  int eeAddress = 0; //EEPROM address to start reading from

//MyObject customVar;



void setup() {
 
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.  
  lcd.print("m done "); 
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(switchPin, INPUT);
  Serial.begin(9600);

while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  
 //read the float data from the EEPROM at position 'eeAddress'

 // value = EEPROM.read(eeAddress);
 //EEPROM.put(eeAddress, f);


 //Data to store.
  MyObject customVar = {
    3.14f,
    65,
    "Working!"
  };

  eeAddress += sizeof(float); //Move address to the next byte after float 'f'.

  EEPROM.put(eeAddress, customVar);
  Serial.print("Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!");

  
  Serial.println("read float from EEPROM: ");
  Serial.println(EEPROM.get(eeAddress, f));
   
   Serial.print(eeAddress, f);Serial.println(" eeAddresse");
   Serial.print(f,3);


  lcd.print(f,3);lcd.print(" ");lcd.print(EEPROM.read(eeAddress));lcd.print("ad ");
  
  lcd.setCursor(0, 1);
  
}

void loop() {
   
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  val = digitalRead(switchPin); // read input value


  EEPROM.get(eeAddress, customVar);

  if (val == HIGH) { // check if the input is HIGH (button released)
	tasterZeit = millis();  	// aktualisiere tasterZeit
	tasterGedrueckt = 1;    	// speichert, dass Taster gedrückt wurde
  }
  // Wenn die gewählte entprellZeit vergangen ist und der Taster gedrückt war...
  if ((millis() - tasterZeit > entprellZeit) && tasterGedrueckt == 1)
	{

     counter = counter + 100.732 ; 
    tasterGedrueckt = 0;    // setzt gedrückten Taster zurück

    
     f = counter;
  
     eeAddress = eeAddress + 1;
  if (eeAddress == EEPROM.length()) {
    eeAddress = 0;
  }

    //EEPROM.put(eeAddress, f);
    EEPROM.put(eeAddress, customVar);

        lcd.print(counter,3);lcd.print(" m ");
        Serial.print(counter,3);Serial.println(" m aus counter");

         Serial.print(f,3);Serial.println(" eeprom f");
        
         lcd.print(f,3);lcd.print(" ee");
       
      Serial.print(eeAddress);Serial.println(" eeAddress");
      //Serial.print(eeAddress, customVar);
	} 
 
}

eeAddress = eeAddress + 1;

What are you trying to do here? You will end up filling the EEPROM with garbage, because each write overwrites 5/6ths of the previous value. Then you've got no way of finding out which address was the last one used when you switch the thing on after a power outage. All of that garbage will be valid floating point numbers, just not any number that you wrote.

The error message is because you created customVar inside setup() so it is out-of-scope in the loop() function.

eeAddress = eeAddress + 1;

this is a part of the eeprom-read-example from the arduino-page. i forgot to take it out.

and i moved the
//Data to store.
MyObject customVar = {
3.14f,
65,
"Working!"
};

above the setup() - so it becomes global

now i do not get any error message anymore - but it still does not keep the last number when i take power of... :frowning:

eeAddress += sizeof(float); //Move address to the next byte after float 'f'.

In the code as posted, you do this increment BEFORE reading the value into f. So you never get the value you have written.

Please re-post with your current code. Try to remove as much as possible of the testing - like remove the customVar thing entirely. Test your code exactly as it is posted here. What does it actually do? What do you think it should do?

Please tell me you're not writing to EEPROM every time through loop().

Well EEPROM.put() uses an update internally, which means it only initiates a write if the data is different to what's already stored there. It's a cheap way to write every single count to the EEPROM instead of once-per-second or once-per-10-counts.

I just hope he doesn't want to count a million items during the lifetime of this device.

ok here is the complete current code

i use a switch to count - first click should generate float 100.732 - second click should add 100.732 so that the new float would be 201.464 - next click 302.196 - and so on...

i need to store the floats somehow to keep the floats even if power ist off. for example 302.196 would be stored.
after power would be on again - i would like to «load» 302.196 again and with next click on the switch it would continue to count and generate 402.928

my script is calculating right but does not write the result into eeprom correct as wished.
for my opinion it should write the f into eeprom - but it writes the MyObject customVar whitch would be 3.14 as integer 4 into the eeprom - so it gives out 4 - 8 - 12 - 16 etc.

i am quite confused :confused:

i am quite confused

Me too.

Why are you storing a float, when you could store an integer value?

sorry - forgot the code - here it is

// include the library code:
#include <LiquidCrystal.h>
#include <EEPROM.h>

struct MyObject {
  float field1;
  byte field2;
  char name[10];
};

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);

// set pin numbers:
const int switchPin =2; // choose the input pin (for a pushbutton)
const int ledPin = 13; // choose the pin for the LED


int val = LOW; // variable for reading the pin status
int tasterGedrueckt = 0;        // abfragen ob Taster gedrückt war
float counter = 0;
int ledStatus = LOW;

int entprellZeit = 200;         // Zeit für Entprellung, anpassen!

unsigned long tasterZeit = 0;   // Zeit beim drücken des Tasters
unsigned long ledMillis = 0;    // Zeit für den Blinkrythmus der LED


float f = 0.00f;   //Variable to store data read from EEPROM.
  int eeAddress = 0; //EEPROM address to start reading from


//Data to store.
  MyObject customVar = {
    3.14f,
    65,
    "Working!"
  };


void setup() {
 
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD. 
  lcd.print("m done ");
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(switchPin, INPUT);
  Serial.begin(9600);

while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

 // eeAddress += sizeof(float); //Move address to the next byte after float 'f'.

  EEPROM.put(eeAddress, customVar);
  Serial.print("Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!");

 
  Serial.println("read float from EEPROM: ");
  Serial.println(EEPROM.get(eeAddress, f));
   
   Serial.print(eeAddress, f);Serial.println(" eeAddresse");
   Serial.print(f,3);


  lcd.print(f,3);lcd.print(" ");lcd.print(EEPROM.read(eeAddress));lcd.print("ad ");
 
  lcd.setCursor(0, 1);
 
}

void loop() {
   
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  val = digitalRead(switchPin); // read input value




  if (val == HIGH) { // check if the input is HIGH (button released)
  tasterZeit = millis();    // aktualisiere tasterZeit
  tasterGedrueckt = 1;      // speichert, dass Taster gedrückt wurde
  }
  // Wenn die gewählte entprellZeit vergangen ist und der Taster gedrückt war...
  if ((millis() - tasterZeit > entprellZeit) && tasterGedrueckt == 1)
  {

     counter = counter + 100.732 ;
    tasterGedrueckt = 0;    // setzt gedrückten Taster zurück


  EEPROM.get(eeAddress, customVar);
  eeAddress += sizeof(float); //Move address to the next byte after float 'f'.
   
     f = counter;
 
    EEPROM.put(eeAddress, customVar);

        lcd.print(counter,3);lcd.print(" m ");
        Serial.print(counter,3);Serial.println(" m aus counter");

         Serial.print(f,3);Serial.println(" eeprom f");
       
         lcd.print(f,3);lcd.print(" ee");
       
      Serial.print(eeAddress);Serial.println(" eeAddress");
 
  }
 
}