|
|
View previous topic :: View next topic |
Author |
Message |
mvaraujo
Joined: 20 Feb 2004 Posts: 59 Location: Brazil
|
Compressing timestamp to store in EEPROM |
Posted: Thu May 27, 2004 8:16 am |
|
|
Hi folks,
I need to store events information in a EEPROM and the timestamp is part of the data of these events. This timestamp is day (1-31), month (1-12), year (00-99) that is 2000 to 2099, hour (0-23), minutes (0-59), seconds (0-59).
If I try to build structure and put all this timestamp inside I get 33 bits, that is not reasonable. I would like to limit this data to 32bits only.
I've studied AN-517 from Maxim that explains how to convert date/time to 32 bits binary but the problem is that the algorithm rolls over in January, 2038 and I would like to keep the 2099 as the maximum.
Does anyone have something in mind that could help me solving this issue?
Thanks,
Marcus |
|
|
Gerrit
Joined: 15 Sep 2003 Posts: 58
|
|
Posted: Thu May 27, 2004 8:47 am |
|
|
He mvaraujo,
If you just offer 0ne bit from the year counter you are there 32 bits.
Your product could work 2063 -2004 = 59 year.
I do not think that is will last that time. And this is very simple.
Regards
Gerrit |
|
|
ThadSmith
Joined: 23 Feb 2004 Posts: 5 Location: Boulder, CO, USA
|
Re: Compressing timestamp to store in EEPROM |
Posted: Thu May 27, 2004 10:10 am |
|
|
mvaraujo wrote: | Hi folks,
I need to store events information in a EEPROM and the timestamp is part of the data of these events. This timestamp is day (1-31), month (1-12), year (00-99) that is 2000 to 2099, hour (0-23), minutes (0-59), seconds (0-59).
If I try to build structure and put all this timestamp inside I get 33 bits, that is not reasonable. I would like to limit this data to 32bits only.
|
If you multiply out the number of combinations, not trying to take into account the varying number of days in a month, you have 100*12*31*24*60*60 combinations, which fits in 32 bits. One option to simplify the math slightly is to combine the year, month, and hour to be a 15-bit value 0..28799, and use normal bit packing for the other fields.
Code: |
pack = ((y*12)+mo)*24+h;
|
To extract:
Code: |
h = pack % 24;
pack /= 24;
mo = pack % 12;
y = pack / 12;
|
where y=0..99, mo=0..11, h=0..23.
Thad |
|
|
Guest
|
Re: Compressing timestamp to store in EEPROM |
Posted: Thu May 27, 2004 10:10 pm |
|
|
mvaraujo wrote: |
Does anyone have something in mind that could help me solving this issue?
Thanks,
Marcus |
Simply convert to Seconds and store it as a 32 bit value.
If you use 01/01/2000 as your datum you can log date and time with 1 second resolution for the next 136 years.
Best regards
Hans W |
|
|
mvaraujo
Joined: 20 Feb 2004 Posts: 59 Location: Brazil
|
|
Posted: Fri May 28, 2004 7:17 am |
|
|
Hans,
This is right, itīs possible to convert to seconds but I need to know when leap years happen, etc. It's not that simple!
Thad,
That is great, it's a good way to pack the data! One concern is always the processing time!
Gerrit,
The point is always that specs that someone issues that puts a 100 year lifetime, even if it doesn't make any sense. The good point that this has been negociated and we figured out that the product must keep 15 years lifetime and I can cut one bit from the structure, save the data in 32 bits and don't have any processing time!
All,
Good discussion, sooner or later this kind of problem happens to people and knowing how to pack the data is important! I've learnt a lot from you.
Thanks,
Marcus |
|
|
Ttelmah Guest
|
|
Posted: Fri May 28, 2004 7:54 am |
|
|
mvaraujo wrote: | Hans,
This is right, itīs possible to convert to seconds but I need to know when leap years happen, etc. It's not that simple!
Thad,
That is great, it's a good way to pack the data! One concern is always the processing time!
Gerrit,
The point is always that specs that someone issues that puts a 100 year lifetime, even if it doesn't make any sense. The good point that this has been negociated and we figured out that the product must keep 15 years lifetime and I can cut one bit from the structure, save the data in 32 bits and don't have any processing time!
All,
Good discussion, sooner or later this kind of problem happens to people and knowing how to pack the data is important! I've learnt a lot from you.
Thanks,
Marcus |
May I suggest you use a 'compromise', which has worked for me in the past. First, a leap year is easy to calculate, if you have the 'year number'. The rule is three stage. Test if it is divisible by 400. If so, it is a leap year. Else, test if it is divisible by 100. If so, it is not a leap year. If not, then test if it is divisible by 4. If so it is a leap year. This is fairly easy to code.
Then code 'seconds in the day', as a 17 bit value. Have 5 bits for day of month, 4 bits for month of the year. This then using a 32 bit variable, allows 6 bits to be used for the year number. Starting with '2004' as an offset, this gives coverage till the end of 2067, and makes it much easier to extract the values when required. :-)
Best Wishes |
|
|
mvaraujo
Joined: 20 Feb 2004 Posts: 59 Location: Brazil
|
|
Posted: Fri May 28, 2004 8:18 am |
|
|
Ttelmah,
It looks very interesting!
I understood very well the part of the seconds of the day, but I didn't undestand how you pack the day+month+year! Can you go through this a little more?
Thanks,
Marcus |
|
|
Ttelmah Guest
|
|
Posted: Fri May 28, 2004 9:44 am |
|
|
mvaraujo wrote: | Ttelmah,
It looks very interesting!
I understood very well the part of the seconds of the day, but I didn't undestand how you pack the day+month+year! Can you go through this a little more?
Thanks,
Marcus |
I did it in assembler, on a Z80, so direct translation will be hard. :-)
However I'd suggest considering a layout like:
6 bits 'year'
4 bits 'month'
5 bits 'day_of_month'
1 bit 'am/pm'
16 bits 'seconds in half day'
Then if you declare a union, comprising a 32bit value, and two 16bit values, the second entry, becomes just the 'second' counter, and can be accessed like:
union {
int32 lword;
int16 word[2];
} date;
seconds = date.word[1];
pm = date.word[0] & 1;
day = (date.word[0]>>1) & 0x1F;
month = (date.word[0]>>6) & 0xF;
year = (date.word[0]>>10) & 0x3F;
The nice thing is that the field that updates the most often, is the one that is accessible easiest.
To save the whole 'timestamp', just access date.lword.
Best Wishes |
|
|
ThadSmith
Joined: 23 Feb 2004 Posts: 5 Location: Boulder, CO, USA
|
|
Posted: Fri May 28, 2004 3:27 pm |
|
|
mvaraujo wrote: |
Thad,
That is great, it's a good way to pack the data! One concern is always the processing time!
|
I assumed from the original post that storage space was more important that processing. The packed value is only 16 bits, though. You can save roughly half the processing time by using ldiv(), rather than % and / with the same divisor.
Thad |
|
|
Guest
|
|
Posted: Sun May 30, 2004 1:32 pm |
|
|
mvaraujo wrote: | Hans,
This is right, itīs possible to convert to seconds but I need to know when leap years happen, etc. It's not that simple!
Marcus |
Ttelmah is correct IF you plan to process for dates before 2000. However if your application is "from today and out for the next 96 years, then it is simple to find leap years:
if ( year % 4 == 0 )
{
// leap year
}
You can precalc. seconds per normal year and for a leap year, then it is a simple matter of ADDING values for whole years, and the rest DDMM HH can also be as simple.
There is really nothing difficult about it. ! |
|
|
Ttelmah Guest
|
|
Posted: Sun May 30, 2004 2:44 pm |
|
|
Anonymous wrote: | mvaraujo wrote: | Hans,
This is right, itīs possible to convert to seconds but I need to know when leap years happen, etc. It's not that simple!
Marcus |
Ttelmah is correct IF you plan to process for dates before 2000. However if your application is "from today and out for the next 96 years, then it is simple to find leap years:
if ( year % 4 == 0 )
{
// leap year
}
You can precalc. seconds per normal year and for a leap year, then it is a simple matter of ADDING values for whole years, and the rest DDMM HH can also be as simple.
There is really nothing difficult about it. ! |
Yes. I should have pointed out that the 'exceptions' only apply to the century years, and the quadcentenial years. For the intended application, given that we have just passed the 'exceptional' century year of 2000, division by four (or using an 'AND'), makes identification of the leap years a doddle. :-)
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|