Say i have a huge array of integers (63x63), obviously it is causing memory problems for the RAM of my arduino (Mega 2560). Is there a way I can save the data into EEPROM and retrieve it later when I need to modify it?
nayfaan:
Say i have a huge array of integers (63x63), obviously it is causing memory problems for the RAM of my arduino (Mega 2560). Is there a way I can save the data into EEPROM and retrieve it later when I need to modify it?
Sure. But if it is causing memory problems now, won't it cause memory problems when you retrieve it later?
Paul
But keep in mind that EEPROM is only rated for 100000 writes per cell. So if you need to frequently change that data you could quickly wear out the EEPROM. Also, keep in mind that writing to EEPROM is much slower than writing to SRAM.
If you don't need to change the array at run time then you should put it in flash using PROGMEM instead of using EEPROM. Actually it is possible to write to flash at run time if you install an unofficial bootloader but the flash memory is only rated for 10000 writes and I believe you have to write a page at a time.
Is there any pattern to the values in the array and what is the maximum value held in the array ?
For more context, posting snippet of my code
#include <EEPROM.h>
int loc[63][63] = {/*initializes values*/};
//Following 2 functions and setup quoted from [url=https://forum.arduino.cc/index.php?topic=258193.msg1825511#msg1825511]cattledog[/url]
void EEPROMWriteInt(int p_address, int p_value)
{
byte lowByte = ((p_value >> 0) & 0xFF);
byte highByte = ((p_value >> 8) & 0xFF);
EEPROM.write(p_address, lowByte);
EEPROM.write(p_address + 1, highByte);
}
unsigned int EEPROMReadInt(int p_address)
{
byte lowByte = EEPROM.read(p_address);
byte highByte = EEPROM.read(p_address + 1);
return ((lowByte << 0) & 0xFF) + ((highByte << 8)& 0xFF00);
}
void setup() {
int address;
Serial.println ("Writing data.....");
for(int j=0; j<63; j++){
Serial.println();
for(int i=0; i<63; i++){
EEPROMWriteInt(address= ((2*i)+(j*16)+50), loc[j][i]);//+50 to not start at 0
Serial.println(address);
}
}
Serial.println();
Serial.println();
Serial.println ("Reading data.....");
for(int j=0; j<63; j++){
Serial.println();
for(int i=0; i<63; i++){
unsigned int value= EEPROMReadInt(address=(2*i)+(j*16)+50);//+50 to not start at 0
Serial.print(address);
Serial.print('\t');
Serial.println(value,HEX);
}
}
}
Paul_KD7HB:
Sure. But if it is causing memory problems now, won't it cause memory problems when you retrieve it later?Paul
Yes, it does, that is why I am thinking of a way that would save some extra space... apparently I'm clueless D:
pert:
But keep in mind that EEPROM is only rated for 100000 writes per cell. So if you need to frequently change that data you could quickly wear out the EEPROM. Also, keep in mind that writing to EEPROM is much slower than writing to SRAM.If you don't need to change the array at run time then you should put it in flash using PROGMEM instead of using EEPROM. Actually it is possible to write to flash at run time if you install an unofficial bootloader but the flash memory is only rated for 10000 writes and I believe you have to write a page at a time.
Sadly I have to change the array during run time. I have already considered PROGMEM but it wasn't a constant.
Let's say read/write speed is not a problem at all, and I don't really care about the EEPROM wearing out (it's a school project...)
UKHeliBob:
Is there any pattern to the values in the array and what is the maximum value held in the array ?
Yes, i think it only ranges from like -5 to 1 or something similar
i think it only ranges from like -5 to 1 or something similar
If that is the range of values then use a byte array instead of an int, save a range between 0 and 7 and add/subtract an offset to get the actual value when you need to use it
[quote author=nayfaan link=msg=3933939 date=1541455135
Yes, it does, that is why I am thinking of a way that would save some extra space... apparently I'm clueless D:
[/quote]
The problem Paul_KD7HB mentioned would be if you needed to load the entire array from EEPROM into SRAM all at once. In that case, you're no better off than storing it in SRAM from the start. In fact, worse off because then you have all the overhead of the EEPROM code. But if you can work with portions of the data at a time then you won't have that problem.
nayfaan:
Yes, i think it only ranges from like -5 to 1 or something similar
That makes int a quite poor choice for your array, the given range would fit in three bits (or something similar).
UKHeliBob:
... then use a byte array instead of an int,
save a range between 0 and 7 and add/subtract an offset to get the actual value when you need to use it
A char array would require no additional computation.
UKHeliBob:
If that is the range of values then use a byte array instead of an int, save a range between 0 and 7 and add/subtract an offset to get the actual value when you need to use it
That is actually a good advice. However, for educational purposes, say if I want to do it with an integer, how do I do it?
pert:
[quote author=nayfaan link=msg=3933939 date=1541455135
Yes, it does, that is why I am thinking of a way that would save some extra space... apparently I'm clueless D:The problem Paul_KD7HB mentioned would be if you needed to load the entire array from EEPROM into SRAM all at once. In that case, you're no better off than storing it in SRAM from the start. In fact, worse off because then you have all the overhead of the EEPROM code. But if you can work with portions of the data at a time then you won't have that problem.
If i have to work with the entire array once at a time?
anyways, just writing the array into EEPROM with the code snippet I posted above already used up the SRAM memory, not to mention retrieving it and editing it.
Whandall:
That makes int a quite poor choice for your array, the given range would fit in three bits (or something similar).A char array would require no additional computation.
OK I'm not good with the programming... tell me more about the char array?
nayfaan:
OK I'm not good with the programming... tell me more about the char array?
int16_t integerArray[3][3]; // signed 16 bit
uint8_t byteArray[3][3]; // unsigned 8 bit
int8_t charArray[3][3]; // signed 8 bit
void setup() {
Serial.begin(250000);
}
void loop() {}
nayfaan:
say if I want to do it with an integer, how do I do it?
Certainly not with EEPROM. That array is 7938 bytes (63 * 63 * 2 bytes/int) and the ATmega2560 only has 4096 bytes of EEPROM.
nayfaan:
If i have to work with the entire array once at a time?
Yes. Meaning if you read the whole array from EEPROM and stored it in SRAM.
nayfaan:
anyways, just writing the array into EEPROM with the code snippet I posted above already used up the SRAM memory
Well, that's easily solved by putting it in flash memory instead of SRAM.