CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Compressing timestamp to store in EEPROM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mvaraujo



Joined: 20 Feb 2004
Posts: 59
Location: Brazil

View user's profile Send private message

Compressing timestamp to store in EEPROM
PostPosted: Thu May 27, 2004 8:16 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu May 27, 2004 8:47 am     Reply with quote

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

View user's profile Send private message

Re: Compressing timestamp to store in EEPROM
PostPosted: Thu May 27, 2004 10:10 am     Reply with quote

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
PostPosted: Thu May 27, 2004 10:10 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri May 28, 2004 7:17 am     Reply with quote

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







PostPosted: Fri May 28, 2004 7:54 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri May 28, 2004 8:18 am     Reply with quote

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







PostPosted: Fri May 28, 2004 9:44 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri May 28, 2004 3:27 pm     Reply with quote

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








PostPosted: Sun May 30, 2004 1:32 pm     Reply with quote

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







PostPosted: Sun May 30, 2004 2:44 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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