I am using a DS3231 for time keeping and date. It seems that after I set the date, the day of week is not updated accordingly.
Or I didn't read the datasheet properly or else, the DS3231 does not track and update the day of the week. I think that the later is correct, as according to some reading, to calculate the day of the week we also need the century, of which the DS3231 does not have.
For anyone interested, from the reading I did on calculations I did a small procedure, which seems to be working correctly: -
'===================================================================================================
'***********************************************
'* Find the day of week of a date *
'* Input : YY holds the interested year *
'* Output: Returns the day of week; 1 = Monday *
'* Notes : Century can be added to get dates *
'* : from different centuries *
'***********************************************
proc Day_of_Week(YY as byte, MM as byte, Date_of_Month as byte), byte
dim Year_Code as byte ' Variable to hold Year Code
dim Month_Code as byte ' Variable to hold Month Code
dim Cent_Code as byte ' 1700's = 4, 1800's = 2, 1900's = 0, 2000's = 6
' 2100's = 4, 2200's = 2, 2300s = 0
dim Leap_Year as bit ' Flag to indicate if it's leap year; 0 = Not leap , 1 = leap
cent_code = 6 ' Century code is 6 for century 2000
'--------------------------------------------------------------------------------------------------
year_code = (YY / 4) + YY ' Do not use the century for year, i.e.: - Year 2022 use only 22
year_code = year_code // 7 '
month_code = lookupl mm, [0, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5] ' Get Month Code according to current month
Leap_year = 0 ' Reset Leap Year
for bloop = 0 to 96 step 4 ' Create a loop wit a x4 increase to detect leap year
if bloop = YY then ' If loop equals year then
Leap_year = 1 ' it is a leap year, so set Leap bit
else leap_year = 0 ' else if it not leap year, clear Leap_Year
endif ' End If...Then instruction
next ' next loop
result = year_code + month_code + cent_code + date_of_month - leap_year
result = result // 7 '
endproc
Then to get the day of the week: -
Global_DayNum = day_of_week(Global_year, Global_month, Global_day)
NOTE: - Global_year should input the LAST two digit of the year, i.e.: - 2022, input only 22
Century is fixed for the years 2000's, for different centuries please update with appropriate century code: -
cent_code = 6 ' Century code is 6 for century 2000
or add another input directly to the procedure.
Regards
Joe
Thanks for sharing.
I had some experiment with date and time, but I consider the fact that we don't need much expansion to other century, so calculation may be lowered to a couple of decades. For my project I just expect to last no more than a decade, if any.
The DS3231 has the weekday at register $03, just the last 3 bits, didn't get the result of it?
QuoteThe day-of-week register increments at midnight.
low while SCL is high, generating a START condition.
Values that correspond to the day of week are user-defined but must be sequential (i.e., if 1 equals
Sunday, then 2 equals Monday, and so on). Illogical time and date entries result in undefined operation
Sorry I didn't tried, but if I'm not wrong it's necessary to write a value first, corresponding to the day of the week of the written period, then the RTC will increase at midnight. Values bigger than 7 might be crippled down.
So reading the register it should be
ANDed with 0b0000111.
Keytapper,
That is why I wrote that procedure because the DS3231 does not set the weekday directly. With the procedure is very easy.
Someone else will input the date so I eliminated the need to add another routine to set the date.
I needed this so I can add day light saving. Here again I read some on the internet and what a load of crap and formulas I saw just to get the daylight saving.
The routine I came up with is very, very, very easy. I will add this when I have some time.
Regards
Joe
In DS3231 you have to set all the registers, it doesn't do any calculation of the variables
Once the registers are set, he goes ahead by himself updating all the variables.
I usually run DS3231 in UTC.
After reading it, I transform it into local time taking into account the time zone (only positive at the moment) and summer or winter time.
when I save I transform first into UTC time.
He always goes forward in UTC time and the pic reading the DS 3231 is able to calculate the local time even if powered after a long time, provided that the DS battery works :-)
Sorry google translate
There are some C library for date and time. Most of them convert the time in seconds and it's calculated by a starting epoch. Some is set on 1/1/1970, the so called Unix time.
What that makes is to perform the time calculation, which involves the DST too.
But for a simple project, the beginning of the year will widely suffice, the just count how many seconds are passed since then.
There are libraries to deal with local time as well, which is including the DST calculating rules.
I think that it is not hard to convert these libraries in basic.