DS1994 Memory/Time iButton - Page 2


Closed Thread
Page 2 of 4 FirstFirst 1234 LastLast
Results 16 to 30 of 48
  1. #16
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    And here is the Release Candidate:

    It's actually the two examples from Melanie merged into one program
    with some minor changes: (LOOKUP-Table in EEPROM)
    and additions: (Calculation of WeekDay)
    and it reads the DWORD seconds counter from a real iButton.

    This Version is about 250 Words smaller than my initial Version.

    Many thanks to Melanie

    Code:
    
    
    
            DEFINE LOADER_USED 1
            DEFINE OSC 20
            
            ADCON1=7
    
    	DEFINE LCD_LINES 2							
    	DEFINE LCD_BITS 4							
    	DEFINE LCD_DREG PORTD					
    	DEFINE LCD_DBIT 4						
    	DEFINE LCD_RSREG PORTD					
    	DEFINE LCD_RSBIT 1							
    	DEFINE LCD_EREG	PORTD						
    	DEFINE LCD_EBIT	0						
    
    
    
    	'	Software Defines
    	'	----------------
            iButton     var PortD.2
    	ByteA       var BYTE
    	ByteB       var BYTE
    	ByteC       var BYTE
    	ByteD       var BYTE
    	DAYS        var WORD
    	HOURS       var BYTE
    	MINUTES     var BYTE
    	SECONDS     var BYTE
    	TempA       var WORD
    	TempB       var WORD
    	TempHOURS   var WORD
    	TempMINUTES var WORD
    	TempSECONDS var WORD
            CounterA    var BYTE
    	DAY         var BYTE
    	MONTH       var BYTE
    	YEAR        var BYTE
            DoW         var byte[3]
        
    	DATA @0,"S","a","t","S","u","n","M","o","n","T","u","e","W","e","d","T","h","u","F","r","i"
            DATA @21,31,28,31,30,31,30,31,31,30,31,30,31	
    
    
    	'	Calculate and Display
    	'	---------------------
    Loop:
    
    	'	Read iButton
    	'	------------
     
            owout iButton,1,[$cc,$f0,$03,$02]
    	owin iButton,0,[ByteD,ByteC,ByteB,ByteA]
    
    	Gosub CalculateLinearDAYS
    	GOSUB CalculateDateFromLinear
    	LCDOut $FE,$01, STR DOW\3,". ", dec2 Day,".",dec2 month,".","20",dec2 year
    	LCDOut $FE,$C0,"    ",DEC2 HOURS,":",DEC2 MINUTES,":",DEC2 SECONDS
    	Pause 1000
    	Goto Loop
    	
    	'
    	'	Calculate Linear DAYS and Day of Week
    	'	-------------------------------------
    CalculateLinearDAYS:
    	TempA.Highbyte=ByteA
    	TempA.Lowbyte=ByteB
    	TempB=TempA*18
    	DAYS=DIV32 24
    	HOURS=R2
    	TempB=TempA*12
    	TempHOURS=DIV32 60
    	MINUTES=R2
    	TempB=TempA*16
    	TempMINUTES=DIV32 60
    	SECONDS=R2
    	'
    	TempA.Highbyte=ByteC
    	TempA.Lowbyte=ByteD
    	TempHOURS=TempHOURS+(TempA/3600)+HOURS
    	TempA=TempA//3600
    	TempMINUTES=TempMINUTES+(TempA/60)+MINUTES
    	TempA=TempA//60
    	TempSECONDS=TempA+SECONDS
    	'
    	TempMINUTES=TempMINUTES+(TempSECONDS/60)
    	SECONDS=TempSECONDS//60
    	TempHOURS=TempHOURS+(TempMINUTES/60)
    	MINUTES=TempMINUTES//60
    	DAYS=DAYS+(TempHOURS/24)
    	HOURS=TempHOURS//24
    	'
            Read (DAYS//7*3),DoW[0]
            Read (DAYS//7*3+1),DoW[1]
            Read (DAYS//7*3+2),DoW[2]
            '
    	Return
    
    
    	'	Subroutine Calculates Date from Linear Days
    	'	-------------------------------------------
    CalculateDateFromLinear:
    	YEAR=0
    	DAYS=DAYS+1 
    	For CounterA=4 to 183
    		TempA=CounterA//4
    		TempB=365
    		If TempA=0 then 
    			TempB=TempB+1
    			endif
    		If DAYS>TempB then 
    			YEAR=YEAR+1
    			DAYS=DAYS-TempB
    			else
    			Goto CalculateMonth
    			endif
    		Next CounterA
    	' add 2000 to the YEAR value, ie YEAR=4 implies 2004.
    CalculateMonth:
    	MONTH=0
    CalculateMonthLoop:
        READ (MONTH+21),DAY
    	IF TempA=0 then
    			If MONTH=1 then DAY=DAY+1
    			Endif
    	If DAYS>DAY then
    		DAYS=DAYS-DAY
    		MONTH=MONTH+1
    		Goto CalculateMonthLoop
    		Endif
    	MONTH=MONTH+1
    	DAY=DAYS
    	Return
    
    
    	End
    Best regards

    Ralph
    Last edited by NavMicroSystems; - 27th September 2004 at 18:28.

  2. #17
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    That looks good Ralph...

    Have you worked out how to calculate 32-Bit Linear Seconds from a Gregorian Date (ie Year, Month Day) in order to set the iButton to say today's Date and Time?

  3. #18
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Melanie,

    to be honest, I'm still struggling with it.
    It would be a lot easier if PBP would have DWORD vars and math.

    To initially set the iButton I have calculated the set value manually and written it to the iButton.

    The accuracy of the "uncalibrated" DS1994 is surprisingly good, it is up for 61 days now and is "only" 29 seconds behind.

    Could you help with a SET-Routine that is less codespace hungry than my attempts so far?

    BTW
    I have written a "AUTO-DST-adjustment" that I will add as well.

    best regards

    Ralph
    Last edited by NavMicroSystems; - 27th September 2004 at 20:13.

  4. #19
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    The way I see to handle this is in three stages...

    1. A Data-Entry routine to capture individual YEAR, MONTH, DAY, HOUR and MINUTE. You have the LCD screen, do you also have say three buttons available that we can assign to UP, DOWN and SET function?

    2. CalculateLinearFromDate routine, to calculate Linear Days from the Date component (again a form of Julian Date - the inverse of my CalculateDateFromLinear routine.

    3. A method of generating the 32-Bit number containing the Linear Seconds to feed the iButton.

    Sure it would be easier to have all those other functions in PBP... but isn't it fun doing it this way? And it also proves that IT CAN BE DONE!

    I recall going to dinner once with an old retired gentleman that used to be the Data Processing Manager/IT Director of the Rolls Royce company. He recalled, that when he joined the company as a young Systems Analyst, one of his first tasks was to find an unsed BIT in memory to act as a Flag for a new feature in their Payroll program... they ran a weekly payroll for over 2000 employees on a computer with 8kb core memory! We've got it easy!

  5. #20
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default


    1. A Data-Entry routine to capture individual YEAR, MONTH, DAY, HOUR and MINUTE. You have the LCD screen, do you also have say three buttons available that we can assign to UP, DOWN and SET function?


    YES, there are three Buttons


    2. CalculateLinearFromDate routine, to calculate Linear Days from the Date component (again a form of Julian Date - the inverse of my CalculateDateFromLinear routine.


    I think the principle is clear (eventhough I don't have the code ready yet)


    3. A method of generating the 32-Bit number containing the Linear Seconds to feed the iButton.


    This is the challange !

  6. #21
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Ralph... you may have a small flaw in your code... shouldn't...

    READ (MONTH+20),DAY

    actually be...

    READ (MONTH+21),DAY

    I have a habit of checking other peoples changes to my code before I use it myself... an old adage I always go by "Trust - but verify".

  7. #22
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Melanie,

    thanks for checking the code.

    the first EEPROM Address for the lookup table is 21, so far you are right.

    as the address is calculated from "Month+20" the result for January (Month=1) would give 21.

    (We are counting months starting from 1, not zero.)

    best regards

    Ralph

  8. #23
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    When you first go through the loop, MONTH=0.

    (We don't add the MONTH correction until you're out of the loop.)

  9. #24
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Thanks Melanie,

    you are absolutely right.

    I messed it up when I changed the DoW Table from two characters to three characters for the weekday.

    Thanks again!

  10. #25
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Melanie,

    I'm past the timelimit for editing the post, could you correct that for me?

    regards

  11. #26
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Here's the solution to item 2 from my previous post yesterday (as it's the easiest to complete). It's the inverse of the CalculateDateFromLinear subroutine.

    This subroutine takes YEAR, MONTH and DAY and returns with Linear DAYS starting with DAYS=0 for 01/01/2000. Note, it's only good for 100 years as it does NOT account for year 2100 leap anomaly. I'm reusing variables and EEPROM presets previously defined in your program.

    Code:
    	'
    	'	Subroutine Calculates Linear Days from Date
    	'	-------------------------------------------
    CalculateLinearFromDate:
    	DAYS=0
    	For CounterA=0 to YEAR
    		TempA=CounterA//4
    		If CounterA < YEAR then
    			TempB=365
    			If TempA=0 then TempB=TempB+1
    			DAYS=DAYS+TempB
    			endif
    		Next CounterA
    	IF MONTH > 1 then
    		For CounterA=1 to MONTH-1
    			Read (CounterA+20),ByteA
    			If TempA=0 then
    				If CounterA=2 then ByteA=ByteA+1
    				endif
    			DAYS=DAYS+ByteA
    			Next CounterA
    		endif
    	DAYS=DAYS+DAY-1
    	Return
    Oh and in this routine, my MONTHS start counting from 1, so CounterA+20 is valid here!

  12. #27
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Just have enough time to squeeze in Part 3 (supposedly the most difficult part) before I have to go and do something meaningful with my life...

    This next subroutine takes our previously calculated Linear DAYS, and together with our HOURS, MINUTES and SECONDS builds a 32 bit number. It's the PBP mathematical equivallent of...

    X=(DAYS*86400)+(HOURS*3600)+(MINUTES*60)+SECONDS

    ...but using simple 16-bit integer math only. It would be interesting to compare which method uses less codespace.

    Before you look at the subroutine, I'd like to point out, that again I'm re-using variables previously defined earlier. Don't get confused with the names of the WORD variables such as TempHOURS, TempMINUTES and TempSECONDS. They have been previously defined in our program and I'm just using them as convenient WORD-sized storage.

    Code:
    	'
    	'	Subroutine Calculates Linear Seconds (as 32-Bit Number)
    	'	-------------------------------------------------------
    CalculateLinearSeconds:
    	TempA=0	' Holds the HighWord (Bits 16-31) ie ByteA and ByteB
    	TempB=0	' Holds the LowWord (Bits 0-15) ie ByteC and ByteD
    	IF HOURS > 11 then
    		TempB=$A8C0
    		HOURS=HOURS-12
    		endif
    	TempSeconds=(HOURS*3600)+(MINUTES*60)+SECONDS
    	TempB=TempB+TempSeconds
    	If TempB < TempSeconds then TempA=TempA+1
    	TempMINUTES=$A8C0:TempSeconds=$0000
    	TempHOURS=$8000
    	If DAYS=0 then CalculateLinearSecondsExit
    	While DAYS > 0
    		If DAYS = > TempHOURS then
    			TempB=TempB+TempSECONDS
    			If TempB < TempSECONDS then TempA=TempA+1
    			TempA=TempA+TempMINUTES
    			DAYS=DAYS-TempHOURS
    			endif
    		TempSECONDS=TempSECONDS>>1
    		If TempMINUTES.0=1 then TempSECONDS.15=1
    		TempMINUTES=TempMINUTES>>1
    		TempHOURS=TempHOURS>>1
    		Wend
    CalculateLinearSecondsExit:
    	Return
    Naturally we can extract our four 8-Bit Bytes (ByteA, ByteB etc) from the two 16-Bit variables (TempA and TempB) holding our 32-Bit result, and use that to directly set our iButton.

    What the above program does is a very simple Binary Recursive Addition to add together up to a maximum of 65535 days worth of seconds in sixteen (or less) itterations - which makes this a fast solution. We start off with TempMinutes and TempSeconds together holding a 32-Bit number ($A8C0:0000) which is the equivallent of 32768 days worth of Seconds. TempHOURS contains our DAY count-down, starting with 32768 days. Each time we travel through the WHILE-WEND loop, we halve the number of days (and so halving the number of seconds), until we run out of days and the loop is exited.

    Actually we can only calculate around 49710 days worth of seconds, before we spill out of 32 bits, so there's no point in calculating any dates beyond about 135 years anyway.

    I'll give you a pretty Data-entry routine to tie it all together later when I've some more time.

    Once again. for all the skeptics complaining about the lack of big-number math in PBP, this demonstrates that it CAN be done.

    I've not actually tested this routine, but it's simple enough that I'm confident it'll hold water.

  13. #28
    Join Date
    Dec 2003
    Location
    Wichita KS
    Posts
    511


    Did you find this post helpful? Yes | No

    Default

    Hello You two,

    I wish I had a RTC chip to play around with you all....I used to (many years ago) play with calanders and converting... But its been way to long now... I can't even remember the differences between them <g>.

    I delt with the YY.MMDD method, and the DD/MM/YY. In my programs in accounting, I wrote a very short routine that took any two dates and figured the differences between the two (Hey you got to produce agings somehow... <g>.

    Would you mind explaining exactly what you are trying to do?

    Dwayne
    Ability to Fly:
    Hurling yourself towards the ground, and missing.

    Engineers that Contribute to flying:
    Both optimists and pessimists contribute to the society. The optimist invents the aeroplane, the pessimist the parachute

    Pilots that are Flying:
    Those who know their limitations, and respect the green side of the grass...

  14. #29
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Dwayne,

    by re-reading this thread from the beginning you should get the full picture.

    If there are still questions let us know.

    regards

    Ralph
    Last edited by NavMicroSystems; - 28th September 2004 at 14:59.

  15. #30
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    This is a great thread, because it's demonstrating and reminding us of a whole heap of things... and these are useful things...

    So far...

    1. We've been reminded of a little known but very useful variable called R2 in the DIV32 command.

    2. We've manipulated a 32 bit variable which on the face of it seemed impossible with PBP, and reduced it to something useful and manageable.

    3. We've converted Gregorian Date (DAY, MONTH, YEAR) into a Julian Date (Linear DAYS).

    4. We've converted Julian Date (Linear DAYS) back into a Gregorian Date (DAY, MONTH, YEAR). This has been mentioned you can't do it with only 16-bit variables.

    5. We've discovered a way of saving a Date (as DAY, MONTH and YEAR) compactly as two BYTES (great for space saving when Data-Logging).

    6. Better than that we've discoverd a way to save DAY, MONTH, YEAR, HOUR, MINUTE and SECOND, as only FOUR bytes. Again, beat that for a Data-Logging application.

    Just using those you could enter two dates, and not only determine the DAYS between them, but you could determine it to the SECOND.

    7. We've demonstrated a method of 16 by 17 bit multiplication... to produce a 32 Bit result.

    And we've done it all in 'pure' PBP with no Assembler or other 'bought-in' foreign routines. That way, everybody can follow it and learn something to their benefit.

    And this thread isn't done yet...

Similar Threads

  1. Writing & Reading to iButton EEPROM
    By crhomberg in forum Code Examples
    Replies: 2
    Last Post: - 6th October 2008, 19:40
  2. DS1920 IButton
    By scottl in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 2nd November 2007, 00:39
  3. iButton
    By menze in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 26th June 2006, 23:48
  4. RS485 - ibutton network
    By ccsparky in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 6th June 2005, 21:48
  5. Dallas DS1994 iButton CLOCK
    By NavMicroSystems in forum Code Examples
    Replies: 0
    Last Post: - 29th September 2004, 22:19

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts