Your comment on the servicing reminded me of something that I normally do o= n this type of product: I maintain time like items as a running total from 0 and separately record what time 0 is. In your case, if the during servicing they failed to transfer the running time to the new unit, that could be rectified when that was subsequently discovered assuming of course that there was a paper record of the device swap. The display then become adding the running time plus the starting offset or base time. And if default offset is 0xffff.. rather than 0 then failing to initialize the device is evident. -----Original Message----- From: piclist-bounces@mit.edu [mailto:piclist-bounces@mit.edu] On Behalf Of Brent Brown Sent: Tuesday, December 12, 2017 15:20 To: Microcontroller discussion list - Public. Subject: Re: [PIC] Sum of digits On 12 Dec 2017 at 11:31, Isaac M. Bavaresco wrote: > The mechanism of the sequence count works differently than the time=20 > roll-over. >=20 > With two bytes you will have 65536 possible values, but your EEPROM=20 > memory has room for, say, 128 records. >=20 > So if any record has sequence number more than 128 counts AHEAD of the=20 > one you have, it is older. We could increase (double it, for instance)=20 > this threshold to account for some lost record in-between. >=20 > You compare sequence numbers by subtracting them and doing an unsigned > compare: >=20 > if( (uint16_t)( Seq2 - Seq1 ) < THRESHOLD ) > =A0=A0=A0 { > =A0=A0=A0 /* Record with sequence Seq2 is newer than record with sequence= =20 > Seq1 */ > =A0=A0=A0 } >=20 > This method takes care of roll-over, you will never need to check for=20 > overflow. >=20 > Example: >=20 > #define THRESHOLD=A0=A0=A0 256 >=20 > int=A0=A0=A0 NewestRecord=A0=A0=A0 =3D -1; > for( int i =3D 0; i < NumRecords; i++ ) > =A0=A0=A0 { > =A0=A0=A0 if( ValidateRecord( i )) > =A0=A0=A0 =A0=A0=A0 { > =A0=A0=A0 =A0=A0=A0 if( NewestRecord < 0 || (uint16_t)( GetSequence( i ) = -=20 > GetSequence( NewestRecord )) < THRESHOLD ) > =A0=A0=A0 =A0=A0=A0 =A0=A0=A0 NewestRecord=A0=A0=A0 =3D i; > =A0=A0=A0 =A0=A0=A0 } > =A0=A0=A0 } >=20 > if( NewestRecord < 0 ) > =A0=A0=A0 { > =A0=A0=A0 /* There is no valid record. */ > =A0=A0=A0 } > else > =A0=A0=A0 { > =A0=A0=A0 /* This is the record with the latest saved value. */ > =A0=A0=A0 } >=20 Ok, cool, I see how that works, nice. For that matter though it is conceivable that the record counter and the hours counter could be the same thing. Kind of what I was thinking all alon= g but probably never spelled it out. Count increments by a value of one each time interval, store record in next EEPROM location(s). At power up find th= e highest record number/hours count using the method you descibe. The only slight challenge I will have, and not mentioned previously, is tha= t a service person has access to change the engine hours count - for example when servicing a machine and swapping out this module. In that one and only case the "new" hours count could be lower than any of the "old" records stored in EEPROM, or "ahead"=20 by more than the number of records stored. The solution would be to delete, or mark as invalid, all the old values at that time. I don't like to have code that does this, with the chance that it could run errantly, but conced= e it may be necessary. I have safeguards in place to reduce the chances of th= e service person routines being accessed improperly. -- Electronic Design Solutions 9 Titoki Place, Pukete Hamilton 3200, New Zealand P: +64 7 849 0069 M: +64 27 433 4069 -- http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/chang= e your membership options at http://mailman.mit.edu/mailman/listinfo/piclist --=20 http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .