how to know when a EEPROM address is empty?

In the setup I am reading a float from an Ardu Mega. Sometimes the Mega is virgin, and there is no value returned.
In that case I would want to assign it a value in the setup.

Next time I boot , if that read is valid, other than nothing, I would want to keep the value read from the EEPROM>

So with a virgin Mega, I get a "nan" returned for my float ,

I tried to write it in an if else.... but won't even compile,

Please help.

#include <EEPROM.h>

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

void setup(){

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

  Serial.begin( 9600 );
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.print( "Read float from EEPROM: " );

  //Get the float data from the EEPROM at position 'eeAddress'
  EEPROM.get( eeAddress, f );
  Serial.println( f, 3 );  //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float.

  // get() can be used with custom structures too. 
  eeAddress = sizeof(float); //Move address to the next byte after float 'f'.
  MyObject customVar; //Variable to store custom object read from EEPROM.
  EEPROM.get( eeAddress, customVar );

  if (customVar == nan)
{Serial,print ("Empty");
  customVar=8.88;
  }
  
  else
  {
  Serial.println( "Read custom object from EEPROM: " );
  Serial.println( customVar.field1 );
  Serial.println( customVar.field2 );
  Serial.println( customVar.name );
  }
}
1 Like

Is an EEPROM location ever empty ?

I believe that new EEPROMs have a value of 0xFF in all locations. You could, of course, initialise the EEPROM to known values with a simple sketch before using it with your main sketch

You can't compare an arbitrary object to 'NAN' since 'NAN' is a value of type 'double'. You can compare the 'float' field of your object to NAN:

  if (customVar.field1 == NAN)
  {
    Serial.print ("Empty");
    customVar.field1 = 8.88;
  }

Use the first few bytes of the EEPROM as a signature word (2-8 bytes). If they are all 0xff, ,then the EEPROM is "empty". Initialize it as you want, then set the signature word to a unique value. Next time, check the value of the signature word. If it is that same unique value, you can assume the EEPROM is initialized.

John
Tried your method like this. It does compile, but I don't get the expected results....

#include <EEPROM.h>


float Target =8.88;
void setup(){


  int eeAddress = 0; //EEPROM address to start reading from

  Serial.begin( 9600 );
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.print( "Read float from EEPROM: " );
  float TestAddress;
  EEPROM.get( 0, TestAddress );

if (TestAddress == NAN)
  {
    Serial.print ("First time target will be set at 8.88");
    Target = 8.88;
  }
  
  else
  {
   EEPROM.get( 0, Target );
  }
}

void loop(){ /* Empty loop */
  Serial.println (Target);
  delay (500);
  }

I think it hangs the processor, Mega. The loop won't print more than 3 times...
What am I doing wrong.

Ray,
your method sounds great, but how do I code such a thing. Sorry ,,,, beginner here.

Thanks

The other approach, like Ray’s is to reserve a nominated block of EEPROM, as a Byte Allocation Table (BAT), then when you write to previously unused memory, keep track of that in the BAT. There are better ways !
It’s fairly unusual to write unmanaged data to EEPROM, so you really should know where you put what.

An EEPROM location can only ever hold an unsigned byte value of 00-FF
So as was pointed out above, they are never ‘empty’ unless you specify an ‘empty’ value

laptophead:
Tried your method like this. It does compile, but I don't get the expected results....

It looks like "== NAN" doesn't work an you have to use the 'isnan()' macro. Here is code that works and the output thereof:

#include <EEPROM.h>

float Target;

void setup()
{
  Serial.begin(115200);
  while (!Serial) {}
  Serial.println();
  Serial.println(F("Begin"));

  Serial.print(F("Initial value of Target is "));
  Serial.println (Target);

  Serial.println( "Read Target from EEPROM");
  EEPROM.get(0, Target);

  Serial.print(F("Read value of Target is "));
  Serial.println (Target);

  if (isnan(Target))
  {
    Serial.println(F("Target is 'nan' so initialize."));
    Target = 2.22;
    Serial.print(F("Initialized value of Target is "));
    Serial.println (Target);
  }

  Serial.print(F("Working value of Target is "));
  Serial.println (Target);

  Target += 1.11;

  Serial.print(F("Incremented value of Target is "));
  Serial.println (Target);

  Serial.println("Updating EEPROM");
  EEPROM.put(0, Target);
  // EEPROM.put(0, NAN);  // Reset to unprogrammed
}

void loop() {}
Begin
Initial value of Target is 0.00
Read Target from EEPROM
Read value of Target is nan
Target is 'nan' so initialize.
Initialized value of Target is 2.22
Working value of Target is 2.22
Incremented value of Target is 3.33
Updating EEPROM

Begin
Initial value of Target is 0.00
Read Target from EEPROM
Read value of Target is 3.33
Working value of Target is 3.33
Incremented value of Target is 4.44
Updating EEPROM

Begin
Initial value of Target is 0.00
Read Target from EEPROM
Read value of Target is 4.44
Working value of Target is 4.44
Incremented value of Target is 5.55
Updating EEPROM
2 Likes

John
That worked like a charm. I am using this with an encoder that is setting the Target. In the past I had to load the code twice for every virgin unit. I wish you taught me this earlier... than you,

Mitch

Here is my code with the encoder

#include <EEPROM.h>

float Target;

float AddToTarget;

#include <Encoder.h>

long positionKnob  = -999;
long  newKnob;
Encoder Knob(18, 19); // 18 is Yellow 19 is Green

void setup()
{
  Serial.begin(115200);
  while (!Serial) {}
  Serial.println();

  EEPROM.get(0, Target);

  Serial.print(F("Read value of Target is "));
  Serial.println (Target);

  if (isnan(Target))
  {
    Serial.println(F("Target is 'nan' so initialize."));
    Target = 8.88;
    Serial.print(F("Initialized value of Target is "));
    Serial.println (Target);
    EEPROM.put(0, Target);
  }

}

void loop(){ /* Empty loop */

   newKnob = Knob.read();
    if (newKnob != positionKnob) {

      positionKnob = newKnob;
    AddToTarget = (newKnob / 10.0);
      

      Target = (Target + AddToTarget);
      Target = constrain(Target, 1, 10000);
      Serial.print(" KNOB = ");
      Serial.println(newKnob);
      Serial.print("   Target = ");
      Serial.print(Target, 2);
      Serial.println();
      Knob.write(0);

       EEPROM.put(0, Target);
    
    }
  Serial.println (Target);
  delay (500);
  }

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