1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

One Wire Temperature sensor (DS1820) to PC interface.

Discussion in 'Electronic Projects' started by Pommie, Jan 10, 2009.

Thread Status:
Not open for further replies.
  1. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    ONLINE
    Here is a project I worked on a while ago that I’ve finally got around to documenting.

    It interfaces Dallas One Wire (OW) temperature devices to a PC using the smallest Pic chip available, the 10f200. The 10f200 can hold 256 instructions and has 16 bytes of RAM so fitting the OW search algorithm in it was rather challenging. It can also use a 12F509.

    What the device actually does is to interrogate the Dallas chips one at a time, find their ROM IDs, do a conversion and send a string to the PC containing all the information. It is powered from the RS232 port and works with the 2 USB to RS232 converters that I have.

    Here it is with 3 DS13S20s attached. You can attach as many as you like in theory but you will probably have to add an external power supply.
    [​IMG]

    And a closer look,
    [​IMG]

    The Schematic,
    [​IMG]

    Parts list,
    A preprogrammed 10F200 or 12F509.
    2 x 1K resistors
    2 X 10uF electrolitic capacitors
    2 x 0.1uF capacitors
    1 x 1N4148 diode.
    1 x 78L05 voltage regulator

    The board,
    [​IMG]
    I've attached a monochrome image. See below.

    If you run hyperterminal you will get this,
    [​IMG]

    Not very useful and so I’ve written a little VB application to demonstrate how to extract the ROM and temperature information. See below. (anyone familiar with the Dallas devices will recognize the above as the ROM ID followed by the scratch pad area.)

    This is what the VB app does. This is the 3 ROM Ids and temperatures.
    [​IMG]


    The code is rather hard to follow as it uses every trick in the book to minimize ROM and RAM usage. But here it is anyway,
    Code (text):

    ;*******************************************************************
    ;   Title   One Wire temperature reader
    ;   Author  Mike Webb
    ;   Date    10th January 2009
    ;   Pic 10F200 or 12F509
    ;*******************************************************************

        errorlevel  -302,-224
        radix   dec

        #ifdef  __12F509

        include "p12f509.inc"
        __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_ON & _IntRC_OSC

    OW_Bit  equ 4
    RS_Bit  equ 2
    #define DataLow     b'11111111' - (1<<OW_Bit) - (1<<RS_Bit)
    #define DataHigh    b'11111111' - (1<<RS_Bit)
    #define DataBit     GPIO,OW_Bit
    #define b_RS232Out  GPIO,RS_Bit

        cblock  0x10
    RomBuffer:8 ;must be on 16 byte boundary
    temp
    OwByte:0
    Discrepency
    OutByte
    OwCount
    OwFlags
    BitIndex
    OwTemp
    LastDiscrepency
        endc
        endif  


        #ifdef  __10F200

        include "p10f200.inc"
        __CONFIG   _MCLRE_OFF & _CP_OFF & _WDT_ON

    OW_Bit  equ 2
    RS_Bit  equ 0
    #define DataLow     b'11111111' - (1<<OW_Bit) - (1<<RS_Bit)
    #define DataHigh    b'11111111' - (1<<RS_Bit)
    #define DataBit     GPIO,OW_Bit
    #define b_RS232Out  GPIO,RS_Bit

        cblock  0x10
    RomBuffer:8     ;must be on 16 byte boundary
    temp
    OwByte:0    ;shares same location as Discrepency
    Discrepency
    OutByte
    OwCount
    OwFlags
    BitIndex
    OwTemp
    LastDiscrepency
        endc
        endif  


    #define OwSkipRom   0xcc
    #define OwConvert   0x44
    #define OwReadScratchPad    0xbe
    #define OwSearchRom 0xf0
    #define OwMatchRom  0x55

    #define b_OwPresent OwFlags,7
    #define b_ClrBit    OwFlags,6
    #define b_Done      OwFlags,5
    #define b_IsGetBit  OwFlags,4
    #define b_SendRom   OwFlags,3


            org 0

            movwf   OSCCAL
            clrf    7       ;turn of comparators (10f204/6)
    start       movlw   DataHigh    ;release line
            tris    GPIO
            movlw   0xdf        ;make GPIO2 I/O
            option
    First       clrf    LastDiscrepency ;restart search rom
            bcf b_Done     
    Next        bcf DataBit
            btfsc   b_Done      ;Have we completed list
            goto    start       ;Yes so restart
            clrf    BitIndex    ;start at first bit
            call    OwReset
            movlw   OwSearchRom ;Send search rom command
            call    OwWriteByte
            clrf    Discrepency
    GetBits     clrf    OwFlags     ;clear all bit variables
            call    OwReadBit   ;get bit A
            rlf OwFlags,f
            call    OwReadBit   ;get bit B
            rlf OwFlags,f
            movlw   0x03
            xorwf   OwFlags,w   ;If A=1 && B=1 then no devices present
            btfsc   STATUS,Z   
            goto    start       ;Restart
            xorlw   0x03
            btfss   STATUS,Z
            goto    Not00
    ;A=0 and B=0
            movfw   BitIndex
            subwf   LastDiscrepency,w
            btfsc   STATUS,Z
            goto    RomIndexEqualLD
            btfss   STATUS,C
            goto    RomIndexGTLD
            call    GetBit      ;RomIndex < LastDiscrepency
            btfss   STATUS,C
            goto    SetMarker
            goto    SendRomBit
    Not00       btfsc   OwFlags,1   ;set ROM bit to match Bit A
            call    SetBit
            btfss   OwFlags,1
            call    ClrBit
            goto    SendRomBit
    RomIndexGTLD    call    ClrBit      ;RomIndex > LastDiscrepency
    SetMarker   movfw   BitIndex
            movwf   Discrepency
            goto    SendRomBit
    RomIndexEqualLD call    SetBit      ;RomIndex = LastDiscrepency
    SendRomBit  call    GetBit
            call    OwSendCarry
            incf    BitIndex,f
            btfss   BitIndex,6
            goto    GetBits
            movfw   Discrepency
            movwf   LastDiscrepency
            btfsc   STATUS,Z
            bsf b_Done

            bsf b_SendRom   ;this was a subroutine but due to lack of
    OwMatch     call    OwReset     ;stack space it was put in line and a flag
            movlw   OwMatchRom  ;used to indicate the return address
            call    OwWriteByte
            movlw   RomBuffer   ;=0x10 = 0001 0000
            movwf   FSR
    SendRom     movfw   INDF
            call    OwWriteByte
            incf    FSR,F
            btfss   FSR,3       ;bodgey, FSR=0x18
            goto    SendRom
            btfss   b_SendRom
            goto    Continue    ;taken 2nd time around

            movlw   OwConvert
            call    OwWriteByte
            bcf b_SendRom

            bsf DataBit     ;drive data line high by
            movlw   DataLow     ;setting to output for
            tris    GPIO        ;parasitic power devices
            call    Delay1      ;wait for conversion
            movlw   DataHigh    ;release data line
            tris    GPIO        ;by setting to input

    SendSerial  decf    FSR,F       ;FSR=0x18 when entering
            btfss   FSR,4       ;will be clear when FSR=0x0f
            goto    OwMatch
            swapf   INDF,W
            call    SendNibble
            movfw   INDF
            call    SendNibble
            goto    SendSerial

    Continue    movlw   OwReadScratchPad
            call    OwWriteByte
            call    SendSpace
            movlw   0x100-9
            movwf   FSR     ;very dodgey - relies on unused bits being 1
    ReadLoop    call    OwReadByte  ;but no choice as out of RAM!!
            swapf   OwByte,W
            call    SendNibble
            movfw   OwByte
            call    SendNibble
            incfsz  FSR,F      
            goto    ReadLoop
            movlw   0x0d        ;send cr/lf
            call    Send
            movlw   0x0a
            call    Send
            goto    Next        ;go get next rom ID
           
    GetBit      bsf b_IsGetBit  ;Get bit RomBuffer[BitIndex]
            goto    DoBit
    ClrBit      bsf b_ClrBit    ;Clear bit RomBuffer[BitIndex]
            btfss   b_ClrBit
    SetBit      bcf b_ClrBit    ;Set bit RomBuffer[BitIndex]
            bcf b_IsGetBit
    DoBit       rrf BitIndex,W
            movwf   OwTemp
            rrf OwTemp,f
            rrf OwTemp,W
            andlw   0x07
            iorlw   RomBuffer
            movwf   FSR
            movfw   BitIndex
            andlw   0x07
            clrf    OwTemp
            movwf   OwCount
            bsf STATUS,C
    GetBitLoop  rlf OwTemp,f    ;will clear the carry bit
            decf    OwCount,F
            btfss   OwCount,7
            goto    GetBitLoop
            movfw   OwTemp
            btfsc   b_IsGetBit
            goto    DoGetBit    ;carry must be clear
            btfsc   b_ClrBit
            goto    IsClrBit
            iorwf   INDF,f
            retlw   0
    IsClrBit    xorlw   0xff
            andwf   INDF,f
            retlw   0
    DoGetBit    andwf   INDF,w
            btfss   STATUS,Z
            bsf STATUS,C
            retlw   0

    OwReset     movlw   DataLow     ;pull line low
            tris    GPIO
            movlw   .750/4      ;delay 750uS
            movwf   temp
            decfsz  temp,W
            goto    $-2
            movlw   DataHigh    ;release line
            tris    GPIO
        ;   movlw   .68/4       ;delay 68uS
        ;   movwf   temp
        ;   decfsz  temp,W
        ;   goto    $-2
        ;   bcf b_OwPresent
        ;   btfss   DataBit     ;pulled low?
        ;   bsf b_OwPresent ;yes so chip present
        ;   movlw   .480/4      ;delay 480uS
            movlw   .548/4      ;combined times
    ExitDelay   movwf   temp
            decfsz  temp,W
            goto    $-2
            retlw   0

    OwWriteByte movwf   OwByte      ;store byte to write
            movlw   .8      ;send 8 bits
            movwf   OwCount
    OwWriteLoop rrf OwByte,f    ;move bit to carry
            call    OwSendCarry ;send it
            decfsz  OwCount,F   ;sent all bits
            goto    OwWriteLoop ;no, so loop
            retlw   0

    OwReadByte  movlw   .8      ;get 8 bits
            movwf   OwCount
    OwReadByteLoop  call    OwReadBit   ;returns bit in carry
            rrf OwByte,F    ;move carry into byte
            decfsz  OwCount,F   ;finished?
            goto    OwReadByteLoop  ;no, so carry on
            retlw   0

    OwSendCarry btfss   STATUS,C    ;is carry clear
            goto    OwSend0     ;yes, so goto send zero
    OwSend1     movlw   DataLow     ;pull line low
            tris    GPIO
            goto    $+1     ;wait 4uS
            goto    $+1
            movlw   DataHigh    ;release line
            tris    GPIO
    Exit60      movlw   .60/4       ;wait 60uS
            goto    ExitDelay

    OwSend0     movlw   DataLow     ;pull line low
            tris    GPIO
            movlw   .60/4       ;wait 60uS
            movwf   temp
            decfsz  temp,W
            goto    $-2
            movlw   DataHigh    ;release line
            tris    GPIO
            movlw   .4/4
            goto    ExitDelay

    OwReadBit   movlw   DataLow     ;pull line low
            tris    GPIO
            goto    $+1     ;wait 4uS
            goto    $+1
            movlw   DataHigh    ;release line
            tris    GPIO
            movlw   .12/4       ;Wait 12uS
            movwf   temp
            decfsz  temp,W
            goto    $-2
            bcf STATUS,C
            btfsc   DataBit
            bsf STATUS,C
        ;   movlw   .60/4       ;Wait 60uS
            goto    Exit60      ;Delay

    SendSpace   movlw   ' '     ;0x20
            goto    Send

    SendNibble  andlw   0fh     ;keep lower nibble
            movwf   temp        ;save for later
            movlw   0x100-10    ;test if greater
            addwf   temp,W      ;than 10
            movlw   "0"     ;add "0"
            btfsc   STATUS,C    ;or, if greater than 10
            movlw   "0"+7       ;add "A"-10
            addwf   temp,W      ;do add and fall through to send it
       
    Send        movwf   OutByte     ;sends data inverted so no MAX232 needed
            bsf b_RS232Out  ;start bit
            call    BitDelay
            bsf STATUS,C    ;will be first stop bit
    SendLoop    rrf OutByte,F   ;move bit to carry
            bsf b_RS232Out
            btfsc   STATUS,C
            bcf b_RS232Out
            call    BitDelay
            bcf STATUS,C    ;ensure 0 shifted into outbyte
            movfw   OutByte     ;will be zero when 8 bits + 1 stop bit sent
            btfss   STATUS,Z
            goto    SendLoop
            bcf DataBit     ;ensure data line is low

    ;fall through for second stop bit.

    ; at 1 meg instructions and 9600 baud
    ; delay is 1,000,000/9600 = 104 cc
    ; the calling loop and the call/return = 13
    ; therefore delay needs to be 91 cycles

    BitDelay    movlw   .30
            movwf   temp
    DelayLoop   decfsz  temp,F;     (3*30)-1 = 89 + 2 = 91
            goto    DelayLoop
            clrwdt          ;kick the dog
            retlw   0

    Delay1      clrf    OwTemp      ;approx 1 second delay
            movlw   .40
            movwf   OwCount
    del     call    BitDelay
            decfsz  OwTemp,F
            goto    del
            decfsz  OwCount,F
            goto    del
            retlw   0



        if  ($>0xff)
        messg   "Memory Overflow"
        endif
        end
     
    Note, it is essential that the pic has the correct oscillator calibration value so use a new one or recalibrate it with the Pickit2 software.

    The attachments are the VB files, Hex files and board image.

    Mike.
     

    Attached Files:

    • Like Like x 1
  2. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    Nice project and execptional post.
    A demo of how handy the little pics can be,
    and your asm skill too :D
     
  3. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,641
    Likes:
    109
    Location:
    Michigan, USA
    Hi Mike,

    A very impressive effort. Thank you for sharing.

    I've not implemented the ROM Search algorithm and so I'm looking forward to studying your code.

    Regards, Mike
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    ONLINE

    Hi Mike,

    Maxim have a very good explanation of the search ROM algorithm in this document. My implementation above is very convoluted (spaghetti like) mainly due to the stack limitations. I also gave up trying to comment the search part as it really needs a whole paragraph per 4 lines of code and it's easier to refer people to the document (which I forgot to do). Anyway, have fun trying to untangle that web of code.:D

    Mike.
     
  6. BeeBop

    BeeBop Active Member

    Joined:
    Dec 22, 2005
    Messages:
    1,281
    Likes:
    23
    Location:
    Vancouver Canada
    Really nice, thanks for sharing Mike!

    Isn't documentation always the tough part. :D

    Well done!
     
  7. nickelflippr

    nickelflippr Member

    Joined:
    Oct 20, 2006
    Messages:
    891
    Likes:
    18
    Location:
    Oregon, USA
    Great job!! Fully documented projects like yours are such a rare commodity, Thanks. There's a lot going on for such a little device.

    By coincidence, there are a couple of 10F's from Newark coming my way very soon. Now, to put on my assembly deciphering hat.
     
  8. Gayan Soyza

    Gayan Soyza Active Member

    Joined:
    Oct 23, 2006
    Messages:
    1,821
    Likes:
    19
    Location:
    Colombo
    Very nice job.Power also from serial port, thats nice too.........:)
     
  9. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,641
    Likes:
    109
    Location:
    Michigan, USA
    Mike (Pommie),

    Thank you again for sharing your project. I think (hope) I'm getting a handle on the search algorithm thanks to your example and the Maxim application note and I'm taking a stab at optimizing the code a bit and organizing it in a way that's more intuitive for me.

    If you get a chance could you take a peek at the following excerpt and tell me if it makes sense? The program is about 45 bytes smaller so far and I was able to eliminate the OwFlags variable and its flag bits as well as the GetBit, SetBit, and ClrBit routines.

    Thanks. Take care. Mike

    Code (text):
    First
            clrf    LastDiscrepency ; restart search rom
    Next
            bcf     DataBit         ; clear 1-wire port latch
            clrf    BitIndex        ; start at first bit
            clrf    LastZero        ;
            movlw   RomBuffer       ;
            movwf   FSR             ; FSR = &RomBuffer
            movlw   1               ;
            movwf   BitMask         ; reset rom array bit mask
            call    OwReset         ;
            OwSend (OwSearchRom)    ; send "search rom" command
    GetBits
            clrf    OwTemp          ;
            call    OwReadBit       ; get bit A
            rlf     OwTemp,F        ; F = -------A
            call    OwReadBit       ; get bit B
            rlf     OwTemp,W        ; W = ------AB
            xorlw   0x03            ; AB == 11, no devices present?
            bz      start           ; yes, branch (restart), else
            xorlw   0x03            ; AB == 00, discrepency?
            bnz     SendRomBit      ; no, branch (use 'A' bit), else
    Discrepency
            bsf     OwTemp,0        ; set 'A' bit to '1'
            movf    BitIndex,W      ; 0..63
            subwf   LastDiscrepency,W
            bnc     IndexGTLD       ;
            bz      SendRomBit      ; set rom bit to '1'
    IndexLTLD
            movf    BitMask,W       ; get ROM bit
            andwf   INDF,W          ; is ROM bit '0'?
            bnz     SendRomBit      ; no, branch, use '1', else
    IndexGTLD
            bcf     OwTemp,0        ; set 'A' bit to '0'
            movf    BitIndex,W      ;
            movwf   LastZero        ; update LastZero
    SendRomBit
            rrf     OwTemp,F        ; put 'A' bit into Carry
            movf    BitMask,W       ; set ROM bit to bit 'A'
            iorwf   INDF,F          ; set ROM bit (unconditionally)
            skpc                    ; is bit a '1'? yes, skip, else
            xorwf   INDF,F          ; clr ROM bit
            call    OwSendCarry     ; send direction/qualifier bit
            rlf     BitMask,W       ;
            rlf     BitMask,F       ; advance rom array bit mask
            skpnc                   ; all 8 bits done? no, skip, else
            incf    FSR,F           ; bump RomBuffer array address
            incf    BitIndex,F      ; bump bit index, 0..63
            btfss   BitIndex,6      ; BitIndex = 64?  yes, skip, else
            goto    GetBits         ; do next bit
            movf    LastZero,W      ;
            movwf   LastDiscrepency ; update last discrepency
    ;
    ;  we now have a qualified 64 bit ROM serial number
    ;
    OwMatch
     
     
    Last edited: Jan 12, 2009
  10. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    ONLINE
    That looks like it should work. I like the way you've kept FSR current rather than recalculating it each bit. I don't have the equipment setup at the moment to test it but can probably try it later. Are you able to test it?

    I'm looking forward to seeing the complete code.

    Edit, Did you realise that Discrepancy (LastZero) and OWByte share the same RAM location hence why I cleared Discrepancy after sending OWSearchRom.

    Mike.
     
    Last edited: Jan 12, 2009
  11. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,641
    Likes:
    109
    Location:
    Michigan, USA
    I won't be able to test it for a few days but then I'm still workin' on it. There are lots of changes like the SendCarry routine below.

    Yes, I think I figured out your local and global variables. I changed them around a bit to fit the new structure.

    I can't tell you how geeked I am to try this routine on a couple projects.

    Thank you, thank you, thank you...

    Mike

    Code (text):
    OwSendCarry
            movlw   DataLow         ;
            tris    GPIO            ; initiate write slot
            skpnc                   ; send 0 bit
            movlw   DataHigh        ; send 1 bit
            tris    GPIO            ;
            movlw   .60/4           ; finish 60 usec slot
            movwf   temp            ;
            decfsz  temp,W          ;
            goto    $-2             ;
            movlw   DataHigh        ;
            tris    GPIO            ; release bus
            retlw   0               ;
     
     
    Last edited: Jan 12, 2009
  12. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    ONLINE
    I still had the breadboard with a SOT-23 10F200 on it and just incorporated your code. It worked first time and occupies 0xc4 locations - less than 200.

    Mike.
     
  13. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,641
    Likes:
    109
    Location:
    Michigan, USA
    Hi Mike (Pommie),

    I attached my crude unpolished 168 byte version of your program below just in case you might be interested. It's probably a reasonably good example of optimization and the problems that the subtle dependencies may cause.

    Here's my version of your OwMatch code section. I used some macros to hide detail and hopefully make it easier to follow the logic and program flow. I used your flag method to reuse the MatchRom code for both the "Convert" and "Read Scratchpad" operations but I used my BitMask variable for the flag since BitMask always equals '00000001' when we fall out of the "OwSearch" code into the "OwMatch" code.
    Code (text):
    ;       bsf     BitMask,0       ; do "convert" (bit = 1 already)
    OwMatch
            [COLOR=DarkOrchid]OwReset[/COLOR]                 ; reset all 1-wire devices
            [COLOR=DarkOrchid]OwWrite[/COLOR](OwMatchRom)     ; send "match rom" command
            [COLOR=DarkOrchid]OwWriteBuffer[/COLOR]           ; send + print rom serial number
            [COLOR=DarkOrchid]Send232[/COLOR](' ')            ; send <space> char
            btfss   BitMask,0       ; conversion complete?
            goto    OwScratch       ; yes, branch, else
            [COLOR=DarkOrchid]OwWrite[/COLOR](OwConvert)      ; send "convert" command
            [COLOR=DarkOrchid]OwPowerBus[/COLOR]              ; power OW pin during conversion
            [COLOR=DarkOrchid]Send232[/COLOR](0x0D)           ; send <cr> char (htab 0)
            bcf     BitMask,0       ; indicate conversion complete
            goto    OwMatch         ; do "match rom" for OwScratch
    OwScratch
            [COLOR=DarkOrchid]OwWrite[/COLOR](OwReadScratch)  ; send "read scratchpad" command
            movlw   -9              ;
            movwf   FSR             ; use FSR as byte counter
    RdLoop  [COLOR=DarkOrchid]OwReadByte[/COLOR]              ; read + print scratchpad byte
            incfsz  FSR,F           ; all 9 bytes read + printed?
            goto    RdLoop          ; no, branch, else
            [COLOR=DarkOrchid]Send232[/COLOR](0x0D)           ; send <cr> char
            [COLOR=DarkOrchid]Send232[/COLOR](0x0A)           ; send <lf> char
            goto    OwSearchNext    ; search and process next device
     
    Another subtle dependency is that my Send232() routine always forces the OW pin latch bit in GPIO to '0' so I saved one instruction in my OwPowerBus code by omitting that instruction after powering the bus for 1 second. But this means you have to print something after performing the OwPowerBus operation and before trying to write something else on the OW bus. These kind of dependencies will easily get you into trouble when you try to modify the program.

    One program difference worth mentioning is that the OwWriteBuffer code also sends each byte to the serial port. This results in the rom serial number being printed twice but I send a <cr> character after the "OwConvert" operation so the second instance of the rom serial number printout should print on top of the first instance. This should work fine for Hyperterminal but if you're using an application then it will need to ignore the first 17 characters after detecting each <newline> (<cr>+<lf>) sequence.

    Now I'm wondering if 88 bytes of free memory might be enough for adding code to print the temperature as a decimal number?

    Regards, Mike
     

    Attached Files:

    Last edited: Jan 22, 2009
  14. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    ONLINE
    Hi Mike,

    I've been playing with your code but I can't get it working. I had to add an extra stop bit to the RS232 routine to get sensible data but I don't seem to be getting a correct ROM address.

    This is what I'm getting in Hyperterminal,
    Code (text):

    0100000000000080 000000000000000000
    0100000000000040 000000000000000000
    01000000000000C0 000000000000000000
    0100000000000020 000000000000000000
    01000000000000A0 000000000000000000
    0100000000000060 000000000000000000
    01000000000000E0 000000000000000000
    0100000000000010 000000000000000000
    0100000000000090 000000000000000000
    0100000000000050 000000000000000000
     
    It looks like it's taking the discrepancy path when there isn't one but I can't figure it out.

    Also, I found a problem in the OwScratch routine, FSR has to be -9 and incremented as the unused bits of FSR are set to 1.

    I'l have another play later and see if I can figure anything out.

    Do you have hardware to test this? Did it work? Have you any ideas why I'm getting strange results?

    BTW, some great code saving ideas there. I'm not sure the decimal part will be possible but look forward to trying.

    Mike.
     
  15. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,641
    Likes:
    109
    Location:
    Michigan, USA
    Thanks for checking it out Mike.

    I'll keep working on the code and look for those errors.

    Did you notice my serial code was 19200 baud instead of 9600 baud?

    I wonder if there's a problem with my modified OwReadBit routine?

    I don't have hardware to test this code yet.

    Mike
     
    Last edited: Jan 20, 2009
  16. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    ONLINE
    Mike,

    For a sanity check I just reverted to the code from the first post and I'm getting the same results so I suspect my hardware is at fault.

    <edit> one of the outer pins (DS1820) had shorted to the middle pin. No wonder I couldn't get any sense out of it. I'll try your code again and get let you know.</edit>
    <edit2> You code works with the mod to OwScratch and the extra stop bit. Extremely nice piece of code. Now for the decimal bit!!</edit2>

    Mike.
     
    Last edited: Jan 23, 2009
  17. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    ONLINE
    Mike,

    The data I was receiving for the scratch area was wrong, I tracked it down to the bsf BitCtr,3 in OwReadByte. It failed because Send232 leaves BitCtr containing 1. Took me a while to spot that ,W on the end of it. Shortening the loop makes the timing better anyway.

    Mike.
     
  18. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,641
    Likes:
    109
    Location:
    Michigan, USA
    Good catch. One of those darned optimization dependencies. I modified OwReadByte to correct the problem. Program is now 169 bytes.

    What do you mean by "shortening the loop makes the timing better"? That Put232 subroutine has perfect 52 usec bit timing with absolutely no jitter. Also wondering why do you need two stop bits?
     
  19. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,641
    Likes:
    109
    Location:
    Michigan, USA
    Ok, here's a revised Put232 routine that leaves BitCtr = 0 on exit and still provides perfect 52 usec timing between bit edges.

    Code (text):
    ;
    ;  19200 baud, exact 52-usec bit timing (4 MHz)
    ;
    Put232  bsf     GPIO,RS_Bit     ; send start bit
            movwf   OwTemp          ; save Tx data
            movlw   9               ; 8 data bits + 1 stop bit
            movwf   BitCtr          ; update bit counter
    PutBit  setc                    ; shift in stop bits
            movlw  (52-8)/4         ; 52 usecs - 8 usec loop time
            movwf   temp            ; a 4 cycle / 4 usec loop
            decfsz  temp,W          ; W == 0? yes, skip, else
            goto    $-2             ; loop
            rrf     OwTemp,F        ; put data bit in C (W = 0)
            skpc                    ; a '1' bit? yes, skip, else
            iorlw   1<<RS_Bit       ; send a '0', W = 1<<RS_Bit
            movwf   GPIO            ; send bit, clear OW DataPin
            decfsz  BitCtr,F        ; all 9 bits? yes, skip, else
            goto    PutBit          ; send next bit
            retlw   0               ;
     
     
  20. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    ONLINE
    Hi mike,

    I should have mentioned that I had already moved the setc into the loop to enable it to send two stop bits and so moving the label down one line brought it back to 52 cycles. If I don't send two stop bits then I get corruption in Hyperterminal.

    Mike.
     
  21. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,641
    Likes:
    109
    Location:
    Michigan, USA
    Yeah, I should have figured you did that.

    Thanks for telling me about how the unused bits behave in the FSR register.

    Got the program down to 166 bytes now. I used bit 3 in the BitMask variable for the "conversion complete" flag which leaves BitMask preset to 9 for use as the byte counter in the "Read Scratchpad" section. It saves two bytes. Check it out;

    Code (text):
    ;       bcf     BitMask,3       ; do "convert" (BitMask=00000001)
    OwMatch
            [COLOR=Blue]OwReset[/COLOR]                 ; reset all 1-wire devices
            [COLOR=Blue]OwWrit[/COLOR]e(OwMatchRom)     ; send "match rom" command
            [COLOR=Blue]OwWriteBuffer[/COLOR]           ; send + print rom serial number
            [COLOR=Blue]Send232[/COLOR](' ')            ; send <space> char
            btfsc   BitMask,3       ; conversion complete?
            goto    OwScratch       ; yes, branch, else
            [COLOR=Blue]OwWrite[/COLOR](OwConvert)      ; send "convert" command
            [COLOR=Blue]OwPowerBus[/COLOR]              ; power OW pin during conversion
            [COLOR=Blue]Send232[/COLOR](0x0D)           ; send <cr> char (htab 0)
            bsf     BitMask,3       ; indicate conversion complete
            goto    OwMatch         ; do "match rom" for OwScratch
    OwScratch
            [COLOR=Blue]OwWrite[/COLOR](OwReadScratch)  ; send "read scratchpad" command
    ;       movlw   9               ; instructions not needed
    ;       movwf   BitMask         ; BitMask = 9 already from above
    RdLoop  [COLOR=Blue]OwReadByte[/COLOR]              ; read + print scratchpad byte
            decfsz  BitMask,F       ; all 9 bytes read + printed?
            goto    RdLoop          ; no, branch, else
            [COLOR=Blue]Send232[/COLOR](0x0D)           ; send <cr> char
            [COLOR=Blue]Send232[/COLOR](0x0A)           ; send <lf> char
            goto    OwSearchNext    ; search and process next device
     
    On a newer version of the program I added code to detect DS1820 and DS18S20 devices and to convert their 9 bit temperature word to the DS18B20 12 bit format (1/16th degree resolution);

    Code (text):
    OwScratch
            [COLOR=Blue]OwWrite[/COLOR](OwReadScratch)  ; send "read scratchpad" command
            [COLOR=Blue]OwReadByte[/COLOR]              ; read byte 1
            movf    OwByte,W        ;
            movwf   Cels_H          ; save temperature hi
            [COLOR=Blue]OwReadByte[/COLOR]              ; read byte 2
            movf    OwByte,W        ;
            movwf   Cels_L          ; save temperature lo
            movf    RomBuffer,W     ; get Family ID byte
            xorlw   0x28            ; is it 12 bit DS18B20?
            bz      OwTemperature   ; yes, branch, else
            [COLOR=Blue]OwReadByte[/COLOR]              ; read byte 3
            [COLOR=Blue]OwReadByte[/COLOR]              ; read byte 4
            [COLOR=Blue]OwReadByte[/COLOR]              ; read byte 5
            [COLOR=Blue]OwReadByte[/COLOR]              ; read byte 6
            [COLOR=Blue]OwReadByte[/COLOR]              ; read byte 7, Count_Remain
            rlf     Cels_L,F        ;                                 |
            rlf     Cels_H,F        ;
            rlf     Cels_L,F        ;
            rlf     Cels_H,F        ;
            rlf     Cels_L,F        ;
            rlf     Cels_H,F        ;
            movlw   0xF0            ;
            andwf   Cels_L,F        ;
            movlw   16              ;
            movwf   temp            ;
            movf    OwByte,W        ; Count_Remain
            subwf   temp,W          ;
            iorwf   Cels_L,F        ; now DS18B20 12 bit format
    OwTemperature
     
    Now I'm trying to add a sign extended 8x16 multiply routine which will produce a 3 byte sign extended binary result of C° * 1000 (3 decimal places with a value ranging from -55000 to 125000); C° * 1000 = 125 * (Celsius16) / 2

    Regards, Mike
     
    Last edited: Jan 23, 2009
Thread Status:
Not open for further replies.

Share This Page