EEPROM.read not reading the correct data
We have an application which will burn 7 bytes of data into EEPROM during a calibration sequence. The 7th byte is a checksum of bytes 1 through 6.
When the system boots and when certain code executes, the values 1 through 6 are read and compared to the checksum. If this fails, the javelin reports a failure to the pc.
This will work very well for months. However, after a while, the checksum will fail. The data values in bytes 1 through 6 continue to report the same values as when burned, but the checksum check fails. To correct this, we have to run the calibration again and re-burn the checksum.
The program isn't being re-burnt, the javelin is in continuous operation. The EEPROM is being read every few seconds and will pass for months, but then as some point, that one address fails.
No, I do not know what the data changes to. The PC prints out the values for EEPROM address 1 through 6, but it doesn't print out the checksum.
Is there any reason for the 7th byte to change?
static boolean RefreshABS()
{
ABS_SPSUM.set(0);
ABS_SPNUM = 0;
bABSSampling = true;
int ABS_CHSUM = EEPROM.read(1) + EEPROM.read(2) +
EEPROM.read(3) + EEPROM.read(4) +
EEPROM.read(5) + EEPROM.read(6);
if ((ABS_CHSUM & 0xFF) != EEPROM.read(7))
{
errorNum = ErrorEEPROM;
ABS_SP = 602; /*1470[noparse][[/noparse]mV]*/
ABS_OFFSET = 1092; /*2000[noparse][[/noparse]mV]*/
ABS_GAIN = 16; /* 1.0 */
return false;
}
else
{
ABS_SP = EEPROM.read(1) | (EEPROM.read(2) << 8);
ABS_OFFSET = EEPROM.read(3) | (EEPROM.read(4) << 8);
ABS_GAIN = EEPROM.read(5) | (EEPROM.read(6) << 8);
return true;
}
}
static boolean SaveABS()
{
//ABS_SP sampling
if (ABS_SPNUM != 0)
{
ABS_SPSUM.divide(ABS_SPNUM);
ABS_SP = ABS_SPSUM.low;
ABS_SPSUM.set(0);
ABS_SPNUM = 0;
bABSSampling = true;
}
EEPROM.write(1, (byte)(ABS_SP & 0xFF));
EEPROM.write(2, (byte)(ABS_SP >> 8));
EEPROM.write(3, (byte)(ABS_OFFSET & 0xFF));
EEPROM.write(4, (byte)(ABS_OFFSET >> 8));
EEPROM.write(5, (byte)(ABS_GAIN & 0xFF));
EEPROM.write(6, (byte)(ABS_GAIN >> 8));
EEPROM.write(7, (byte)(((ABS_SP & 0xFF) + (ABS_SP >> 8) +
(ABS_OFFSET & 0xFF) + (ABS_OFFSET >> 8) +
(ABS_GAIN & 0xFF) + (ABS_GAIN >> 8)) & 0xFF));
return RefreshABS();
}
When the system boots and when certain code executes, the values 1 through 6 are read and compared to the checksum. If this fails, the javelin reports a failure to the pc.
This will work very well for months. However, after a while, the checksum will fail. The data values in bytes 1 through 6 continue to report the same values as when burned, but the checksum check fails. To correct this, we have to run the calibration again and re-burn the checksum.
The program isn't being re-burnt, the javelin is in continuous operation. The EEPROM is being read every few seconds and will pass for months, but then as some point, that one address fails.
No, I do not know what the data changes to. The PC prints out the values for EEPROM address 1 through 6, but it doesn't print out the checksum.
Is there any reason for the 7th byte to change?
static boolean RefreshABS()
{
ABS_SPSUM.set(0);
ABS_SPNUM = 0;
bABSSampling = true;
int ABS_CHSUM = EEPROM.read(1) + EEPROM.read(2) +
EEPROM.read(3) + EEPROM.read(4) +
EEPROM.read(5) + EEPROM.read(6);
if ((ABS_CHSUM & 0xFF) != EEPROM.read(7))
{
errorNum = ErrorEEPROM;
ABS_SP = 602; /*1470[noparse][[/noparse]mV]*/
ABS_OFFSET = 1092; /*2000[noparse][[/noparse]mV]*/
ABS_GAIN = 16; /* 1.0 */
return false;
}
else
{
ABS_SP = EEPROM.read(1) | (EEPROM.read(2) << 8);
ABS_OFFSET = EEPROM.read(3) | (EEPROM.read(4) << 8);
ABS_GAIN = EEPROM.read(5) | (EEPROM.read(6) << 8);
return true;
}
}
static boolean SaveABS()
{
//ABS_SP sampling
if (ABS_SPNUM != 0)
{
ABS_SPSUM.divide(ABS_SPNUM);
ABS_SP = ABS_SPSUM.low;
ABS_SPSUM.set(0);
ABS_SPNUM = 0;
bABSSampling = true;
}
EEPROM.write(1, (byte)(ABS_SP & 0xFF));
EEPROM.write(2, (byte)(ABS_SP >> 8));
EEPROM.write(3, (byte)(ABS_OFFSET & 0xFF));
EEPROM.write(4, (byte)(ABS_OFFSET >> 8));
EEPROM.write(5, (byte)(ABS_GAIN & 0xFF));
EEPROM.write(6, (byte)(ABS_GAIN >> 8));
EEPROM.write(7, (byte)(((ABS_SP & 0xFF) + (ABS_SP >> 8) +
(ABS_OFFSET & 0xFF) + (ABS_OFFSET >> 8) +
(ABS_GAIN & 0xFF) + (ABS_GAIN >> 8)) & 0xFF));
return RefreshABS();
}
Comments
An EEPROM has only a limited lifetime based on the number of times you are writing on it. So if you are writing on it every 3 secondes for the past 6 months, that mean you did 5,184,000 write operations.
Based on EEPROM documentation (http://www.parallax.com/Portals/0/Downloads/docs/prod/oem/24LC256.pdf), specification are 1,000,000 erase/write cycles.
So you are lucky because your EEPROM lasted more than 5 time the specifications [noparse];)[/noparse] But know, it's burned.
Did you try replacing your EEPROM with a new one? If you are using the internal Javelin EEPROM, I think you will have to replace your entire Javelin by a new one.
JMS
The reading of the EEPROM shouldn't be an issue.
Data retention is > 200 years. So values should still be readable. Did you try to read each byte and compare it to what you are exectping in order to see which one is wrong? Are they all wrong? Only one? Is everything at 0? Did you try to re-write the values and test the read again? Just some ideas.
JMS
Bytes 0 through 6 though are always correct, it is just byte 7 that is in error. That is what is so odd. There is about no way a particular byte can be fautly on about 20 different Javelin chips. We have about 20 systems running this code and many have experienced this fault at some point. Does the Javelin ever use the EEPROM for anything outside of holding the program? Also, when doing an EEPROM.read does it always go to the EEPROM or by any chance will the operating system say, "hey I have that value in RAM from a previous read, let me grab it from RAM instead?
Thanks
GJ
Particularly with a variable argument? If that argument is to become
7 (for whatever reason) it will overwrite your checksum.
regards peter
Is there any history of the Javelin having EEPROM issues or read issues related to the EEPROM?
so it is likely there is another cause.
Question is, how did you assume the eeprom would be bad? Just the report of
the error number? In that case I would check the code to see if errNum could be
loaded with value ErrorEEPROM anywhere else.
regards peter