DS1994 Memory/Time iButton


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

    Default DS1994 Memory/Time iButton

    I know I'm a pain...
    but
    does anyone have a piece of PBP-code that converts the binary data from a DS1994 iButton to "readable" time and date ?

    Thanks!

  2. #2
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    60+ Views on this posting (so far) and no reply.

    So may I assume there are 60+ people interested in a solution?

    Has really nobody used the DS1994 yet?

    I have a bunch of DS1994 sitting in a drawer and think they are a good replacement for DS1307 or PCF8583 as they have an embedded crystal and Lithium Backup Battery (that lasts 10+ years) and they are 1-wire.
    In addition there is 4k of NV-RAM on Chip.

    They count seconds from a reference Date and Time.

    How to calculate Year, Month, Day, Day of Week and Time from this DoubleWord Counter
    using the Integer Brain of a PIC?
    (ok, the counter is actually 5 Bytes, but I don't need the Least Significant Byte that counts fractional seconds)

    Any Input is appreciated!

    regards

    Ralph
    Last edited by NavMicroSystems; - 10th August 2004 at 00:13.

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


    Did you find this post helpful? Yes | No

    Default

    Does really nobody have any Input?

    (Or do you just nor want to share it?)

    Melanie?

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


    Did you find this post helpful? Yes | No

    Default

    I have not used this part before.

    When I've a moment free I'll download the Datasheet and see what's cooking...

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


    Did you find this post helpful? Yes | No

    Default

    Melanie thanks for your response.

    I have used a number of 1-wire devices and iButtons in the past.
    So reading from and writing to the DS1994 is no problem.

    The "Time" reading from the DS1994 is a 5 Byte value
    that contains the number of seconds (and fractional seconds) elapsed since the counter has been started.

    The least significant of those 5 bytes contains fractional seconds.
    So we actually have only to deal with a four bytes (or Dword) seconds counter.

    To set the Clock choose a reference date, calculate the number of seconds that have elapsed from then til "NOW" and write this to the DS1994 as the "start-value"

    All this works fine and the clock is running.

    But how do I calculate Year, Month, Day, Day of Week and Time from that DWord Counter to have something more readable to display having only the poor integer math of the PIC?

    Best regards

    Ralph

  6. #6
    Join Date
    Dec 2003
    Location
    Wichita KS
    Posts
    511


    Did you find this post helpful? Yes | No

    Default

    Hello Nav!

    Nav>>I know I'm a pain...but<<

    forgot "in the" <chuckle>.... No, just kidding here. Giving a friend a hard time.

    Nav>>does anyone have a piece of PBP-code that converts the binary data from a DS1994 iButton to "readable" time and date ?<<

    I have never used a DS1994, or any RTC before. I am getting a little interested in them right now... I biggest problem with RTC, is I want "forever", instead of 10 years <g>. I would like to know what you come up with on these RTC chips. I may order one, next time I order from allelectronics.com

    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...

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


    Did you find this post helpful? Yes | No

    Default


    Let's hope for a "MN1994.txt"
    ("MN1307.txt was excellent!)

    Last edited by NavMicroSystems; - 14th August 2004 at 03:08.

  8. #8
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Some progress has been made.

    I managed to calculate the number of Days, Hours, Minutes and Seconds
    elapsed since the reference date (01/01/2000 00:00:00)
    from the DoubleWord seconds counter reading.

    So far I can display the correct time from the iButton reading.

    Next steps will be:
    - calculation of Year, Date and Day of Week.
    - A "Set Clock" Routine.
    - automatic DST adjustment.

    Your Input is still appreciated.

    regards

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


    Did you find this post helpful? Yes | No

    Default

    I've got as far as downloading the Datasheet... looks like a linear extension of Julian Date kind of application... this is a bad two weeks for me (lots of work plus being an Olympics fan I'm in Athens at the weekends!)... but I'll see what I can do after.

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


    Did you find this post helpful? Yes | No

    Default

    Thank you for reminding me Ralph... I thought if I stayed nice and quiet and kept my head down the problem will go away...

    To achieve the answer is easy... to write it up so you all know how we get to it is what I wasn’t looking forward to doing... ah well, here goes an hour out of my life... and as always I draw your attention to the fact that there are many ways to get to the result - this is just one that’s simple and easy to grasp...

    1. Firstly let’s stand back and look at the big picture and try to understand it...

    The problem is that we have linear seconds represented as a 32 bit number which in theory we can’t handle. What we need to achieve is linear DAYS, with the remainder in the form of HOURS, MINUTES and SECONDS. That remainder of HOURS, MINUTES and SECONDS we can display as our REAL-TIME CLOCK component, whilst the linear DAYS we can then simply add to a reference point (ie a PIC version of a JULIAN DATE) to give us our YEAR, MONTH and DAY.

    There are two further problems here... not too obvious but pretty serious if you think about it, and that is (a) We can’t take significant time to calculate the result (after all it’s a clock and really you’d like to see the seconds ticking by and still have time to do something else), and (b) We can’t use up serious amount of codespace (what’s the point of using the equivalent of floats and then not having any space left in your PIC).

    Here’s our known limitations so far... We can’t have numbers bigger than 16-bits (65535), and we can’t have a divisor bigger than 15 bits (32767) if we decide to use DIV32 which is the only large calibre weapon in our maths arsenal. We could embed Microchips 32-bit Assembler routines but that will burn codespace and anyway, that’s cheating, quite apart from the fact that as soon we write a single line of Assembler, half the readers of this forum will immediately drop-out through lack of understanding or interest.

    2. How do we reduce the numbers to something manageable?

    What we ideally want to do is divide our 32-Bit number by 86400 (the number of seconds in a day). Well, the divisor is already 17 bits, and that’s two bits more than DIV32 can handle... looks on the surface like we’re losing this one - but are we?

    Let’s analyse those 32 bits... what have we got?

    The lower 16 bits are seconds from zero, up to 65535. The upper 16 bits are multiples of 65536 seconds. If we load the two upper bytes as a word, then each count represents 65536 seconds. What is 65536 seconds? It is 18 HOURS, 12 MINUTES and 16 SECONDS. Knowing this, we can simply explode our most significant word into multiples of HOURS, MINUTES and SECONDS...

    3. Let’s program...

    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

    Now assume we’ve read our 32-Bit number from the RTC into variables ByteA, ByteB, ByteC and ByteD where ByteA holds our Most Significant Bits, and ByteD holds the Least Significant Bits.

    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

    This now completely resolves our most significant byte:-

    DAYS holds our resolved days.
    HOURS and TempHOURS together hold the Hours quotient
    MINUTES and TempMINUTES together hold the Minutes quotient
    SECONDS holds the Seconds quotient

    Now for our least Significant 16 Bits...

    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

    And finally, let’s resolve the issue in it's entirity...

    TempMINUTES=TempMINUTES+(TempSECONDS/60)
    SECONDS=TempSECONDS//60
    TempHOURS=TempHOURS+(TempMINUTES/60)
    MINUTES=TempMINUTES//60
    DAYS=DAYS+(TempHOURS/24)
    HOURS=TempHOURS//24

    So at the end of this, we have DAYS (a word variable which can be used to offset our Reference Point), HOURS, MINUTES and SECONDS, the latter all being BYTE variables. The only clever thing we have used, is a little known system variable called R2 which holds the remainder from a DIV32 execution. Before anyone asks that they've never hear of R2, that little golden nugget on this forum was brought to you by Darrel Taylor in the Code Examples section. Bet nobody's paid attention!

    4. Let’s work through a random example…

    10154 days, 18 Hours, 48 Minutes and 52 seconds… is 877373332 Seconds, which equates to the 32 bit number… $344BA794… (assuming my math serves me correctly)…
    Code:
    	'
    	'	Software Defines
    	'	----------------
    	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
    
    	'
    	'	Enter Test Data
    	'	---------------
    	ByteA=$34
    	ByteB=$4B
    	ByteC=$A7
    	ByteD=$94
    
    	'
    	'	Calculate and Display
    	'	---------------------
    Loop:
    	Gosub CalculateLinearDAYS
    	LCDOut $FE,$01,"Days=",#DAYS
    	LCDOut $FE,$C0,"Time=",DEC2 HOURS,":",DEC2 MINUTES,":",DEC2 SECONDS
    	Pause 1000
    	Goto Loop
    	
    	'
    	'	Calculate Linear DAYS
    	'	---------------------
    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
    	Return
    
    	End
    Does it work? As if you need to ask!

    Now… having got this to work, your hour is up, and JULIAN DATE routines is another story…

    Melanie

  11. #11
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Melanie,

    many thanks for taking the time to teach us in math,
    I like your approach.

    In the meantime I have found a slightly different solution that works.

    But I still feel it takes too much code space and memory.

    After I have cleaned up the code (hopefully tomorrow) I will post my example.

    BTW.
    I followed the discussion" PBP vs. PROTON+"

    I have tried my DWORD calculations using PROTON+
    and feel it does not really help.
    If one writes own double precision math routines in PBP
    the same result can be achieved.
    PROTON+ (and its math routines) do not save any memory or code space
    as they don't (and can't) do any magic.

    best regards:

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

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


    Did you find this post helpful? Yes | No

    Default Converting Linear date to DAY, MONTH, YEAR

    As we all know, Julian Date was fixed by Julius Caesar, this was a guy that played with PICs a lot - and look where it got him. The problem we have is that PBP doesn’t handle Roman Numerals too well, and whilst the idea of having a Linear Date is a good (and very useful) one, generally, we only have to handle the Century that we’re in. So let’s start our PIC’s handling of a Linear Date from 1st January 2000... this way an integer variable (counting in DAYS) can ‘theoretically’ handle over 170 years worth of data.

    Now I don’t know about you, but it’s highly unlikely that any of my designs are still going to be working in the year 2170 (in best engineering tradditions they're only guaranteed to work until the warranty expires), and I’m sure not going to be fielding the tech-support calls. If you find that the date gets screwed past 05/06/2179 (integer value 65534), don't email me - I'm not interested.

    Converting Linear DAYS Back to a Date in the form of YEAR, MONTH and DAY is a little tricky... This is a clumsy way of working out the result, however, the routine I actually use I’m not willing to share, so you’ll have to make do with this one I threw together this morning... starting at January 1 2000 it’s good for almost 180 years (and being a thoughtful kinda girl, I've accounted for the fact that Year 2100 is NOT a Leap Year)...

    The Subroutine shares variables that I've used earlier in this thread, and is called with the Linear Date held in the variable DAYS, and returns with a useable YEAR, MONTH and DAY.

    Code:
    	CounterA var BYTE
    	DAY var BYTE
    	DAYS var WORD
    	MONTH var BYTE
    	TempA var WORD
    	TempB var WORD
    	YEAR var BYTE
    
    	'
    	'	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 
    			If CounterA<>104 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:
    	Lookup2 MONTH,[31,28,31,30,31,30,31,31,30,31,30,31],DAY
    	IF TempA=0 then
    		IF YEAR<>100 then
    			If MONTH=1 then DAY=DAY+1
    			Endif
    		Endif
    	If DAYS>DAY then
    		DAYS=DAYS-DAY
    		MONTH=MONTH+1
    		Goto CalculateMonthLoop
    		Endif
    	MONTH=MONTH+1
    	DAY=DAYS
    	Return
    Melanie

  13. #13
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Melanie,
    thanks again !!

    your code is smaller than my one and I will use it for the DS1994.

    You could save another 79 words of codespace by replacing the LOOKUP2 with LOOKUP.

    Code:
    CalculateMonthLoop:
    	Lookup2 MONTH,[31,28,31,30,31,30,31,31,30,31,30,31],DAY
    Best regards

    Ralph

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


    Did you find this post helpful? Yes | No

    Default

    I originally used LOOKUP2 because my first rough code this morning used the last day of each month cumulative, which means as you get towards the end of the year the DAY spills out of a byte variable, before I changed the code to the version I actually posted, and forgot to change it back.

    You can of course save yourself another 14 words of codespace by not caring that your code runs past year 2100 and removing the century leap-year correction. As if we're going to lose sleep over it...

  15. #15
    Join Date
    Feb 2004
    Location
    Germany
    Posts
    762


    Did you find this post helpful? Yes | No

    Default

    Great,
    those 14 plus another 20 by moving the LOOKUP Table to EEPROM

    regards

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