I bought two of these recently. What is the default setup for the eeprom in these boards, as sold by yourselves?
We're trying to figure out how to detect an 'unused' eeprom in order to load the relevant values into a program, either from sketch defaults or the eeprom, depending if the eeprom already has something usable in it or not.
It would probably be faster to find the answer if you has written a small test sketch to read the eeprom cells and find the answer yourself
Anyway
I have used this example in the past to calculate the crc. Advantage is that it can also pick up eeprom corruption.
I used the last 4 locations of the eeprom to store the calculated CRC; the for-loop needs to end at EEPROM.length() -4.
Below a simple demo to demonstrate
#include <EEPROM.h>
void setup()
{
Serial.begin(57600);
Serial.print("EEPROM length: ");
Serial.println(EEPROM.length());
// calculate CRC over eeprom (eeprom.length - 4 bytes)
unsigned long calculatedCrc = eeprom_crc();
Serial.print("calculated CRC32 of EEPROM data: 0x");
Serial.println(calculatedCrc, HEX);
// get stored crc
unsigned long storedCrc;
EEPROM.get(EEPROM.length() - 4, storedCrc);
Serial.print("stored CRC32 of EEPROM data: 0x");
Serial.println(storedCrc, HEX);
// check for eeprom 'corruption'
if (storedCrc != calculatedCrc)
{
// save something
float pi = 3.14;
EEPROM.put(0, pi);
Serial.println("Initial values stored in EEPROM");
//calculate CRC over eeprom
calculatedCrc = eeprom_crc();
Serial.print("calculated CRC32 of EEPROM data: 0x");
Serial.println(calculatedCrc, HEX);
// save calculated CRC to eeprom
EEPROM.put(EEPROM.length() - 4, calculatedCrc);
Serial.println("CRC saved to EEPROM");
}
else
{
Serial.println("EEPROM OK");
}
Serial.print("\n\nDone!");
}
void loop()
{
}
unsigned long eeprom_crc(void)
{
const unsigned long crc_table[16] =
{
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
unsigned long crc = ~0L;
for (int index = 0 ; index < EEPROM.length() - 4 ; ++index)
{
crc = crc_table[(crc ^ EEPROM[index]) & 0x0f] ^ (crc >> 4);
crc = crc_table[(crc ^ (EEPROM[index] >> 4)) & 0x0f] ^ (crc >> 4);
crc = ~crc;
}
return crc;
}
The first time that you run it, it will update the eeprom because the calculated CRC and the stored CRC don't match. The second time that you run it, the CRCs should match and you will see the message that the eeprom is OK.
I thought the Arduino Uno started putting a serial number in the first few bytes of EEPROM?
Did they stop doing that?
In any case, if you have an application that you want to have check whether it has already put stuff in EEPROM, the thing to do is to put some "magic numbers" in there, and perhaps a "proprietary" checksum of your significant data fields.
struct my_eeprom_data EEMEM {
uint32_t magicNumber;
uint16_t checksum;
uint8_t eedatat[100];
};
void initializeEEPROM() {
if (eeprom_read_dword(&my_eeprom_data.magicnumber == 0xDEADBEEF) {
if (eeprom_read_word(&my_eeprom_data.checksum) == do_checksum(&my_eeprom_data.checksum, 100))
// EEPROM is already initialized and looks good.
return;
}
// EEPROM is not initialized, or bad. Initialize it.
for (int i=0; i<100;i++)
eeprom_write_byte(&my_eeprom_data.data[i], 0);
eeprom_write_word(&my_eeprom_data.checksum, do_checksum(&my_eeprom_data.checksum, 100));
eeprom_write_dword(&my_eeprom_data.magicnumber, 0xDEADBEEF);
// NOW eeprom is initialized!
}}