using DS1307


Closed Thread
Results 1 to 17 of 17

Thread: using DS1307

Hybrid View

  1. #1
    Join Date
    Oct 2009
    Posts
    583

    Default using DS1307

    Following on from my previous threads, the current code for my aquarium controller has been running without issue for the past three days, and has been keeping time very well considering it uses a timer overflow rather than a dedicated time chip like the DS1307 (which the previous version used and kept issuing 10:10:10:10 as the time etc). My new code uses a variable to store a value based on minutes since midnight, and then logic statements are used to determine the phase of the lights (ramp up, on ramp down). This works really well, but as the code is using the internal timers to overflow, the main program loop must be less than the overflow timing, otherwise the clock looses time.

    The alternative is to use a DS1307, and but still do the conversion into minutes since midnight as that has proven to be more reliable than doing direct comparison to matching time in Hrs and Min format. However I only really need the HH:MM segment of the time, and I know that the DS1307 has a long string of info stored that includes month, day, year etc. What would be the best way to write / read the DS1307 so that it only gives the hours and minutes and nothing else.

    This way if I add features which would otherwise delay the cycle and cause the clock to loose time, with the reading of the DS1307 the counter would still be correct.

    The idea is

    Code:
    Counter1 variable word
    
    Read DS1307 to get hours and minutes
    Counter1 = (Hours * 60) + minutes
    
    Do logic of if on time >= counter1 then do something etc
    Last edited by Scampy; - 28th November 2013 at 13:55.

  2. #2
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    The DS1307 keeps each time "segment" in separate registers, you may read only those you need by standard I2C. From the data sheet, the registers you require are 01H and 02H - minutes and hours respectively. The difficulty is only that the values are stored in BCD format. You may work with them directly, but I find it more intuitive to convert them to decimal, so that every calculation may be done with decimal result.

    Below is a snippet from my recent work that reads ALL the DS1337 registers (I am sure they are the same, but '37 is without battery backup) and decodes them to the Debug for verification. You may use the entire code segment or, change the REG_TIM variable to match the first register you require, then collect only two values (as [ MIN, HR]). Also, abbreviate the loop (LP).

    SDA/ SCL = PIN DESIGNATIONS, RTC_ADD = ADDRESS, REG_TIM = BEGINNING REGISTER TO READ, REG_VAL[X] = BCD register value from chip.

    I2CRead SDA, SCL, RTC_ADD, REG_TIM, [REG_VAL[0], REG_VAL[1], REG_VAL[2], REG_VAL[3], REG_VAL[4], REG_VAL[5], REG_VAL[6]]
    FOR LP = 0 TO 6 ' For each register
    D0 = (REG_VAL[LP] >> 4) * 10 ' Decode 10's digit
    D1 = REG_VAL[LP] & %0001111 ' Blank 10's, get 1's
    REG_VAL[LP] = D0 + D1 ' Write Decimal value to register
    NEXT LP ' Next register

    DEBUG "TIME:[", dec1 REG_VAL[3], "] ", dec2 REG_VAL[5], "/", dec2 REG_VAL[4], "/", dec2 REG_VAL[6], " ", dec2 REG_VAL[2], ":", dec2 REG_VAL[1], ":", dec2 REG_VAL[0], 10

    Debug should print TIME:[DOW] MO/DAY/YR HR:MN:SC and each REG_VAL[X] should contain the decimal value of the segment indicated.

    At this point, then... Multiply HR * 60 + MN. Of course I (elsewhere) set my clock to 24 hour mode - or also read the AM/PM bit and add 12 hours as required.

  3. #3
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    Thanks for the info.

    From a previous example I have:

    Code:
    I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]  ; read DS1307 chip
    My question is would I need to read every bit or could I get away with

    Code:
    I2CRead SDApin,SCLpin,$D0,$00,[,RTCMin,RTCHour,,,,,]  ; read DS1307 chip
    How would I get it to ignore the first bit (rtcsec) accept the next two bits and ignore the rest... or doesn't it work that way ?

  4. #4
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    You need not read any that you do not require.

    I2CRead SDApin,SCLpin,$D0,$01,[,RTCMin, RTCHour] ; read DS1307 chip

    Will begin reading at register $01 (note change I made to your code) and collect two registers in the variables (RTCMin, RTCHour) you provided. Like that you have BCD minutes and hours.

    Also, remove the leading comma in the variable list as: [RTCMin, RTCHour]
    Last edited by Amoque; - 28th November 2013 at 15:58.

  5. #5
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    Cheers - Between our replies I found that I could do as you suggested, although I didn't know about the $01 address part. I assume where I had $00 the is the RTCSec bit, so using the $01 tells the code to read from the second bit (RTCMIN) ?

    Thanks for your help

  6. #6
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    Yes, but understand only that where you use the word "bit" is actually a byte. $00 is "%00000000", $01: "%00000000" ... like that. It is how you can read and write the AM/PM bit and read Status bits to verify the clock is running:

    IF RTCHour.6 = 0 then 24H mode enabled.

    Enjoy...

  7. #7
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    Hi,

    Thanks for your help... The following code works fine for just hours and minutes.

    Posted here for reference should anyone else need this.

    18F4520 - running with a 20mhz crystal - 4x20 LCD

    Code:
    ASM 
      __CONFIG    _CONFIG1H, _OSC_HSPLL_1H
      __CONFIG    _CONFIG2L, _PWRT_ON_2L  
      __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
      __CONFIG    _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H  
      __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
    ENDASM
    
    DEFINE  OSC 48  ; config settings 18F4580, 20mhz crystal
    ADCON1 = $0F
    clear
    
    	RTCMin var byte		' Minutes
    	RTCHour var byte	' Hours
    	RTCCtrl var byte	' Control 
                       
    SCLpin var PORTC.3               ' RTC pin - clk
    SDApin var PORTC.4               ' RTC pin - data	
    
    Hours             var byte
    Minutes           var byte	
    
    	CounterA var byte	' General purpose Variable
    	CounterB var byte	' General purpose Variable
    	CounterC var byte	' General purpose Variable
    	CounterD var byte	' General purpose Variable
    	
    	SetMN var byte		' Minutes
    	SetHR var byte	' Hours
    
    
    'analog settings
    
    ADCON0 = 0                      'Set ADCON0
    ADCON1 = %00001111              'Set D i/o
    CMCON = 7                       'Disable Comparators
    
    PR2 = 249 
    '****************************************************************
    'Port settings
    
    CCP1CON = %00001100             ' 
    CCP2CON = %00001100             '     
    TRISA  = %11101111              'set PORTA as all output apart from 0,1,2
    TRISB  = %00000011 
    TRISD  = %00000011              'set PORTB as all output apart from 0&1
    DEFINE LCD_DREG  PORTB           ' LCD Data port
    DEFINE LCD_DBIT  0               ' starting Data bit (0 or 4)
    DEFINE LCD_EREG  PORTB           ' LCD Enable port
    DEFINE LCD_EBIT  5               '     Enable bit  (on EasyPIC 5 LCD)
    DEFINE LCD_RSREG PORTB           ' LCD Register Select port
    DEFINE LCD_RSBIT 4               '     Register Select bit   (on EasyPIC 5 LCD)
    DEFINE LCD_BITS  4               ' LCD bus size (4 or 8 bits)
    DEFINE LCD_LINES 4               ' number of lines on LCD
    DEFINE LCD_COMMANDUS 2000        ' Command delay time in us 
    DEFINE LCD_DATAUS 50             ' Data delay time in us 
    
    setHR = 12
    setMN = 01
    
    '	Save Minutes
    '	------------
    			CounterA=SetMN
    			Gosub ConvertBCD
    			RTCMin=CounterB
    '
    '	Save Seconds
    '	------------
    			CounterA=SetHR
    			Gosub ConvertBCD
    			RTCHour=CounterB
    
    I2cwrite  SDApin,SCLpin,$D0,$01,[RTCMin,RTCHour]  ; read DS1307 chip
    		
    main:		
    I2CREAD SDApin,SCLpin,$D0,$01,[RTCMin,RTCHour]  ; read DS1307 chip
    
    	LCDOut $FE,$80
    If RTCHour.6=1 then
    			
    CounterA=(RTCHour>>4)&$01                           ' Work-Out 12 or 24 hour Display for Hours
    else
    CounterA=(RTCHour>>4)&$03
    endif
    CounterA=CounterA*10+(RTCHour&$0F)                  ' Display Hours appropriately for 12 or 24 hour Mode 
    If RTCHour.6=1 then			
    LCDOut $FE,$D4,#CounterA
    else
    LCDOut $FE,$D4,#CounterA Dig 1,#CounterA Dig 0
    endif
    LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,"   "
    
    	Goto main
    ConvertBCD:
    	CounterB=CounterA DIG 1                        ' CounterA is the entry variable
    	CounterB=CounterB<<4                           ' CounterB holds the converted BCD result on exit
    	CounterB=CounterB+CounterA DIG 0
    	Return
    It's all rough and ready... now to convert the Hours and minutes into the value for a counter and try this in my next version of aquarium lighting

    Thanks for your contribution - steep learning curve but I'm getting there

  8. #8
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    OK, whilst the RTC is working fine with just reading and writing RTCHours and RTCMin, I'm having issues converting the time into minutes so I can use the variable Counter1 to store that value which is then used in the logic within my code to trigger case statements.

    For example 14:00 hrs would equate to 840 minutes as the counter is reset to 00:00 at midnight. 14 * 60 = 840. 14:01 would thus be 841 etc

    I've tried the following

    Code:
    If RTCHour.6=1 then
    			
    CounterA=(RTCHour>>4)&$01                           ' Work-Out 12 or 24 hour Display for Hours
    else
    CounterA=(RTCHour>>4)&$03
    endif
    CounterA=CounterA*10+(RTCHour&$0F)                  ' Display Hours appropriately for 12 or 24 hour Mode 
    If RTCHour.6=0 then			
    LCDOut $FE,$D4,#CounterA
    else
    LCDOut $FE,$D4,#CounterA Dig 1,#CounterA Dig 0
    endif
    LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,"   "
    MM=(RTCMin>>4)&$0F+RTCMin&$0F
    Counter1 = (counterA*60)+MM
    But using this 13:57 gives a value of 784, when it should be 837.... anyone have any suggestions ?

  9. #9
    Join Date
    May 2013
    Location
    australia
    Posts
    2,389


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    you need to put the rtc seconds into your ss var , so the leds can ramp up/down

  10. #10
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    Doh !!!

    I obviously had spent too long looking at this screen...... that's obvious now you've pointed that out... All working now

    Thanks Richard

  11. #11
    Join Date
    May 2013
    Location
    australia
    Posts
    2,389


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    I hope your screen isn't green like your prev post , I nearly went blind trying to read your red and green sections

    cheers richard

  12. #12
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    It appears even fish have something to be thankful for on Thanksgiving!

    As a younger man I kept tropical varieties and had the greatest joy from watching their antics. Reading through your code I imagine a very cool arrangement for lighting that simulates a cycle much more natural than my own habit of turning off the lights at bed time! I can hardly wait for version "2" of your software that incorporates the calendar for seasonal adjustments of daylight hours. Perhaps you think this will not happen, but I think it will - sometime. I recall that keeping fish compelled me always to "futz" with this and improve on that to make their environment more natural and realistic; I think your project shows you are the same? In fact, have you not also thought of the sensors that measure Ph and the devices (Peltier?) that might control heat and cool? Then there is dissolved oxygen, clarity, water level, feeding...

    Congratulations on both the completed project and mastering the skills... I find nothing more satisfying than creation by my own hand; perhaps you are the same in this too?

  13. #13
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: using DS1307

    Another option, depending on real natural light available, is to have the pic learn the
    real daylight cycle so you never have to set the clock.
    This is what some solar controllers with auto night light output do to figure out when
    to turn night lights on and off.
    They are designed to use on remote toilet blocks and such, and would not be subject
    to getting thrown off too much by the home lights being turned on and off.

Similar Threads

  1. ds1307
    By mel4853 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 8th January 2013, 09:46
  2. ds1307
    By jonas2 in forum Code Examples
    Replies: 0
    Last Post: - 2nd November 2009, 09:50
  3. DS1307 on fire
    By brid0030 in forum General
    Replies: 6
    Last Post: - 25th November 2006, 02:44
  4. DS1307 help
    By Orlando in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 17th March 2005, 15:17
  5. Ds1307
    By miniman in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 2nd February 2005, 08:29

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