Store multiple data to EEPROM

I just need a small help to completed my project. As my output is printing 2 result but only 1 result is saving into the eeprom. How can i save multiple data into eeprom?


  1. Could you share some code please?
  2. If you’re writing to the EEPROM you need to specify an address and then the information like:
#include <EEPROM.h> // include library

void Setup() {

}

void Loop() {

EEPROM.write(some address, some value);

}

Here’s the code:

#include <math.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

#define O0 11
#define O1 10
#define O2 9
#define O3 6
#define O4 5
#define O5 3
#define I0 A0
#define I1 A1
#define I2 A2
#define I3 A3
#define I4 A4
#define I5 A5

const int analogInPin1 = I0; // Analog input pin that the Accelerometer's first pin is attached to
const int analogInPin2 = I1; // Analog input pin that the Accelerometer's second pin is attached to
const int analogInPin3 = I2; // z-axis
const float LPF_alpha = 0.16; //LPF_Alpha=dT/(RC+dT)
const float HPF_alpha = 0.83; //HPF_Alpha=RC/(RC+dT)
const float gNlowB=0.038,GNlowB=0.008;
const float gNhighB=1,GNhighB=1;

float ValueX,ValueY,ValueZ; //raw data from ADC

float output[5];
//acc date wrt to g value of earth, gN is the norm
//gNavg is after LPF (the constant due to earth). gNins should be 0 if not moving...

//these data do averaging on individual axis
float gX,gY,gZ,gXA,gYA,gZA,gXP,gYP,gZP;
float gXins,gYins,gZins,gNins,gXinsP,gYinsP,gZinsP,gNinsP;
float gXinsA=0,gYinsA=0,gZinsA=0,gNinsA=0;
float GN,GNP,GNA,GNins,GNinsA=0; 
float gNinsMax,GNinsMax;
float actgN_acc=0,actGN_acc=0;
float actgN,actGN;
float act_dist=0,act_DIST=0;
float gX_hpf=0,gY_hpf=0,gZ_hpf=0,GN_hpf=0;
//these data convert to norm early on, and do avg/ins
float gN_hpf=0;

float vel=0, dist=0, VEL=0,DIST=0;

float aX, aY, aZ;   //tilt angle
float vdd=4.91;     //the measured 5V supply. Meter reading is more accurate

//sensitivity from datasheet is 0.5V/g. unit of sens is g/value. 1024=vdd
//this group of data can be calibrated and stored in EEPROM
float sens=(vdd/1024)/0.5000; 
float sensX=sens;  //without calibration, default value is from the datasheet
float sensY=sens;
float sensZ=sens;
float mid=1023/2;
float midX=mid;
float midY=mid;
float midZ=mid;
unsigned long time,preTime=0,curTime; //dT need for integration
float dT=0,aT=0;

int noAvg=10; //averaging of 10 reading
int dispCnt=1,actCnt=0; //display 1/10 the data or else human can't read. actCnt must be offset from dispCnt
int keyResponse;
int i =0;
int loopI = 1;
struct calData_t
{ int   written; //99 if written
  float mx,my,mz,sx,sy,sz,dx,dy,dz,dv,dd;
} ;
calData_t calData;

struct gVector_t{
  float gx,gy,gz;
};
gVector_t gV,gVNorm;

float readAcc(float &ValueX,float &ValueY, float &ValueZ, char One, int noAvg);
void calOne(char One, float &mid, float &sens);
void LPF(float &d, float &dAvg, float &dIns); //LPF 1 data
void Max(float &Max, float &d);
void reset_vel(float &a, float lowB, float &v);

int readkey() { 
  // read 1 char from serial monitor
  int c;
  while(!Serial.available());   
    c= Serial.read(); //read 1 byte ?only read 1 byte 
    delay(100);
    while(Serial.available()>0){   
      Serial.read();  //keeping reading. Clear the buffer until Serial.available()==0
    }
  return c;
}

void calibration(){
  calOne('z',midZ,sensZ);
  calOne('x',midX,sensX);
  calOne('y',midY,sensY);
  dispCalData();
  storeCalData();
}

void storeCalData(){ // store data after dispCalData()
  calData=(calData_t){99 , midX,midY,midZ,sensX,sensY,sensZ};
  while (!eeprom_is_ready()); // Wait for EEPROM to be ready
  cli();
  eeprom_write_block((const void*)&calData, (void*)0, sizeof(calData));
  Serial.println("Cal data written to EEPROM...");
  sei();
}
void data(){

  Serial.print(" gXins= ");
  Serial.print(output[0],5);

  Serial.print(" gYins ");
  Serial.print(output[1],5);
  
  Serial.print(" gZins= ");
  Serial.print(output[2],5);
  
  Serial.print(" VEL ");
  Serial.print(output[3],3);

  Serial.print(" DIST= ");
  Serial.print(output[4],3);

  Serial.println();
  delay(5000);
}

void dispCalData(){
  Serial.println("The current middle value and sensitivity are: ");
  Serial.print("sensX:");
  Serial.print(sensX,5);
  Serial.print("\tsensY:");
  Serial.print(sensY,5);
  Serial.print("\tsensZ");
  Serial.print(sensZ,5);
  Serial.print("\tsens without cal:");
  Serial.println(sens,5);
  
  Serial.print("midX:");
  Serial.print(midX,5);
  Serial.print("\tmidY:");
  Serial.print(midY,5);
  Serial.print("\tmidZ");
  Serial.print(midZ,5);
  Serial.print("\tmid without cal:");
  Serial.println(mid,5);  
  delay(5000);
}

void calOne(char One, float &mid, float &sens){
  //when you're cal z=+1g, you could cal for x=y=0g
  //this only need to perfm 6 cal instead of 9 cal
  //however, it is more messy in the code and hard to trace if there is cal error.
  float Pos1g=0, Neg1g=0;
  String String1=String(One)+"=0g cal: put "+String(One)+                "=0g and hit 'y' & RETURN";
  String String2=String(One)+"=+1g cal: put +"+String(One)+ " facing upwards and hit 'y' & RETURN";
  String String3=String(One)+"=-1g cal: put +"+String(One)+ " facing   downwards and hit 'y' & RETURN";
  Serial.println(String1);
  keyResponse=readkey();
  if (keyResponse=='y'){
    delay(1000);
    mid=readAcc(ValueX,ValueY,ValueZ,One,100);
  }
  Serial.println(String2);
  keyResponse=readkey();
  if (keyResponse=='y'){
    delay(1000);
    Neg1g=readAcc(ValueX,ValueY,ValueZ,One, 100); 
  }
  Serial.println(String3);
  keyResponse=readkey();
  if (keyResponse=='y'){
    delay(1000);
    Pos1g=readAcc(ValueX,ValueY,ValueZ,One,100); 
  }  
  if (Pos1g==0 || Neg1g==0){}
  else {sens=2/(Pos1g-Neg1g);}  
}

float readAcc(float &ValueX,float &ValueY, float &ValueZ, char One, int noAvg){
  //read acc data (from ADC) with averaging. Return values via pointers.
  //parameter One allow you to return 1 axis acc reading.
  float X=0; float Y=0; float Z=0;
  for (int i=0; i < noAvg; i++){  //int is 16bit
    X = X+analogRead(analogInPin1);
    Y = Y+analogRead(analogInPin2);
    Z = Z+analogRead(analogInPin3);
    delay(10);   //datasheet suggest 10ms delay for ADC to settle
  } 
  ValueX=X/noAvg;
  ValueY=Y/noAvg;
  ValueZ=Z/noAvg;  
  if (One == 'x')     { return ValueX;}
  else if (One == 'y'){ return ValueY;}
  else                { return ValueZ;}
}

void Max(float &Max, float &d){ //max is keyword
  if (d>Max){Max=d;}
}

void cap(float &d,float lowB, float highB){ 
  if (d<lowB){d=0;}
  else if (d>highB){d=highB;}
  else {;}
}    

void reset_vel(float &a, float lowB, float &v){
  if (a<lowB){v=0;}
}

float mapAcc(float x, float mid, float sens){
  //what return is the actual acc data in g
  return sens*(x-mid);
}

float norm(float x, float y, float z){
  return sqrt(x*x+y*y+z*z);
}

void LPF(float &gN, float &gNP, float &gNA, float &gNins){
  gNA=LPF_alpha*gN + (1-LPF_alpha)*gNA;
  gNins=gN-gNA;
} 

void HPF(float &gin, float &ginP, float &gout){
  gout=HPF_alpha*(gout+gin-ginP);
} 

void display_result(int delayLoop){
  delay(delayLoop);
    
  Serial.print(" gXins=" );
  Serial.print(gXins,5);

  Serial.print(" gYins=" );
  Serial.print(gYins,5);

  Serial.print(" gZins=" );
  Serial.print(gZins,5);
  
  Serial.print(" VEL=" );
  Serial.print(VEL,3);
  
  Serial.print(" DIST=" );
  Serial.print(DIST,3);  
  
  Serial.println(' ');
  Serial.print("\n"); 
}

Note that EEPROM only stores bytes so if you want to store an int you have to split it up into two bytes and store each one separately. Then to read it you read two bytes and join them together.

How about posting ALL of your code.

You know code that actually compiles.

And doesn't have functions missing.

It's probably best to use the included arduino EEPROM library instead of the backgroud C libs.

Simply include the library found in the IDE
and the write and read to an address by changing the EEPROM parameter.

e.g EEPROM.read(address); or EEPROM.write(address, data);

each storage space is 1 byte long so like the grumpy version of me said, you may need to store the data and read the data separately and co-join them together again.

Each read / write cylce takes roughly a few millis

Code too long.
Here’s the second part:

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
  Serial.println("Hit 'y' and RETURN, if you want to calibrate...");
  Serial.println("Hit 's' and RETURN, if you want to collect data...");
  Serial.println("Hit 'x' and RETURN, if you want to clear the cal data in EEPROM...");
  Serial.println("If not, 'n' and RETURN");
  Serial.println(' ');
  Serial.println("\n");
  keyResponse=readkey();
  //keyResponse='n';
  if (keyResponse=='y'){
      calibration();
  }
   if (keyResponse=='s'){
      Serial.println("Collecting data...................");
  }
  else if (keyResponse=='x'){ 
    while (!eeprom_is_ready()); // Wait for EEPROM to be ready
    cli();
    calData.written=0;
    eeprom_write_block((const void*)&calData, (void*)0, sizeof(calData));
    Serial.println("Cal data is cleared...");
    sei();    
  }
  else {
     while (!eeprom_is_ready()); // Wait for EEPROM to be ready
     cli();
     eeprom_read_block((void*)&calData, (void*)0, sizeof(calData));
     sei();
     if (calData.written==99){
       Serial.println("Using previously stored cal data from EEPROM");
   //    midX=calData.mx; midY=calData.my; midZ=calData.mz;
   //    sensX=calData.sx;sensY=calData.sy;sensZ=calData.sz;
       output[0]=calData.dx; output[1]=calData.dy; output[2]=calData.dz;
       output[3]=calData.dv; output[4]=calData.dd;
     }
     else {
        Serial.println("no previous cal data, using default");
     }
    // dispCalData();
    data();
    exit(0);
  }
  readAcc(ValueX,ValueY,ValueZ,'x',10);
  gXA = mapAcc(ValueX, midX, sensX); //cannot let gXA at 0, will create err.
  gYA = mapAcc(ValueY, midY, sensY);
  gZA = mapAcc(ValueZ, midZ, sensZ); 
  GNA = norm(gXA,gYA,gZA); 
  preTime=micros();
}
void loop() {

int i=0;
  while(loopI<=2){
 // read the both analog in values:
			readAcc(ValueX,ValueY,ValueZ,'x',10);
curTime=micros();
dT=curTime-preTime;
preTime=curTime;
aT=aT+dT;
gX = mapAcc(ValueX, midX, sensX);
gY = mapAcc(ValueY, midY, sensY);
gZ = mapAcc(ValueZ, midZ, sensZ);

LPF(gX,gXP,gXA,gXins);
LPF(gY,gYP,gYA,gYins);
LPF(gZ,gZP,gZA,gZins);
gNins=norm(gXins,gYins,gZins);
cap(gNins,0.01,1);

gXinsA=(gXinsA+gXins)/2;
gYinsA=(gYinsA+gYins)/2;
gZinsA=(gZinsA+gZins)/2;
gNinsA=(gNinsA+gNins)/2;

//HPF(gXins,gXinsP,gX_hpf);
//HPF(gYins,gYinsP,gY_hpf);
//HPF(gZins,gZinsP,gZ_hpf);
//HPF(GNins,GNinsP,GN_hpf);
//HPF(gNins,gNinsP,gN_hpf);


GN = norm(gX,gY,gZ);
LPF(GN,GNP,GNA,GNins);
cap(GNins,GNlowB,GNhighB);
GNinsA=(GNinsA+GNins)/2;

Max(gNinsMax,gNins);
Max(GNinsMax,GNins);

reset_vel(gNins, gNlowB, vel);
reset_vel(GNins, GNlowB, VEL);

vel=vel+9.81e-6*gNins*dT;
VEL=VEL+9.81e-6*GNins*dT;
act_dist=act_dist+9.81e-6*vel*dT;
act_DIST=act_DIST+9.81e-6*VEL*dT;

actCnt=actCnt+1;

if (actCnt>=10){
actGN=sqrt(actGN_acc/10);
actGN_acc=0;
actgN=sqrt(actgN_acc/10);
actgN_acc=0;

dist=dist+act_dist;  act_dist=0;
DIST=DIST+act_DIST;  act_DIST=0;
actCnt=0;
}
actgN_acc=actgN_acc+(gNins*gNins);
actGN_acc=actGN_acc+(GNins*GNins);

dispCnt=dispCnt+1;
if (dispCnt>=40){
display_result(0);
loopI++;

dispCnt=0;
}
gXP=gX; gYP=gY; gZP=gZ;  GNP=GN;
  }			
output[0] = gXins;
output[1] = gYins;
output[2] = gZins;
output[3] = VEL;
output[4] = DIST;
  Serial.println("Cal data written to EEPROM..."); // store to EEPROM	
  calData=(calData_t){99 , 0,0,0,0,0,0,output[0],output[1],output[2],output[3],output[4]};
while (!eeprom_is_ready()); // Wait for EEPROM to be ready
  eeprom_write_block((const void*)&calData, (void*)0, sizeof(calData));
 
 if(loopI>2)
 {   
   exit(0);
 }
}

Code too long

Then read the how to use this forum sticky which will tell you to attach the file!

It still does not compile.

And by the way use lowByte and highByte to do the splitting up before saving, and then word later on after you read them back and stick them back together again.

@Fufu

Is there a third part to this code because the function we all want to see is 'eeprom_is_ready()'

What is this EEPROM? it is certainly not the internal one with such a named function.

Grumpy_Mike:
@Fufu

Is there a third part to this code because the function we all want to see is 'eeprom_is_ready()'

What is this EEPROM? it is certainly not the internal one with such a named function.

'eeprom_is_ready()' is under the loop

output[0] = gXins;
output[1] = gYins;
output[2] = gZins;
output[3] = VEL;
output[4] = DIST;
  Serial.println("Cal data written to EEPROM..."); // store to EEPROM	
  calData=(calData_t){99 , 0,0,0,0,0,0,output[0],output[1],output[2],output[3],output[4]};
  while (!eeprom_is_ready()); // Wait for EEPROM to be ready
  eeprom_write_block((const void*)&calData, (void*)0, sizeof(calData));

eeprom_is_ready()' is under the loop

What is that supposed to mean?

eeprom_is_ready is a function. I can see where you have used it. I can not see where you have defined it.

Grumpy_Mike:

eeprom_is_ready()' is under the loop

What is that supposed to mean?

eeprom_is_ready is a function. I can see where you have used it. I can not see where you have defined it.

How do i defined it? I was using arduino EEPROM examples.

How do i defined it?

You tell me.

I was using arduino EEPROM examples.

What examples?

Why do you think this code compiles without you defining it. It can't.

This means you are not posting all your code, like you have been requested to do.

Are you just jerking us around because that is what it looks like from this end.

Grumpy_Mike:

How do i defined it?

You tell me.

I was using arduino EEPROM examples.

What examples?

Why do you think this code compiles without you defining it. It can't.

This means you are not posting all your code, like you have been requested to do.

Are you just jerking us around because that is what it looks like from this end.

Please my code is working, i'm asking how to store multiples data into EEPROM, Can u look at the picture i upload in the first place? Stop give those unnecessary comment. If my code can't compiles, where do u think i get the picture from?
Lastly have u try and test all my code was given here? how do u know i'm not posting all my code?

eeprom_is_ready() is defined in avr/eeprom.h, you do need to include it.

Instead of using your own loop, the macro eeprom_busy_wait() does this for you.

Yes your code compiles but when I try and compile what you posted there are lots of errors. That is why I know you have not posted all your code.

If you have a problem with that just you try copying and pasting what you have posted and see if you can get it to compile.

void storeCalData(){ // store data after dispCalData()
  calData=(calData_t){99 , midX,midY,midZ,sensX,sensY,sensZ};
  while (!eeprom_is_ready()); // Wait for EEPROM to be ready
  cli();
  eeprom_write_block((const void*)&calData, (void*)0, sizeof(calData));
  Serial.println("Cal data written to EEPROM...");
  sei();
output[0] = gXins;
output[1] = gYins;
output[2] = gZins;
output[3] = VEL;
output[4] = DIST;
  Serial.println("Cal data written to EEPROM..."); // store to EEPROM	
  calData=(calData_t){99 , 0,0,0,0,0,0,output[0],output[1],output[2],output[3],output[4]};
  while (!eeprom_is_ready()); // Wait for EEPROM to be ready
  eeprom_write_block((const void*)&calData, (void*)0, sizeof(calData));

I’m not really sure where you are writing to the eeprom in your code, but i have the feeling that you are writing to the same destination both times you store the cal data. Clearly from the posted screen shots the second set is there correctly, so you have probably overwritten the first.

One thing that helps with these projects involving eeprom is to actually monitor where things are going. The tool can be as simple as

#include <EEPROM.h>

// start reading from the first byte (address 0) of the EEPROM
int address = 0;
byte value;

void setup()
{
  
  Serial.begin(9600);
  
  // read a byte from the current address of the EEPROM

  for(address=0; address<100; address++)
  {
    value = EEPROM.read(address);

    Serial.print(address);
    Serial.print("\t");
    Serial.print(value, HEX);
    Serial.print("\t");
    Serial.print(value, DEC);
    Serial.print("\t");
    Serial.print(char(value));
    Serial.println();


  }

}


void loop()
{

}