Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 20:26 24 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Maximite SM1 RTC Sucess

     Page 3 of 4    
Author Message
Vikingboy
Regular Member

Joined: 23/09/2011
Location: Australia
Posts: 82
Posted: 03:01pm 04 Nov 2011
Copy link to clipboard 
Print this post

Hi,

Sorry I run mine in 24 hour mode and prefer it, havn't thought about converting to 12 hour mode, although i did make a snippet to display am and pm for something, it shouldn't be too hard, just subtract 12 from the hours using left$ etc.

Now back to the day of the week thing, after some more testing, I find that my fix works, "most" of the time, something very strange is happening in the reader, setting the day seems ok, but the reader is giving different results everytime I run it, then after about 4 runs it settles down and gives the right day even without that patch line I just posted, Its much too late for me to figure out now, So I will take another look tomorrow/
If you want to try basically, when I first ran it wday$ return 36 hence my hack fix, then it showed 24 once, fix didn't work :( then 16, fix ok again yay, then its back to showing 6 as it should ?? fix not needed ?-{.. anyway a job for tomorrow.

Andrew
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 07:13pm 04 Nov 2011
Copy link to clipboard 
Print this post

also i would like to note that after 24:00 hours and after 12:00 all that is needed is a subtraction of 12 hours and you will have the 12 hour read its not a hard ask for some simple personal ability so ...the 24:00 hour clock doesent worry me ...///...///
technicians do it with least resistance
 
Moongazer
Newbie

Joined: 06/11/2011
Location: Australia
Posts: 8
Posted: 09:38am 06 Nov 2011
Copy link to clipboard 
Print this post

  Quote  
16 PRINT "PLEASE TELL ME WHAT TODAY IS?"


General principle of programming (IMHO): If you can calculate it, don't ask the user for it. (Even if you're the user.) The weekday of a date is directly computable from the date. Here's some BASIC code to do it. (Not MMBASIC, but easily portable). (The zip file includes a Windows executable, so you can test the code.)

2011-11-06_203052_Weekday-bas.zip Edited by Moongazer 2011-11-07
 
Vikingboy
Regular Member

Joined: 23/09/2011
Location: Australia
Posts: 82
Posted: 02:03pm 06 Nov 2011
Copy link to clipboard 
Print this post

  Moongazer said  
  Quote  
16 PRINT "PLEASE TELL ME WHAT TODAY IS?"


General principle of programming (IMHO): If you can calculate it, don't ask the user for it.


Very true, however even the most complex clock needs to be set by a user :p

Thia thread is all about setting and retrieving the Day of the week from the RTC attached to the Maximite, As I said originally and later, there are other and some surely better solutions .
But I merely corrected a couple of errors in someone elses code to allow them to set and then retrieve the DOW from their RTC.

rgds,

Andrew
 
Moongazer
Newbie

Joined: 06/11/2011
Location: Australia
Posts: 8
Posted: 11:40pm 06 Nov 2011
Copy link to clipboard 
Print this post

  Vikingboy said  
I merely corrected a couple of errors in someone else's code
Indeed. (It was lazy quoting on my part.)

I mainly wanted to contribute the code to calculate the weekday if anyone wants to use it. But if you do, please use the link below to download it rather than the one in my previous post. This is an improved version of (though functionally the same as) what I posted yesterday. Tidied up the code a bit and the comments.

2011-11-07_093843_Weekday-bas.zip

(Note to mod: If you can delete the previous link, or make it point to this one instead, that would help.)Edited by Moongazer 2011-11-08
 
Vikingboy
Regular Member

Joined: 23/09/2011
Location: Australia
Posts: 82
Posted: 01:03am 07 Nov 2011
Copy link to clipboard 
Print this post


Hi,

Thanks very much , this code is indeed a very useful snippet.

One point, after an admittedly very quick glance, I noted that in places it seems to expect the date in US format ie month/day/year rather than the usual AU day/month/year. this may cause some problems.

Although looking further it seems to state the opposite in other areas so it may be a misread on my part.

rgds,

Andrew
 
Moongazer
Newbie

Joined: 06/11/2011
Location: Australia
Posts: 8
Posted: 03:56am 07 Nov 2011
Copy link to clipboard 
Print this post

For all human-interface date input (which is just the command-line in that demo program) the expected ordering is d-m-y.

You may have been referring to the code segment which retrieves and parses the system date in cases where no date is supplied on the command line. The system date is stored internally (at least on Windows PCs, which is what the demo program is compiled for) in the American m-d-y order (regardless of how it is set to be displayed by the user-account preferences). The code that parses the system date is constrained by how the system stores it.

Where a date is passed internally in the code as parameters to a function or subroutine, I generally use y-m-d ordering, except where some other order may be preferrable for clarity or consistency for the benefit of a human reader/programmer. In the latter case, it would usually be transposed to the d-m-y convention. I don't think the American m-d-y convention is used anywhere (except as mentioned above for parsing the system date).

Don't confuse YearType (where passed/expected as a parameter) with year number. The former is just a pseudo-boolean indicating whether the year is a common or a leap year. BTW, in some places the value for true (indicating that it IS a leap year), MUST be -1 (= NOT False, i.e. NOT zero), not just any non-zero value (like 1), because that value (-1) is sometimes used in arithmetic operations. It is only a pseudo-boolean (meaning a numeric value used as a boolean), not a real boolean.

 
Vikingboy
Regular Member

Joined: 23/09/2011
Location: Australia
Posts: 82
Posted: 04:38am 07 Nov 2011
Copy link to clipboard 
Print this post

  Moongazer said  
You may have been referring to the code segment which retrieves and parses the system date in cases where no date is supplied on the command line.



Yes, this is the section I was looking at, the problem being ofcourse that the maximite uses DD/MM/YYYY.
So anyone using it for Maximite programming needs to realise this.

No problem I suppose as long as people realise.

It might be useful if you could post a short instruction on where the changes might be necessary if using the code on Maximite computer.

thanks,

Andrew
 
Moongazer
Newbie

Joined: 06/11/2011
Location: Australia
Posts: 8
Posted: 04:55am 07 Nov 2011
Copy link to clipboard 
Print this post

  Quote  
16 PRINT "PLEASE TELL ME WHAT TODAY IS?"


General principle of programming (IMHO): If you can calculate it, don't ask the user for it. (Even if you're the user.) The weekday of a date is directly computable from the date. Here's some BASIC code to do it. (Not MMBASIC, but easily portable). (The zip file includes a Windows executable, so you can test the code.)

2011-11-07_093843_Weekday-bas.zip
 
Bill.b

Senior Member

Joined: 25/06/2011
Location: Australia
Posts: 226
Posted: 05:12am 07 Nov 2011
Copy link to clipboard 
Print this post

Why calculate the weekday when it is available from most RTC Chips??

In the interests of the environment, this post has been constructed entirely from recycled electrons.
 
Moongazer
Newbie

Joined: 06/11/2011
Location: Australia
Posts: 8
Posted: 05:37am 07 Nov 2011
Copy link to clipboard 
Print this post

  Vikingboy said  It might be useful if you could post a short instruction on where the changes might be necessary if using the code on Maximite computer.
Good idea. Would you be willing to do it? I don't have the necessary knowledge of the Maximite or of MMBASIC to do it myself, as I do not (yet) possess either. You should find my code very easy to follow (it is extensively commented), but I'd be happy to answer any questions if something seems unclear.

BTW, date and calendar computations are a particular programming interest of mine, so if there's any other programming need in that area, just ask -- I may have the answer.

 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6097
Posted: 07:56am 07 Nov 2011
Copy link to clipboard 
Print this post

  Moongazer said  
  Vikingboy said  
BTW, date and calendar computations are a particular programming interest of mine, so if there's any other programming need in that area, just ask -- I may have the answer.


I like your well commented code.

Most of the users are only interested in recent times so I usually don't try and cater for anything before 1900 or after 2100.

The following code should be correct between those dates:

100
110 currentdate$= date$
120 day= val(mid$(currentdate$,1,2))
130 month= val(mid$(currentdate$,4,2))
140 year= val(mid$(currentdate$,7,4))
150
160 'weekday subroutine
161 'given day, month, year
162 'dayz=days since 1/1/1900 - agrees with Excel after 1/3/1900
163 'weekday starts at 0 for Sunday to match the RTC chip
170 dayofyear= day+int((month-1)*30.57+0.5)
180 if month >2 then
190 dayofyear= dayofyear-1
200 if (year/4)>0 then dayofyear= dayofyear-1
210 endif
220 dayz= int((year-1900)*365.25)+dayofyear+1
230 weekday= dayz-1-int((dayz-1)/7)*7
240 print day;" ";month;" ";year
250
260 print dayz,weekday


Having the days since 1900 makes it easy to do days between dates.
It still needs the reverse - format a date given the day number.

Jim
VK7JH
MMedit   MMBasic Help
 
Moongazer
Newbie

Joined: 06/11/2011
Location: Australia
Posts: 8
Posted: 04:53am 09 Nov 2011
Copy link to clipboard 
Print this post

I'm a newbie here, so sorry if this is obvious, but I don't see any links here to contact the admin or moderator of this site. (I have already tried replying to the confirmation email I received when I registered, but that hasn't worked.) There is something strange about the post from me at the top of page 5 of this thread. I'm not sure how it got there. It appears to be a copy of my original post on page 4 of this thread, but the link to the uploaded file doesn't work in that copy.

In any case, please don't use that link on page 4 (in the post dated 6 November), instead, please use the one posted on 7 November (lower down on page 4), as requested there.
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6097
Posted: 05:41am 09 Nov 2011
Copy link to clipboard 
Print this post

Updates to MM basic have given us a few new ways to program the RTC.
This program is for the PCF8563 RTC.
This clock doesn't seem to calculate the dayofweek so you have to enter the correct day when setting the clock.
Lines 410 to 470 do this for you.

I have changed the way that the numbers are converted to and from BCD to make use of the HEX$ command.

To convert to BCD using line 320 as an example
Extract the hours fron the Time string: LEFT$(now$, 2)
Fool it into thinking it is HEX by adding '&H' to the start : "&H"+LEFT$(now$, 2)
Convert it into a number with VAL : val("&H"+LEFT$(now$, 2))

To do the reverse with data from the RTC using line 630 as an example,
Convert it into a string with HEX$ : hex$(RTCbuff(0)) (we will ignore the mask for now)
Pad the number with '00' to get leading zeros : "00"+hex$(RTCbuff(0))
Take the last 2 digits : right$("00"+hex$(RTCbuff(0)))
This leaves you with a 2 digit string with leading zeros.

100 ' PCF8563 RTC test by Jim Hiley 09/11/11
110 dim RTCbuff(20)
120 'cls
130 print "MM Time = ";Time$;" ";Date$
140
150 ' [mainloop]
160 print "1 Set RTC"
170 print "2 Read RTC"
180 print "3 Set MM from RTC"
190 print "4 Enter new Time"
200 print
210 input "Choice";c
220 if c = 1 then goto 290
230 if c = 2 then MMset= 0:goto 580
240 if c = 3 then MMset= 1:goto 580
250 if c = 4 then goto 850
260
270 goto 150
280
290 ' [setRTC]
300 now$= time$
310 today$= date$
320 BCDh= val("&H"+LEFT$(now$, 2))
330 BCDm = val("&H"+mid$(now$, 4, 2))
340 BCDs = val("&H"+mid$(now$, 7,2))
350 day = val(LEFT$(today$, 2))
360 month = val(MID$(today$, 4, 2))
370 year = val(RIGHT$(today$, 4))
380 BCDd = val("&H"+LEFT$(today$, 2))
390 BCDmo = val("&H"+MID$(today$, 4, 2))
400 BCDy = val("&H"+RIGHT$(today$, 2))
410 dayofyear= day+int((month-1)*30.57+0.5)
420 if month >2 then
430 dayofyear= dayofyear-1
440 if (year/4)>0 then dayofyear= dayofyear-1
450 endif
460 dayz= int((year-1900)*365.25)+dayofyear+1
470 BCDw= dayz-1-int((dayz-1)/7)*7
480 ' Write Time to RTC
490 i2caddr = &h51 ' PCF8563 I2C address
500 I2CEN 100,100 ' Enable I2C
510 I2CSEND i2caddr, 0, 10,0,0,0, BCDs, BCDm, BCDh, BCDd, BCDw, BCDmo, BCDy
520 I2CDIS
530 print "0=ok 1=nack 2=timeout "; MM.I2C
540 print "RTC set to: ";now$;" ";today$
550 print
560 goto 150
570
580 ' [readRTC]
590 i2caddr = &h51 ' PCF8563 I2C address
600 I2CEN 100,100 ' Enable I2C
610 I2CRCV i2caddr, 0, 7, RTCbuff(0),1,2
620 I2CDIS
630 RTCsec$= right$("00"+hex$(RTCbuff(0) AND &H7F),2)
640 RTCmin$= right$("00"+hex$(RTCbuff(1) AND &H7F),2)
650 RTChr$= right$("00"+hex$(RTCbuff(2) AND &H3F),2)
660 RTCday$= right$("00"+hex$(RTCbuff(3) AND &H3F),2)
670 RTCwday$= right$("00"+hex$(RTCbuff(4) AND &H07),2)
680 RTCmon$= right$("00"+hex$(RTCbuff(5) AND &H1F),2)
690 RTCyr$= "20"+right$("00"+hex$(RTCbuff(6)),2) 'test
700 RTCLongday$= mid$("SUNMONTUEWEDTHUFRISAT",val(RTCwday$)*3+1,3)
710 RTCtime$= RTChr$+":"+RTCmin$+":"+RTCsec$
720 RTCdate$= RTCday$+"-"+RTCmon$+"-"+RTCyr$
730
740 print "RTC Time = ";RTCtime$;" ";RTCdate$;" ";RTCLongday$
750 print "MM Time = ";Time$;" ";Date$
760
770 if MMset= 1 then
780 Time$= RTCtime$
790 Date$= RTCdate$
800 print "MM Time set!"
810 endif
820 print
830 goto 150
840
850 ' [entertime]
860 input "Time? ",newT$
870 input "Date? ",newD$
880 if len(newT$)>1 then Time$= newT$
890 if len(newD$)>1 then Date$= newD$
900 print Time$;" ";Date$
910 print
920 goto 150


With a bit of experimenting, you will probably find that the Maximite keeps better time than the RTC.

Jim

VK7JH
MMedit   MMBasic Help
 
Moongazer
Newbie

Joined: 06/11/2011
Location: Australia
Posts: 8
Posted: 06:29am 09 Nov 2011
Copy link to clipboard 
Print this post

  TassyJim said  
I usually don't try and cater for anything before 1900 or after 2100.

162 'dayz=days since 1/1/1900 - agrees with Excel after 1/3/1900
163 'weekday starts at 0 for Sunday to match the RTC chip
...
200 if (year/4)>0 then dayofyear= dayofyear-1
...
220 dayz= int((year-1900)*365.25)+dayofyear+1
230 weekday= dayz-1-int((dayz-1)/7)*7


Line 200 is wrong. It was intended to subtract 1 if the year is a common year. But you are testing the quotient of the division; you should be testing the remainder of the division. Also, that test on its own will not cater for all years. It will fail in the year 2100 (You said you don't cater for years after 2100.)

Remember the global todo in the years shortly before the turn of the century with governments and industry scrambling to fix old software that was destined to fail due to the Y2K bug? If you have a son born tomorrow, he has a fair chance of still being alive on Feb 28, 2100. He also has a fair chance of having forgotten by then that the software on that old discarded Maximite of yours that he salvaged from your garage when he was a teenager and which is now being used to control the water flow from the dam he built on his property, will turn into a pumpkin tomorrow. As a result, he drowns in the flood caused by the software crash. (That property was the one he inherited from you after you died in a plane crash caused by buggy flight-control software.)

"Nonsense," you may think, "My Maximite will be thoroughly obsolete by then and in any case there is no way it will survive that long; it will be truly dead and buried by then." Maybe, but software lasts a lot longer than hardware, and good software is often reused. (It has worked flawlessly for decades, it's not gonna suddenly fail now, right?) Does anyone remember what caused the (uninsured) European space rocket, Arian 5, to blow up on its maiden launch in 1996? The report on the cause came out several years later. It failed because of the one item that was recycled intact from Arian 4, in which it had been extensively tested and was found to work perfectly, and was still as good as new -- the guidance software. It had an arithmetic overflow bug which could only be triggered by values that could not arise in Arian 4's trajectory, but Arian 5's rocket was much more powerful and followed a shorter take-off trajectory-curve than that of Arian 4, and the bug that "could not arise" did.

Also line 220 is wrong, but I can't fix it without knowing what you intend by:

162 'dayz=days since 1/1/1900

Do you mean days since the beginning of that day, or since the end of that day?
In other words, respectively: is Monday, 1/1/1900, Gregorian, day 1 or day zero?
Since you treat Sunday as weekday 0, I might assume the former. On the other hand, you do say since 1/1/1900, so I'm not sure what you intended, but in either case, your weekdays are wrong for most of 1900, and your day count is out by between 1 and 3, depending on the year and which day-number you attach to 1/1/1900.

The following two routines work correctly and the introductory comments to each show how they can be adapted for use with a modified day count commencing with 1/1/1900 as day 1. (If you want that day to be day zero, add 1 to the suggested adjustment factor.) Note: Like the code I uploaded on 7 November, the following is written in PowerBasic and may require some syntax changes when ported to MMBASIC.


' FnGregorianToJDN& (Y&, M&, D&)
' -----------------
' Converts a Gregorian Date, supplied as Y,M,D, to a Julian Day Number,
' according to the formula in: http://en.wikipedia.org/wiki/Julian_Day.
' Valid for all dates => Wed -4800, Mar 1, G'n proleptic (= JDN -32044).
' Note: the backslash operator denotes an integer division, where the
' decimal portion (if any) is stripped from the result and only the integer
' portion is returned. No rounding is performed.

' If you wish to use a modified day count where day 1 is, say, 1900, Jan 1,
' subtract the JDN of the previous day (2,415,020), from the value returned
' by this function.

' JDN 0 = Jan 1 -4712 (BCE 4713), Julian Proleptic.
' = Nov 24 -4713 (BCE 4714), Gregorian proleptic.

function FnGregorianToJDN& (Y&, M&, D&)
' -----------------
local a&, Mth&, Yr&, JDN&

a& = (14 - M&)\12
Yr& = Y& + 4800 - a&
Mth& = M& + (12 * a&) - 3
JDN& = D& + ((153 * Mth& + 2)\5) + (365 * Yr&) _
+ (Yr&\4) - (Yr&\100) + (Yr&\400) - 32045
function = JDN&
end function ' FnGregorianToJDN& ----------------------------------



' JDNtoGregorianDate (JDN&, Y&, M&, D&)
' ------------------
' Converts a Julian Day Number to a Gregorian date, according
' to the algorithm by Fliegel & Van Flandern given on page 604
' of Explanatory Supplement to the Astronomical Almanac (USA).
' Note: fix (n) strips the decimal portion (if any) from its argument
' and returns only the integer part, with no rounding or scaling.

' If you are using a modified day count where day 1 is, say, 1900, Jan 1,
' first add the JDN of the previous day (2,415,020) to your day count and
' pass the sum as the value of the first parameter to this subroutine.

' Valid for all JDN => -32044 (= -4800, Mar 1, Gregorian proleptic)

' (JDN 0 = -4713 Nov 24 Gregorian proleptic, -4712 Jan 1 Julian proleptic.)
' (JDN 0 = BCE 4714 Nov 24 Greg'n proleptic, BCE 4713 Jan 1 J'n proleptic.)

sub JDNtoGregorianDate (JDN&, Y&, M&, D&)
' ------------------
local L&, N&, I&, J&

L& = JDN& + 68569
N& = fix((4 * L&)/146097)
L& = L& - fix((146097 * N& + 3)/4)
I& = fix((4000 * (L& + 1))/1461001)
L& = L& - fix((1461 * I&)/4) + 31
J& = fix((80 * L&)/2447)
D& = L& - fix((2447 * J&)/80)
L& = fix(J&/11)
M& = J& + 2 - 12 * L&
Y& = 100 * (N& - 49) + I& + L&
end sub ' JDNtoGregorianDate --------------------------------------

 
Moongazer
Newbie

Joined: 06/11/2011
Location: Australia
Posts: 8
Posted: 06:57am 09 Nov 2011
Copy link to clipboard 
Print this post

  TassyJim said  With a bit of experimenting, you will probably find that the Maximite keeps better time than the RTC.


If so, why have an RTC at all? From what I've read here, it needs to be added to the Maximite, which involves some considerable tinkering. Does the RTC have its own oscillator or does it get its pulse from the Maximite?

I'm very interested in this, because the main reason I'm thinking of getting a Maximite is to use it to control a set of (special purpose) analogue clocks in a similar way (but with additional functions) to the way Geoff Graham in one of his other projects controls an analogue clock with a controller board incorporating a GPS unit. So I'm very interested in why others seem to consider it important to add an RTC to their Maximite?

 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6097
Posted: 07:31am 09 Nov 2011
Copy link to clipboard 
Print this post

Why have a RTC?
It keeps the time while the MM is shutdown, same as in normal PC's.
If the Maximite is left running, there is no use for the RTC.
In my own application, I update the Maximite time from the PC daily and the PC is kept in time through the internet. Within one second is more than good enough for me.
For astronomy, the GPS clock is the way to go.

Microsoft in their 'wisdom' used 1/1/1900 as the starting date for their excel spreadsheet and while I know it's not a very good excuse, that was where I started.

162 'dayz=days since 1/1/1900

Microsoft got it wrong for the year 1900 so my formula is consistent with Microsoft from the 1st March 1900 onwards (I think).

The RTC we are using seems to treat all centuries the same so it will give another y2k bug anyway.
From the Datasheet "The PCF8563 compensates for leap years by adding a 29th day to February if the year counter contains a value which is exactly divisible by 4, including the year 00." It doesn't keep centuries but does let you know if the century has rolled over.

I know that Julian Day Number is the correct way to go and I will have a go at converting your latest code soon.

Jim

VK7JH
MMedit   MMBasic Help
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 07:52am 09 Nov 2011
Copy link to clipboard 
Print this post

my "rtc" works fine once set iniatially all i do is run the read "rtc" and this keeps the day as well ..i am using some of the earlier code ...and i have it running on the "SM1" board and it does have an internal oscillator but does require the fitting of a xtal... the read program can be run in the autorun and it can also be run at any other time it can prolly even be called up in your program`s ....
technicians do it with least resistance
 
brucepython

Regular Member

Joined: 19/06/2011
Location: Australia
Posts: 64
Posted: 08:17pm 09 Nov 2011
Copy link to clipboard 
Print this post

Here's the address of a list PowerBASIC and other BASIC assemblers' functions if any translation assistance is required:

http://www.powerbasic.com/support/technote/features.asp

Bruce

Fixed that link for you Bruce. There was a double "http://" in the url, triggering some malware detection software. All good now, and its a very interesting link too. Glenn.Edited by Gizmo 2011-11-13
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 11:04pm 09 Nov 2011
Copy link to clipboard 
Print this post

here is a pic of my "SM1" board running the rtc









Edited by sparkey 2011-11-11
technicians do it with least resistance
 
     Page 3 of 4    
Print this page
© JAQ Software 2024