I have a pointer pointing to a custom structure. Is it possible to use pointer in EEPROM.get and EEPROM.put to save/read the target structure?
#include <EEPROM.h>
struct entry {
int time;
int value;
};
void setup() {
Serial.begin(9600);
struct entry abc[10];
struct entry *ptr;
ptr = &abc[0];
struct entry def[10];
struct entry *ptr2;
ptr2 = &def[0];
for ( int i = 0; i < 10; i++ )
{
abc[i].time = i;
abc[i].value = i+1;
}
for ( int j = 0; j < 10; j++ )
{
Serial.print(ptr[j].time);
Serial.print(" ");
Serial.println(ptr[j].value);
}
Serial.println();
Serial.println();
EEPROM.put(3900, *ptr);
EEPROM.get(3900, *ptr2);
for ( int k = 0; k < 10; k++ )
{
Serial.print(ptr2[k].time);
Serial.print(" ");
Serial.println(ptr2[k].value);
}
Serial.println();
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
}
No you cannot have a pointer into EEPROM and it makes little sense to store a pointer in EEPROM.
Mark
I'm hoping I can save the array of structure being pointed to not the address of the first element of the array of struct
EEPROM.put(3900, *ptr);
what platform are you using?
Arduino mega. I think it has 4096 bytes of eeprom?
dandelionclock:
Arduino mega. I think it has 4096 bytes of eeprom?
OK, just checking.
So you certainly may dereference a pointer and put that information into EEPROM.
#include <EEPROM.h>
const char* animlTxt[] = {"Monkey", "Llama", "Chicken", "Tiger"};
enum Species{
MONKEY,
LLAMA,
CHICKEN,
TIGER
};
struct Animal{
Species species;
int numLegs;
};
Animal myAnimal = {LLAMA, 2};
void setup()
{
Serial.begin(9600);
Animal* ptr;
ptr = &myAnimal;
EEPROM.put(0, *ptr);
}
void loop()
{
Animal myPet;
EEPROM.get(0,myPet);
Serial.println(animlTxt[myPet.species]);
delay(5000);
}
Thanks. However it doesn't seem to work if it is an array of a custom struct? It seems like only the first element is saved to EEPROM. Below is the output of my code. I could change the value assignment and EEPROM.get will get the first element right, but everything else will be wrong.
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
0 1
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 1
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
Basically what I am doing is to be able to switch between using EEPROM and global variable just by changing a flag ( e.g. useGlobal = 1 or 0 ). I'm hoping to use global variable just when I am debugging the program to reduce wear on my EEPROM. By using a pointer I only need to add a condition at the beginning of the function whether to read (and write) from EEPROM to the struct array pointed by the pointer, or simply point the pointer to the global variable.
By slightly editing your code to make myAnimal and myPet arrays with 2 elements,
#include <EEPROM.h>
const char* animlTxt[] = {"Monkey", "Llama", "Chicken", "Tiger"};
enum Species{
MONKEY,
LLAMA,
CHICKEN,
TIGER
};
struct Animal{
Species species;
int numLegs;
};
Animal myAnimal[2] = { {LLAMA, 2}, {MONKEY, 2} };
void setup()
{
Serial.begin(9600);
Animal* ptr;
ptr = &myAnimal[0];
EEPROM.put(0, *ptr);
}
void loop()
{
Animal myPet[2];
EEPROM.get(0,myPet);
Serial.println(animlTxt[myPet[0].species]);
Serial.println(animlTxt[myPet[1].species]);
delay(5000);
}
this is the output I got:
Llama
�����%
Llama
�����%
BulldogLowell:
OK, just checking.
So you certainly may dereference a pointer and put that information into EEPROM.
dandelionclock:
It seems like only the first element is saved to EEPROM.
You could just traverse the array and save each element... careful to index accordingly.
#include <EEPROM.h>
const char* animlTxt[] = {"Monkey", "Llama", "Chicken", "Tiger"};
enum Species{
MONKEY,
LLAMA,
CHICKEN,
TIGER
};
struct Animal{
Species species;
int numLegs;
};
Animal myAnimals[] = {{LLAMA, 4}, {CHICKEN, 2}, {TIGER, 4}};
void setup()
{
Serial.begin(9600);
Animal* ptr[sizeof(sizeof(myAnimals)/sizeof(myAnimals[0]))];
for(int i = 0; i < sizeof(myAnimals)/sizeof(myAnimals[0]); i++)
{
ptr[i] = &myAnimals[i];
EEPROM.put(i * sizeof(myAnimals), *ptr[i]);
}
// Animal* ptr;
// ptr = &myAnimal;
// EEPROM.put(0, *ptr);
}
void loop()
{
Animal myPets[sizeof(myAnimals)/sizeof(myAnimals[0])];
for(int i = 0; i < sizeof(myAnimals)/sizeof(myAnimals[0]); i++)
{
EEPROM.get(i * sizeof(myAnimals), myPets[i]);
}
for(int i = 0; i < sizeof(myAnimals)/sizeof(myAnimals[0]); i++)
{
Serial.println(animlTxt[myPets[i].species]);
}
// Animal myPet;
// EEPROM.get(0,myPet);
// Serial.println(animlTxt[myPet.species]);
delay(5000);
}
Thanks! That would make it rather clumsy so I may just have to write my code a different way 
I thought the beauty of pointer is that when it's mapped to the n'th element of an array, dereferencing pointer+sizeof(element) would point to n+1th element? Through trial and error it seems like arduino knew how to interpret pointer[n] as pointer+n*sizeof(element) when in SRAM but maybe not in the EEPROM library?
BulldogLowell:
You could just traverse the array and save each element... careful to index accordingly.
#include <EEPROM.h>
const char* animlTxt[] = {"Monkey", "Llama", "Chicken", "Tiger"};
enum Species{
MONKEY,
LLAMA,
CHICKEN,
TIGER
};
struct Animal{
Species species;
int numLegs;
};
Animal myAnimals[] = {{LLAMA, 4}, {CHICKEN, 2}, {TIGER, 4}};
void setup()
{
Serial.begin(9600);
Animal* ptr[sizeof(sizeof(myAnimals)/sizeof(myAnimals[0]))];
for(int i = 0; i < sizeof(myAnimals)/sizeof(myAnimals[0]); i++)
{
ptr[i] = &myAnimals[i];
EEPROM.put(i * sizeof(myAnimals), ptr[i]);
}
// Animal ptr;
// ptr = &myAnimal;
// EEPROM.put(0, *ptr);
}
void loop()
{
Animal myPets[sizeof(myAnimals)/sizeof(myAnimals[0])];
for(int i = 0; i < sizeof(myAnimals)/sizeof(myAnimals[0]); i++)
{
EEPROM.get(i * sizeof(myAnimals), myPets[i]);
}
for(int i = 0; i < sizeof(myAnimals)/sizeof(myAnimals[0]); i++)
{
Serial.println(animlTxt[myPets[i].species]);
}
// Animal myPet;
// EEPROM.get(0,myPet);
// Serial.println(animlTxt[myPet.species]);
delay(5000);
}
dandelionclock:
I thought the beauty of pointer is that when it's mapped to the n'th element of an array, dereferencing pointer+sizeof(element) would point to n+1th element?
...but maybe not in the EEPROM library?
yep, pointer math is really the power of C!
in EEPROM you are dealing with simple addresses, not pointers.
in your Mega, you have 4096 slots which each contain a byte. The EEPROM library does a nice job of storing a struct, but it is up to the programmer to manage accessing the data from the addresses (hence the comment "careful to index accordingly").
Thanks for the help! That saved me from spending hours figuring out what's wrong when it's simply a dead end.
I'm a newbie to pointers. Just when I thought I have a good use of it I ran into trouble.