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

Working with bits
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

Working with bits
PostPosted: Sat Sep 05, 2020 6:39 pm     Reply with quote

Hi, I need to represent the date and the time in only 3 bytes without including the minutes and the seconds. Assuming that a byte has 8 bits, then the hours I can represent it with 5 bits, the days also with 5 bits, the months with 4 bits which leaves me 10 bits to represent the year, how would my code be to represent today: 20/09/05 19
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Sep 05, 2020 9:59 pm     Reply with quote

Start counting the years at 0x00.

2020 = 0
2021 = 1
2022 = 2
.
.
.
2062 = 62
2063 = 63

That gives you a product life of 64 years, and it takes 6 bits.

That leaves 4 bits for something else.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Sep 05, 2020 11:53 pm     Reply with quote

Worth possibly also saying, you could just use the top 3 bytes of the
standard Unix time.
This (simply!...), codes time, as the number of seconds past it's epoch.
The epoch is either 1900, or 2010 (if the option TIME_T_USES_2010 is
enabled).
Now standard functions are supplied (in time.h/time.t), to convert
a time in year, month, day, hours, mins, secs etc., into this format, and
back. These are the standard Unix functions for this. The time is stored
in and int32, and though obviously involves adding this code, would save
having to write the conversions yourself. The functions understand about
things like leap years etc..
So if you then just store the upper three bytes of this value, and for
retrieval add a dummy '0' byte to the end, you can store 'time', to the
nearest 4.26 minutes, with all the work done for you.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 4:53 am     Reply with quote

For decades I've stored date and time into 2 bytes.

Time( hrs-mns) is encoded into 7 bits, where each bit is a 15 minute 'slice of the day'. So 0=midnight, 1=00:15, 2=00:30,3=00:45. This leaves one free bit of the 1st byte.
You combine that free bit with the 2nd byte to store the Day of the year( 1-365).
The 3rd byte easily stores the year ( 20, 21,22) with lots of bits leftover.

The 'time in a byte' trick is from the reality(30+ years ago) that alarm 'opening and closings' and energy controls times(heat on/off) don't need to be ultra precise. Slicing 24 hrs into 128 'segments' gives nice 1/4 hr times. Back then it was critical to save bits of memory wherever you could as chips cost big $$$ !

You do have to encode/decode the bits of data, fairly simple but I don't know how it compares to using the UNIX time method. I know my 'hrsmns' is fast and creates compact code. Less of an issue today with fast PICs and lots of memory but... the OP did want 'compact' time.

This might be another option, or at least something to think about.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 7:59 am     Reply with quote

That'll undoubtedly be quicker than the Unix version. But (of course), leaves
you having to do the calculations for maximum number of days in each
month etc..
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 10:53 am     Reply with quote

Hi, Based on your comments I want to convert the data read from a DS3231 to epoch seconds, for this I am using the time.h and time.c, here is my code, but I have errors, can someone tell me how to correct this?

Code:
#include <18F4520.h>
#fuses HS,NOWDT,WDT32768,PROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar

#include <time.h>
#include <time.c>

int32 timeSecond;

struct  {
   int8 myyear;
   int8 mymonth;
   int8 myday;
   int8 myhour;
   int8 mymin;
   int8 mysec;
}timeDatos;

void main(){
    timeDatos.myyear = 2020;
    timeDatos.mymonth = 9;
    timeDatos.myday = 6;
    timeDatos.myhour = 12;
    timeDatos.mymin = 30;
    timeDatos.mysec = 59;

   timeSecond = time_t mktime ( &timeDatos);

while (TRUE);

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 11:20 am     Reply with quote

Your time needs to be a struct_tm.

This is typedefed in time.h, and is what the mktime uses.

You don't want 'time_t' in front of mktime.

Code:

#include <18F4520.h>
#fuses HS,NOWDT,WDT32768,PROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar

#ignore_warnings 242
#include <time.h>
#include <time.c>
#ignore_warnings none

signed int32 timeSecond;

struct_tm timeDatos;

void main(){
    timeDatos.tm_year = 2020-1900; //year needs to be since 1900
    timeDatos.tm_mon = 9;
    timeDatos.tm_mday = 6;
    timeDatos.tm_hour = 12;
    timeDatos.tm_min = 30;
    timeDatos.tm_sec = 59;

    timeSecond = mktime ( &timeDatos);

while (TRUE);

}

I've added an ignore_warnings, since the driver will give warnings about
missing breaks. It is however correct.

The 'time' is a signed value. This allows you to do things like handle
dates before the 1900 epoch.
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 11:51 am     Reply with quote

Hi Ttelmah, the result is:
Code:
timeSecond = 1602073859


but this is different from the value obtained using the https://www.epochconverter.com/
Code:
Epoch timestamp: 1599395459


How can I correct it?
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Sun Sep 06, 2020 11:55 am     Reply with quote

pilar wrote:
Hi Ttelmah, the result is:
Code:
timeSecond = 1602073859


but this is different from the value obtained using the https://www.epochconverter.com/
Code:
Epoch timestamp: 1599395459


How can I correct it?


I thought it's supposed to be the time since 1970?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 12:18 pm     Reply with quote

There are a number of different bases actually used for 'Unix time', as
well as a number of different formats. Unless you need to send the time
to a Unix system and then process it there, why care?. If you are
sending the time, send it as a time in ASCII.
I think you will find the difference is using 31st Jan or 1st Jan.
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 1:45 pm     Reply with quote

Quote:
why care?. If you are
sending the time, send it as a time in ASCII


Unfortunately, I only have 4 bytes to send this date and time data, and these 4 bytes is precisely the size of the epoch seconds expressed in hex, that's why my interest in that the epoch seconds is exact.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Sun Sep 06, 2020 2:04 pm     Reply with quote

If you are sending it to a pre-built system, don't they tell you what it is expecting?

Otherwise, if you are sending it to something you are designing yourself, you can define it however you need. In this case, I'm wondering what is the reason for the 4-byte restriction? If it's a memory restriction I highly recommend updating your hardware...

Do you change from your local time zone to UTC before doing the conversion?

I have some code that converted from the RTC struct rtc_time_t provided by CCS to work with PIC RTCs to unixtime:
Code:
struct_tm rtc_time_t_to_struct_tm(rtc_time_t realtime)
{
    struct_tm tm;
    tm.tm_sec = realtime.tm_sec;
    tm.tm_min = realtime.tm_min;
    tm.tm_hour = realtime.tm_hour;
    tm.tm_mday = realtime.tm_mday;
    tm.tm_mon = realtime.tm_mon - 1;
    tm.tm_year = realtime.tm_year + 100;
   
    return tm;
}

void func()
{
   rtc_time_t realtime_utc;
   // assign a time to realtime_utc here

   struct_tm timestruct = rtc_time_t_to_struct_tm(realtime_utc);
   time_t unixtime = mktime(&timestruct);
}
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 2:21 pm     Reply with quote

Quote:
I'm wondering what is the reason for the 4-byte restriction? If it's a memory restriction I highly recommend updating your hardware...


I have hardware restriction. This is a very specific modem that only allows sending a specific number of data in this case only 16 bytes and only in hexadecimal. I am using 12 bytes for reading sensors and I only have 4 bytes for the date and time.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 2:47 pm     Reply with quote

hmm...in your original post you had 3 bytes....and you only wanted yr/mt/dy/hr.

Having 4 bytes does open up for more coding options....and more data to be sent
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 3:23 pm     Reply with quote

Quote:
hmm...in your original post you had 3 bytes....and you only wanted yr/mt/dy/hr.


Very Happy Yes it is true at the beginning it was my query on how to send yr/mt/dy/hr. in only 3 byts, but along the way I got curious about epoch seconds and since there are not many examples using CCS, keep asking; now I have two doubts, how to correct the epoch seconds and how can I send this data in only 3 bytes

Quote:
For decades I've stored date and time into 2 bytes.


Please could you share your code with us on how you have managed to do this?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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