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
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");
}
}
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().
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
so i really need help to put this together.
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.
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.
// 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);
}
}
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 += 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?
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.
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.
// 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");
}
}