Clock and Dual Termometer


Closed Thread
Results 1 to 25 of 25

Hybrid View

  1. #1
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    582


    Did you find this post helpful? Yes | No

    Default

    If DS18B20 it's in 9 bit mode, the clock run faster (!) with ~ 2 sec/hour (5 sec in 3 hours).

  2. #2
    Join Date
    Oct 2004
    Posts
    448


    Did you find this post helpful? Yes | No

    Default

    Thats about .055%; you ARE using a crystal, not a resonator, right?

    Anand

  3. #3
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    582


    Did you find this post helpful? Yes | No

    Default

    Yes, I use a crystal. But, without code for DS18B20, the clock run correct (~ 1 sec/day).

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default

    Hi,
    If I read this correctly you have an interrupt frequency of 61.035Hz (prescaler 1:64, 256*64=16384, 1/0.016384=61.035Hz) when you ideally should have 61Hz - that's 0.057% off and as Anand says 2 seconds over one hour is 0.055%.

    I currently have no idea why it starts running correct when you remove the DS1820 code - are you sure that's the case?

  5. #5
    Join Date
    Oct 2004
    Posts
    448


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HenrikOlsson View Post
    that's 0.057% off and as Anand says 2 seconds over one hour is 0.055%.
    Closer to .056, actually since its .055555.. So, you might me spot on..

    Anand

  6. #6
    Join Date
    Dec 2008
    Location
    Ploiesti, ROMANIA
    Posts
    582


    Did you find this post helpful? Yes | No

    Default

    Somebody, in a forum of my country, propose this code. It' work ok, just 1 sec/hour faster !
    Code:
    @ __config _XT_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF
    
    define OSC 4
    TRISA= %11111000                       ' RA0..3=Outputs RA4=Input
    TRISB= %00001111              ' RB0..RB2=Inputs, RB3..RB7=Outputs
    CMCON=7                                     ' Disable comparators
    OPTION_REG=%00000111
    
    
    DEFINE LCD_DREG PORTB               ' LCD on port B
    DEFINE LCD_DBIT 4                        ' Data bits B4..B7
    DEFINE LCD_RSREG PORTA            ' RS on PORTA
    DEFINE LCD_RSBIT 1                     ' RS on A1
    DEFINE LCD_EREG PORTA              ' E on PORTA
    DEFINE LCD_EBIT 0                       ' E on A0
    DEFINE LCD_BITS 4                      ' LCD 4 bit mode
    DEFINE LCD_LINES 2                     ' 2 line LCD display
    
    wsave   VAR BYTE    $70     SYSTEM
    TempC           var     word
    Float           var     word
    Sign          var   bit         ' +/- sign
    DQ          var     PORTA.4      ' One-wire data pin
    TempC2          var     word
    Float2          var     word
    Sign2          var   BIT         ' +/- sign
    DQ2          var     PORTA.3      ' One-wire data pin
    Delay           var     byte
    Mode            var     byte
    semn          var     word
    semn2           var     word
    
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System ; Attention ! Modified file !
    INCLUDE "ReEnterPBP.bas"
    
    DS18B20_1_12bit CON %00011111          ' NOW 9 BIT
    DS18B20_2_12bit CON %00011111          ' NOW 9 BIT
    
    
    Ticks      var   byte                   ; Tick count (61 ticks=1 sec)
    Hour      var   byte             ; Hour variable
    Minute   var   byte                   ; Minute variable
    Second   var   byte               ; Second variable
    ZIUA        var   byte
    LUNA        var   byte    
    Disp      var   BIt                   ; Disp=1 to update display
    
    PAUSE 500                   ; Wait 0.5sec for LCD to initialize
    
    Hour=0 : Minute=0 : Second=0
    Ticks=0  : ZIUA=01 : LUNA=01
    
    
    
    
    
    
    ' Init Sensor 1
    OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_1_12bit]
    OWOut DQ, 1, [$CC, $48]             
    OWOut DQ, 1, [$CC, $B8]
    OWOut DQ, 1, [$CC, $BE]
    Pause 50
    OWIn DQ, 2, [TempC.byte0, TempC.byte1]
    Pause 50
    ' Init Sensor 2
    OWOUT DQ2, 1, [$CC, $4E, 0, 0, DS18B20_2_12bit]
    OWOut DQ2, 1, [$CC, $48]             
    OWOut DQ2, 1, [$CC, $B8]
    OWOut DQ2, 1, [$CC, $BE]
    Pause 50
    OWIn DQ2, 2, [TempC2.byte0, TempC2.byte1]
    Pause 50
    OPTION_REG=$05                ; Set prescaler
    INTCON=$A0                   ; Enable TMR
    ASM
    INT_LIST  macro                ; IntSource,   Label,  Type, ResetFlag?
            INT_Handler     TMR0_INT,  _ISR,   PBP,  yes
        endm
        INT_CREATE                ; Creates the interrupt processor
    ENDASM
                       
    @   INT_ENABLE   TMR0_INT
    
    LCDOUT $FE, 1                   ; Clear LCD
    LOOP:
    
    If PORTB.0=0 then                       ' Mode switch preSeconded
         Pause 50                          ' Debounce
       LcdOut $FE, 1
       LcdOut $FE, $C0, "         SETTING"    ' Show that coMinuteand is accepted
       PAUSE 500
       LcdOut $FE, 1
    If PORTB.0=0 then Loop                  ' Wait until button is released 
      Mode=Mode+1                           ' Increment mode
    ENDIF
    
    
    If Mode=1 then                          ' SET HOUR
    LcdOut $FE, $80, dec2 Hour
    LcdOut $FE, $C0, "HOUR     SETTING"
       if portb.1=0 then
          Hour=Hour+1
            IF Hour=24 then
              Hour=0
            ENDIF
          Gosub Debounce
       endif
    
       if portb.2=0 then
            IF Hour = 0 then
              Hour=24
            ENDIF
          Hour=Hour-1
          Gosub Debounce
       endif
    EndIf
    
    If Mode=2 then                          ' SET MINUTES
    LcdOut $FE, $80, dec2 Hour,":",dec2 Minute
    LcdOut $FE, $C0, "MINUTES  SETTING"       
    
       if portb.1=0 then
          Second=0                       
          Minute=Minute+1
            IF Minute=60 THEN
              Minute=0
            ENDIF
          Gosub Debounce
       endif
    
       if portb.2=0 then
          Second=0                       
            IF Minute =<0 THEN
              Minute=60
            ENDIF
          Minute=Minute-1
       Gosub Debounce
       endif
    EndIf
    
    If Mode=3 then                          ' SET DAY
    LcdOut $FE, $80, dec2 Hour,":",dec2 Minute,":",dec2 Second,"   ",DEC2 ZIUA,"/"
    LcdOut $FE, $C0, "DAY      SETTING"
       if portb.1=0 then
          ziua=ziua+1
                IF LUNA=2 THEN
                      IF ZIUA > 28 THEN
                      ZIUA=1
                      ENDIF
                ENDIF
                IF LUNA=4 OR LUNA=6 OR LUNA=9 OR LUNA=11 THEN 
                      IF ZIUA > 30 THEN ZIUA=1
                      ELSE
                      IF ZIUA > 31 THEN ZIUA=1
                      ENDIF
          Gosub Debounce
       endif
    
       if portb.2=0 then
          ZIUA=ZIUA-1
                IF ZIUA = 0 THEN ZIUA=31
          Gosub Debounce
       endif
    EndIf
    
    If Mode=4 then                           ' SET MONTH
    LcdOut $FE, $80, dec2 Hour,":",dec2 Minute,":",dec2 Second,"   ",DEC2 ZIUA,"/",DEC2 LUNA
    LcdOut $FE, $C0, "MONTH    SETTING"
       if portb.1=0 then
          luna=luna+1
                if luna>12 then
                luna=1
                endif
          Gosub Debounce
       endif
    
       if portb.2=0 then
          luna=luna-1
                if luna<1 then
                luna=12
                endif
          Gosub Debounce
       endif
    EndIf
    
    If Mode > 4 then
       LCDOUT $FE, $C0, "END      SETTING"
       PAUSE 100
        LCDOUT $FE, 1, $FE, $0C
       mode=0
    EndIf
    If Mode > 0 then Loop               
    IF Disp=1 THEN
    
    LcdOut $FE, $80, DEC2 Hour, ":",DEC2 Minute, ":",DEC2 Second,"   ",DEC2 ZIUA,"/",DEC2 LUNA
    
    LCDOUT $FE, $C0, semn,DEC ABS TempC/100,".", DEC1 ABS TempC/10, 223,"C ", $FE, $C0 + 9, semn2,DEC ABS TempC2/100,".", DEC1 ABS TempC2/10, 223,"C   "
    
    Disp=0
    ENDIF
    
    GOTO LOOP
    
    @   INT_DISABLE   TMR0_INT
    ISR:
    Ticks=Ticks + 1
    IF Ticks < 61 THEN NoUpdate
    Ticks=0
    Second=Second + 1          ; Update second
    IF Second=60 THEN
    Second=0
    Minute=Minute + 1          ; Update Minute
    IF Minute=60 THEN
    Minute=0
    Hour=Hour + 1             ; Update Hour
    IF Hour=24 THEN
    Hour=0
    ZIUA=ZIUA+1
              IF LUNA=2 THEN
                   IF ZIUA > 28 THEN
                        ZIUA=1
                        LUNA=3
                        ENDIF
              ENDIF
           
              IF LUNA=4 OR LUNA=6 OR LUNA=9 OR LUNA=11 THEN 
                   IF ZIUA > 30 THEN
                        ZIUA=1
                        LUNA=LUNA+1                             
                        ENDIF
                   ENDIF
         
              IF LUNA=1 OR LUNA=3 OR LUNA=5 OR LUNA=7 OR LUNA=8 OR LUNA=10  THEN
                   IF ZIUA > 31 THEN
                        ZIUA=1
                        LUNA=LUNA+1
                   ENDIF                             
              ENDIF           
    
             IF LUNA=12 THEN
                   IF ZIUA > 31 THEN
                        ZIUA=1
                        LUNA=1
                   ENDIF
              ENDIF           
    ENDIF
    ENDIF
    ENDIF
    Gosub Read_temp
    Disp=1                ; Set to update display
    
    
    NoUpdate:
    INTCON.2=0                ; Re-enable TMR0 interrupts
    @ INT_RETURN                ; Re-enable interrupts
    END
    
    
    ;=================================
    ;Subrutine
    
    Debounce:
    FOR Delay=1 To 200
    Pause 1                ; Delay 1ms inside a loop. This way,
    NEXT Delay                ; timer interrupts are not stopped
    Disp=1                ; Set display flag to 1
    RETURN
    ;==================================
    Read_Temp:
        OWOut DQ, 1, [$CC, $44]
        OWOut DQ, 1, [$CC, $BE]
        OWIn  DQ, 2, [TempC.byte0, TempC.byte1]         
    
        Sign = TempC.15
        TempC = ABS(TempC)
        TempC = ((TempC >> 4)*100) + ((TempC & $F)*100 >> 4)
        IF Sign THEN TempC = -TempC
    IF TempC.15 THEN
    Semn="-"
    else
    Semn="+"
    endif
    
        OWOut DQ2, 1, [$CC, $44]
        OWOut DQ2, 1, [$CC, $BE]
        OWIn  DQ2, 2, [TempC2.byte0, TempC2.byte1]         
    
        Sign2 = TempC2.15
        TempC2 = ABS(TempC2)
        TempC2 = ((TempC2 >> 4)*100) + ((TempC2 & $F)*100 >> 4)
        IF Sign2 THEN TempC2 = -TempC2
    IF TempC2.15 THEN
    Semn2="-"
    else
    Semn2="+"
    endif
    Return
    ;=====================================
    
    END                   ; End of program

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default

    Great - as long as it works for your needs.

    But you can't get away from the fact that you're interrupting at 61.035Hz while it ideally should be 61Hz. That little difference WILL make it run fast.

    Let's see.... For a duration of 100.000 interrupts a time of 100,000/61.035=1638.40 seconds have passed. Your code, because it divides by 61, will "display" 1639.34 seconds (the clock runs fast).

    Here's an idea... If you keep a second WORD sized tick counter incrementing in your ISR and when it hits 1754 you reset it to zero and skip updating your normal Ticks variable for that interrupt only. This way, in 100,000 interrupts you'll only increment your Ticks variable 100,000 - (100,000/1754) = 99943 times, resulting in "time" of 99943/61 = 1638.40 seconds - pretty darn close to ideal. The clock will zig-zag a little bit but the period is only about 28 seconds so I don't think you'll notice.

    It's still early here, I may have made some terrible misstake in the math (doesn't have to be early for that). Anyway, it's an idea you may want to look into.

    /Henrik.

Members who have read this thread : 0

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