Go Down

Topic: Can someone explain EEprom to me please (Read 269 times) previous topic - next topic

JohnRandalls

I am trying to learn how data is stored in the eeprom when I write something at one address and want to write different values at a different address.  How do I know how far to advance so I don't overwrite anything.

This is what I am writing to address 2 in eeprom.
Code: [Select]
struct saveConfig
{
  int saved1 = 1;
  int saved2 = 2;
  int saved3 = 2;
  int saved4 = 0;
  int saved5 = 0;
  int saved5 = 4500;
} config;

values saved at address 2


This is what I see when I check the positions.
Code: [Select]
EEPROM position: 0 contains 0
EEPROM position: 1 contains 0
EEPROM position: 2 contains 1
EEPROM position: 3 contains 0
EEPROM position: 4 contains 2
EEPROM position: 5 contains 0
EEPROM position: 6 contains 2
EEPROM position: 7 contains 0
EEPROM position: 8 contains 1
EEPROM position: 9 contains 0
EEPROM position: 10 contains 0
EEPROM position: 11 contains 0
EEPROM position: 12 contains 194
EEPROM position: 13 contains 1
EEPROM position: 14 contains 0


This is the code
Code: [Select]
#include <EEPROM.h>
int zz;
int EEsize = 1024; // size in bytes of your board's EEPROM
bool readMemory = false;

void eraseMemory()
{
  Serial.println("Writing random numbers...");
  for (int i = 0; i < EEsize; i++)
  {
    zz=random(255);
    EEPROM.write(i, zz);
  }
  Serial.println();
}

void readMemoryLocations(int memSize)
{
  //for(int a = 0; a < EEsize; a++)
  for(int a = 0; a < memSize; a++)
  {
    zz = EEPROM.read(a);
    Serial.print("EEPROM position: ");
    Serial.print(a);
    Serial.print(" contains ");
    Serial.println(zz);
    delay(25);
  }
}

void setup()
{
  Serial.begin(19200);
  randomSeed(analogRead(0));

  readMemory = true;
}

void loop()
{
  if(readMemory)
  {
    readMemoryLocations(100);
    readMemory = false;
  }
}



I wanted to write info at address (2) then address (3) but after looking at the output of what I got back I am thinking that this is not how its done because I will overwrite my data that's already there.  How do you calculate how much data you are storing, and how much you need to advance to another memory location before trying to write different values.


Thanks.

lastchancename

#1
Feb 09, 2019, 10:52 pm Last Edit: Feb 10, 2019, 01:35 am by lastchancename
At a quick glance, you're doing ok, but forgot that ints are two bytes long.

A neat trick when using EEPROM is to calculate your target address requirements with sizeof(). That way, you can derive your target address, and the space required for each stored variable.

It takes a little more thinking - or you can simply assign hard addresses for each variable,  but that can stymie flexibility and growth in the future.
Experienced responders have a nose for laziness, (they were beginners once)... Sure, there are trolls, chest-beaters, and pretenders - but the help you'll get here is about as good as it gets - if you try to help youself!.

UKHeliBob

Quote
I wanted to write info at address (2) then address (3)
You can do that, but bear in mins that EEPROM.write() writes only one byte.  You have declared zz as an int (2 bytes) then you write it to successive EEPROM locations each of a single byte.  Can you see the problem ?

EEPROM.put()/get() will allow you to write/read data of any kind but as you suggest you need to know how much to advance the index variable to avoid overwriting previously written data and where to start reading.  Each data type takes a fixed number of bytes but you can always use the sizeof() function to determine how many bytes a variable needs in the EEPROM

The bottom line is that you have control of the data written to EEPROM and are responsible for preventing overwriting previous data.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

JohnRandalls

I was playing around with this, I thought I had it but I cant get to the 3rd record when I do a read.  Before I go on, is this the way to store multiple records?  I want to store maybe 5-10 pages as the data is collected which can be random and not all at the same time.

Also, reading the info back in is a no go when on the third page.  I cant seem to advance correctly when I get to the 3rd page, I know I had seen an example sometime ago on how to concat the values to advance but I dont remember.

Code: [Select]
#include <EEPROM.h>

struct MyObject
{
  char field1[13];
  int field2;
  char name[9];
};

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

MyObject customVar2 =
{
  "Testing-This",
  99,
  "Working!"
};

MyObject customVar3 =
{
  "Third test..",
  11,
  "Work!!!!"
};

bool writeValue = false;
bool readValue = false;
int eeAddress = 0;   //Location we want the data to be put.

void writeToEEprom()
{
  Serial.println("Writing Custom data type to eeprom!");
  EEPROM.put(eeAddress, customVar);
  Serial.print("eeAddress: ");
  Serial.println(eeAddress);
  Serial.println("customVar written to eeprom...");
  Serial.println("");

  eeAddress += sizeof(customVar); //Move address to the next byte Data store.
  Serial.println("Writing Custom data type to eeprom!");
  EEPROM.put(eeAddress, customVar2);
  Serial.print("eeAddress: ");
  Serial.println(eeAddress);
  Serial.println("customVar2 written to eeprom...");
  Serial.println("");

  eeAddress += sizeof(customVar2); //Move address to the next byte Data store.
  Serial.println("Writing Custom data type to eeprom!");
  EEPROM.put(eeAddress, customVar3);
  Serial.print("eeAddress: ");
  Serial.println(eeAddress);
  Serial.println("customVar3 written to eeprom...");
}

void readEEProm()
{
  MyObject customRet;
  Serial.println("Reading data from EEPROM: ");
  EEPROM.get(eeAddress, customRet);
  Serial.print("eeAddress: ");
  Serial.println(eeAddress);
  Serial.println(customRet.field1);
  Serial.println(customRet.field2);
  Serial.println(customRet.name);
  Serial.println("");

  eeAddress = sizeof(customRet); //Move address to the next byte
  Serial.println("Reading data from EEPROM: ");
  EEPROM.get(eeAddress, customRet);
  Serial.print("eeAddress: ");
  Serial.println(eeAddress);
  Serial.println(customRet.field1);
  Serial.println(customRet.field2);
  Serial.println(customRet.name); 
  Serial.println("");

  eeAddress = sizeof(customRet); //Move address to the next byte
  Serial.println("Reading data from EEPROM: ");
  EEPROM.get(eeAddress, customRet);
  Serial.print("eeAddress: ");
  Serial.println(eeAddress);
  Serial.println(customRet.field1);
  Serial.println(customRet.field2);
  Serial.println(customRet.name);
  Serial.println("");
}

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

//  writeValue = true;
  readValue = true;
}

void loop()
{   
  if(writeValue)
  {
    writeToEEprom();
    writeValue = false;
  //  readValue = true;
  }
  if(readValue)
  {
    readEEProm();
    readValue = false;
  }
}

cattledog

Notice how that when you write the eeprom you increment the address
Code: [Select]
eeAddress += sizeof(customVar);
eeAddress += sizeof(customVar2);


When you read, you appear to want the data in reverse order, but you do not use an
eeAddress -= construct.

JohnRandalls

Oh man, I can't believe that I didn't notice that I left out the += from each line, it works as expectd now.  The += is what I needed as I am pulling the data from the beginning then moving on.  Thanks for pointing that out.

Is there a more efficient way to write and retrieve from eeprom using arrays etc?  I haven't seen any examples of people pulling multiple pages of structs using sort of a loop.  My way here is the rookie way, save one page at a time then get confused later on.


Notice how that when you write the eeprom you increment the address
Code: [Select]
eeAddress += sizeof(customVar);
eeAddress += sizeof(customVar2);


When you read, you appear to want the data in reverse order, but you do not use an
eeAddress -= construct.

Notice how that when you write the eeprom you increment the address
Code: [Select]
eeAddress += sizeof(customVar);
eeAddress += sizeof(customVar2);


When you read, you appear to want the data in reverse order, but you do not use an
eeAddress -= construct.


lastchancename

Try these snippets -
Not tested - but the idea is there - I may have missed something

Code: [Select]
// =============================
struct MyObject
{
  char field1[13];
  int field2;
  char name[9];
};

#define NUM_MEMBERS 3
MyObject customVar[NUM_MEMBERS];

customVar[0] = { "SledgeHammer", 65, "Working!" };
customVar[1] = { "Testing-This", 99, "Working!" };
customVar[2] = { "Third test..", 11, "Work!!!!" };

// =============================
// save the WHOLE array of structs
EEPROM.put(eeAddress, customVar);

// =============================
//  to update a SINGLE member
MyObject aMember;
int myMember = 2;
aMember = { "Testing-This", 99, "Working!" };
EEPROM.put(eeAddress + (myMember * sizeof(aMember)), aMember);


// =============================
// to read ALL members
MyObject aMember;
for (int member = 0; member < NUM_MEMBERS; member++) {
 EEPROM.get(eeAddress + (member * sizeof(aMember)), aMember);
 Serial.print(aMember.field1); Serial.print(' ');
 Serial.print(aMember.field2. DEC); Serial.print(' ');
 Serial.println(aMember.name);
}
((or you could simply GET the chunk into a target array the same way as PUT above))

// =============================
// to read a SINGLE member
MyObject aMember;
int myMember = 2;
EEPROM.get(eeAddress + (myMember * sizeof(aMember)), aMember);
Serial.print(aMember.field1); Serial.print(' ');
Serial.print(aMember.field2. DEC); Serial.print(' ');
Serial.println(aMember.name);

Experienced responders have a nose for laziness, (they were beginners once)... Sure, there are trolls, chest-beaters, and pretenders - but the help you'll get here is about as good as it gets - if you try to help youself!.

JohnRandalls

This is definitely worth a shot, Thanks a lot.


Try these snippets -
Not tested - but the idea is there - I may have missed something

johnwasser

This is what I am writing to address 2 in eeprom
Code: [Select]
struct saveConfig
{
  int saved1 = 1;
  int saved2 = 2;
  int saved3 = 2;
  int saved4 = 0;
  int saved5 = 0;
  int saved5 = 4500;
} config;


This is what I see when I check the positions.
Code: [Select]
EEPROM position: 0 contains 0
EEPROM position: 1 contains 0
EEPROM position: 2 contains 1
EEPROM position: 3 contains 0
EEPROM position: 4 contains 2
EEPROM position: 5 contains 0
EEPROM position: 6 contains 2
EEPROM position: 7 contains 0
EEPROM position: 8 contains 1
EEPROM position: 9 contains 0
EEPROM position: 10 contains 0
EEPROM position: 11 contains 0
EEPROM position: 12 contains 194
EEPROM position: 13 contains 1
EEPROM position: 14 contains 0

You show the code you use to read the data but you didn't show the code you used to write the data.  Did you use EEPROM.put(2, config) or did you use some function you wrote?
The data doesn't look right.  
Code: [Select]

EEPROM position: 0 contains 0 (outside your data)
EEPROM position: 1 contains 0 (outside your data)
EEPROM position: 2 contains 1 . (Should be 0)
EEPROM position: 3 contains 0 . (Should be 1)
EEPROM position: 4 contains 2 . (Should be 0)
EEPROM position: 5 contains 0 . (Should be 2)
EEPROM position: 6 contains 2 . (Should be 0)
EEPROM position: 7 contains 0 . (Should be 2)
EEPROM position: 8 contains 1 . (Should be 0)
EEPROM position: 9 contains 0
EEPROM position: 10 contains 0
EEPROM position: 11 contains 0
EEPROM position: 12 contains 194 . (Should be 17 (0x11))
EEPROM position: 13 contains 1 . (Should be 148 (0x94))
EEPROM position: 14 contains 0 (outside your data)
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

JohnRandalls

Hi John,

When I asked the question I was trying to figure out how much data I can post in one eeprom address without overwriting or overlapping into the same area.  I posted some random info and the code that I posted was to read how far down the data went so I would begin to understand how the data takes up space.

Once lastchancename and UKHeliBob chimed I tried using the sizeof() and that pretty much answered my question so I started doing another test just writing structs and see how much space is taken when using the sizeof().

I still would like to be able to do what you did and calculate exactly how much space I will be using before I even compile the code.


You show the code you use to read the data but you didn't show the code you used to write the data.  Did you use EEPROM.put(2, config) or did you use some function you wrote?
The data doesn't look right. 


Go Up