EEProm put and get with Arduino mega

Mega is able to store over 4K bytes and I have an array of floats, that I am trying to store.
Each float is taking only 7 bytes , so space should not be an issue.

However I am able to store only one float, for the rest I get OVF,

Please help.
Mitch

#include <EEPROM.h>

float STEP_VALS [5] = {0.000f, 0.000f, 0.000f, 0.000f, 0.000f};

void setup() {
Serial.begin(115200);

EEPROM.put(0, 0.111);
EEPROM.put(1, 1.886);
 EEPROM.put(2, 2.111);
EEPROM.put(3, 3.886);
 EEPROM.put(4, 4.111);

 delay (100);

EEPROM.get(0, STEP_VALS[0]);
EEPROM.get(1, STEP_VALS[1]);
EEPROM.get(2, STEP_VALS[2]);
EEPROM.get(3, STEP_VALS[3]);
EEPROM.get(4, STEP_VALS[4]);

}

void loop() {
for (int i = 0; i <= 4; i++) {
Serial.print (STEP_VALS[i],3);
Serial.print (" at ");
Serial.println (i);
delay(100);
}

}

How will EEPROM.put know if You want to store a byte, a word, a long or a float?

What does EEPROM.put(0, 0.111); EEPROM.put(4, 1.886); EEPROM.put(8, 2.111); EEPROM.put(12, 3.886); EEPROM.put(16, 4.111);
produce?

I don't know,
The reference says that "Put" will store any data, and "get" will retrieve it.

And it works great , but only for one address.

It takes 4 bytes to store a float data type. The first float takes location 0, 1, 2, 3. The next address for a float is 4, not 1.

Read the forum guidelines to see how to properly post code and some hints on how to get the most from this forum.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Find out and know. Your mother doesn't live in the compiler.

EEPROM.put(1...... Where will that data be written? At the next byte address, next word address, next long or float address? You need to know.

Also know that EEPROMs have a rather limited amount of write/erase cycles before they stop working. Why use EEPROM at all? Why not a RAM residing array, values built in in the source code?

Sorry , I am a new at this, and never took computer science.
Thats the beauty of Arduino, even dum asses can get a project going with help from the real programmers out there...

So I tried,

#include <EEPROM.h>

float STEP_VALS [5] = {0.000f, 0.000f, 0.000f, 0.000f, 0.000f};

void setup() {
Serial.begin(115200);

EEPROM.put(0, 0.111);
EEPROM.put(4, 1.886);
 EEPROM.put(8, 2.111);
EEPROM.put(12, 3.886);
 EEPROM.put(16, 4.111);

 delay (100);
EEPROM.get(0, STEP_VALS[0]);
EEPROM.get(4, STEP_VALS[1]);
EEPROM.get(8, STEP_VALS[2]);
EEPROM.get(12, STEP_VALS[3]);
EEPROM.get(16, STEP_VALS[4]);

}

void loop() {
for (int i = 0; i <= 16; i=i+4) {
Serial.print (STEP_VALS[i],3);
Serial.print (" at ");
Serial.println (i);
delay(100);
}

}

But its still not right...

I need to remember the array after power off.
I will write some values once a week, so 100k writes is OK.

TNKS

Then don't write to EEPROM at every start up. Only write when the data is changed. That preserves the EEPROM.

Qutote: "But its still not right..." No? What is the result?

Use Serial.print (STEP_VALS[i]); as a beginning.

Why "delay(100);"? Learn to write code without delay. That pays off in the future, maybe even the near future.

In my final sketch I write data from encoders, not in the setup,

I made up this sketch to prove the problem.

Yes, I know about non blocking code.
But that is not my problem.

What is not right:

0.111 at 0
4.111 at 4
0.000 at 8
0.000 at 12
0.000 at 16

these are the values I get in the serial. Not what I wrote
Thanks

The STEP_VALS[ ] array has indexes 0,1,2,3,4.

void loop() {
for (int i = 0; i <= 16; i=i+4) {
Serial.print (STEP_VALS[i],3);
Serial.print (" at ");
Serial.println (i);
delay(100);
}

The for loop is addressing for STEP_VALS values at indexes of 0,4,8,12,16. You do not control the address space for the indexes above 4.
The STEP_VAL indexes are independent of the eeprom storage addresses.

Like this?

#include <EEPROM.h>

float STEP_VALS [5] = {0.000f, 0.000f, 0.000f, 0.000f, 0.000f};

void setup()
{
   Serial.begin(115200);

   EEPROM.put(0, 0.111);
   EEPROM.put(4, 1.886);
   EEPROM.put(8, 2.111);
   EEPROM.put(12, 3.886);
   EEPROM.put(16, 4.111);

   delay (1000);

   EEPROM.get(0, STEP_VALS[0]);
   EEPROM.get(4, STEP_VALS[1]);
   EEPROM.get(8, STEP_VALS[2]);
   EEPROM.get(12, STEP_VALS[3]);
   EEPROM.get(16, STEP_VALS[4]);

   for (unsigned int i = 0; i < sizeof(STEP_VALS)/ sizeof(STEP_VALS[0]); i++)
   {
      Serial.print (STEP_VALS[i], 3);
      Serial.print (" at ");
      Serial.println (i);
      delay(100);
   }
}
void loop()
{
}

Great , That works.

I wonder how many more available addresses I would have on a Mega? After 16, 20 etc?

4k gives You 4096 byte == 1024 floats, or long. Last index would be 1023....

Great
That is what I thought

Here is how I record them and it works great


  if ( SET_PIN_DB.fell() )
  { STEP_VALS[StepNo] = Mot_Ang_Read [1];
    EEPROM.put(StepNo*4, STEP_VALS[StepNo]);
  
    
    Serial.print ("Entered: ");
    Serial.println (STEP_VALS[StepNo], 3);
    Serial.print ("at: ");
    Serial.println (StepNo*4);
    
  }
if ( SET_PIN_DB.rose() )
  { 
    StepNo++;
    StepPrint ();
  }
  

Then my robot will remember a sequence of motions. Thanks a lot again, Mitch

Great! Thanks for Your fine communication! Solved in 16 posts is good! Please click the symbol "solved" for the most important reply!

I don't know the libs You use, like SET_PIN_DB so I can't comment that.

NOTE the remark, only wright to the EEPROM when a value is changed!

40 years ago I was investigating the very first EEPROMs and the number of writings was really highly limited. Modern EEPROMS still have a limited amount of cycles. Do some research, read manuals.... It pays off!

EEPROM.put uses the update() function which only writes to the address if the data has changed so the update() function takes care of that.

1 Like

Wow! Thanks for telling!

1 Like