Brent Brown
2017-12-11 00:52:06 UTC
Hi all,
I have a math problem that is a little interesting. Background first: I'm storing
"operating hours" in internal EEPROM on a PIC16F887. It's in a product I've been
making for some time, but despite my best efforts so far the hours counter
occasionally gets corrupted. I suspect the biggest problem is writing to EEPROM in
a "dying gasp" when power supply falls, with simply not enough time to reliably do
so.
A new scheme is planned. Hours increment in units 0.01hr (36s) up to 9999.99,
then roll over to 0. On each increment it will be stored in a different EEPROM
location. This addresses three issues 1) the byte endurance of EEPROM (1M typ
but 100k guaranteed), 2) ability to retrieve a previous record if corruption is
detected, loosing as little as 36 seconds (fairly insignificant), and 3) no longer
writing to EEPROM as power fails.
I plan to encode the number essentially as 6 x BCD digits, 1 digit per byte. I take the
BCD value, add 3 to it (avoids 0 being a valid code), shift to upper nibble, and write
the inverted value into the lower nibble. This results in 10 symbols for numbers 0-9
as follows: 0x3C, 0x4B, 0x5A, 0x69, 0x78, 0x87, 0x96, 0xA5, 0xB4, 0xC3.
Corruption in a digit is detected when a byte does not equate to one of the valid
symbols (10 valid 8 bit codes out of 256). In addition I'll add a checksum. Preferably
I'd like the checksum to never equal FF, as that is the "erased" value of EEPROM, I
will also use that as a "start of record" marker. Thus a complete record will be 8
bytes:
start_record, digit1, digit2, digit3, digit4, digit5, digit6, checksum
Example: (0000.01 hours)
0xFF, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x4B, 0x77
My curious math question is can the checksum ever be 0xFF? It's complicated by
the values I'm using for the symbols, and the checksum being the LS 8 bits of the
sum.
Simplifying the symbols back to decimal values the question becomes: in the
sequence 000000 - 999999 what are all the possible values for the sum of digits?
One can see fairly easily that the minimum would be 0+0+0+0+0+0=0, the
maximum would be 9+9+9+9+9+9=54. Also: there are 1 million possible sums
(10^6), all will be in the range 0-54 (9*6), all integer values will be covered as the
step size is 1, and there will be many identical results.
Wondering if/how I could solve this mathematically. I did make a spreadsheet with
1000 rows to calculate the sums of digits from 000-999 and graphed the results in a
histogram. 1,000,000 rows is possible in Excel, but takes a bit of time, working on
that now. Interestingly, the 1000 row spreadsheet showed sum of digits covered all
values from 0-27, as expected, and the distribution of values is a bell curve.
I can of course work around and allow for the checksum being 0xFF, or change the
value if/when it ever does match 0xFF, but still curious to know if it is necessary.
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
I have a math problem that is a little interesting. Background first: I'm storing
"operating hours" in internal EEPROM on a PIC16F887. It's in a product I've been
making for some time, but despite my best efforts so far the hours counter
occasionally gets corrupted. I suspect the biggest problem is writing to EEPROM in
a "dying gasp" when power supply falls, with simply not enough time to reliably do
so.
A new scheme is planned. Hours increment in units 0.01hr (36s) up to 9999.99,
then roll over to 0. On each increment it will be stored in a different EEPROM
location. This addresses three issues 1) the byte endurance of EEPROM (1M typ
but 100k guaranteed), 2) ability to retrieve a previous record if corruption is
detected, loosing as little as 36 seconds (fairly insignificant), and 3) no longer
writing to EEPROM as power fails.
I plan to encode the number essentially as 6 x BCD digits, 1 digit per byte. I take the
BCD value, add 3 to it (avoids 0 being a valid code), shift to upper nibble, and write
the inverted value into the lower nibble. This results in 10 symbols for numbers 0-9
as follows: 0x3C, 0x4B, 0x5A, 0x69, 0x78, 0x87, 0x96, 0xA5, 0xB4, 0xC3.
Corruption in a digit is detected when a byte does not equate to one of the valid
symbols (10 valid 8 bit codes out of 256). In addition I'll add a checksum. Preferably
I'd like the checksum to never equal FF, as that is the "erased" value of EEPROM, I
will also use that as a "start of record" marker. Thus a complete record will be 8
bytes:
start_record, digit1, digit2, digit3, digit4, digit5, digit6, checksum
Example: (0000.01 hours)
0xFF, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x4B, 0x77
My curious math question is can the checksum ever be 0xFF? It's complicated by
the values I'm using for the symbols, and the checksum being the LS 8 bits of the
sum.
Simplifying the symbols back to decimal values the question becomes: in the
sequence 000000 - 999999 what are all the possible values for the sum of digits?
One can see fairly easily that the minimum would be 0+0+0+0+0+0=0, the
maximum would be 9+9+9+9+9+9=54. Also: there are 1 million possible sums
(10^6), all will be in the range 0-54 (9*6), all integer values will be covered as the
step size is 1, and there will be many identical results.
Wondering if/how I could solve this mathematically. I did make a spreadsheet with
1000 rows to calculate the sums of digits from 000-999 and graphed the results in a
histogram. 1,000,000 rows is possible in Excel, but takes a bit of time, working on
that now. Interestingly, the 1000 row spreadsheet showed sum of digits covered all
values from 0-27, as expected, and the distribution of values is a bell curve.
I can of course work around and allow for the checksum being 0xFF, or change the
value if/when it ever does match 0xFF, but still curious to know if it is necessary.
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist