Closed Thread
Page 2 of 6
First 1 2 3 4 5 6 Last
Results 16 to 30 of 82

Thread: One Wire Temperature sensor (DS1820) to PC interface.

  1. #16
    Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent
    Join Date
    Mar 2005
    Location
    Brisbane Australia
    Posts
    6,773

    Default

    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.


  2. #17
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,511

    Default

    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?

  3. #18
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,511

    Default

    Ok, here's a revised Put232 routine that leaves BitCtr = 0 on exit and still provides perfect 52 usec timing between bit edges.

    Code:
    ;
    ;  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               ;
    

  4. #19
    Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent
    Join Date
    Mar 2005
    Location
    Brisbane Australia
    Posts
    6,773

    Default

    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.

  5. #20
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,511

    Default

    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:
    ;       bcf     BitMask,3       ; do "convert" (BitMask=00000001)
    OwMatch
            OwReset                 ; reset all 1-wire devices
            OwWrite(OwMatchRom)     ; send "match rom" command
            OwWriteBuffer           ; send + print rom serial number
            Send232(' ')            ; send <space> char
            btfsc   BitMask,3       ; conversion complete?
            goto    OwScratch       ; yes, branch, else
            OwWrite(OwConvert)      ; send "convert" command
            OwPowerBus              ; power OW pin during conversion
            Send232(0x0D)           ; send <cr> char (htab 0)
            bsf     BitMask,3       ; indicate conversion complete
            goto    OwMatch         ; do "match rom" for OwScratch
    OwScratch
            OwWrite(OwReadScratch)  ; send "read scratchpad" command
    ;       movlw   9               ; instructions not needed
    ;       movwf   BitMask         ; BitMask = 9 already from above
    RdLoop  OwReadByte              ; read + print scratchpad byte
            decfsz  BitMask,F       ; all 9 bytes read + printed?
            goto    RdLoop          ; no, branch, else
            Send232(0x0D)           ; send <cr> char
            Send232(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:
    OwScratch
            OwWrite(OwReadScratch)  ; send "read scratchpad" command
            OwReadByte              ; read byte 1
            movf    OwByte,W        ;
            movwf   Cels_H          ; save temperature hi
            OwReadByte              ; 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
            OwReadByte              ; read byte 3
            OwReadByte              ; read byte 4
            OwReadByte              ; read byte 5
            OwReadByte              ; read byte 6
            OwReadByte              ; 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 by Mike, K8LH; 23rd January 2009 at 09:41 PM.

  6. #21
    Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent
    Join Date
    Mar 2005
    Location
    Brisbane Australia
    Posts
    6,773

    Default

    Very ingenious, may I suggest you do a multiply by 5 routine (shift left twice and add to original) and call it 3 times as this will keep it in two bytes. I have a Double Dabble routine that will convert it to BCD without the need to do the final multiply by 8. I may have a go at that tomorrow if I get time. The biggest hurdle is RAM.

    I had a play with your code and got rid of the sending the ROM serial twice by checking the "conversion complete" flag in the PowerBus code. I had to clear the DataBit but the result was the same length code as the send cr was two location anyway.

    BTW, I'm sure you need to subtract 4 (¼°) from your extended result.

    Mike.

  7. #22
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,511

    Default

    You mentioned that before and the '1820 Data Sheet also mentions subtracting 0.25 but I haven't quite figured out why.

    Printing the rom ID once is a much better way to do it. Let me study that to see if there's a way to reclaim a byte (grin).

    Your 3 x 5 x Celsius idea is genius but the product will still require 3 bytes, won't it? I'm starting out with a 12 bit number.

    Double-dabble? Sounds familiar. Must check google (grin)...

    Mike
    Last edited by Mike, K8LH; 22nd January 2009 at 05:07 PM.

  8. #23
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,511

    Default

    I think we can still save one byte while printing the rom ID only once. Program size is now 165 bytes.

    Send the <cr> and <lf> newline character pair during the "OwConvert" pass after the OwPowerBus function instead of at the end of the OwMatch code section and print the rom serial number in the OwWriteBuffer function only during the "OwReadScratch" pass.

    Code:
    ;       bcf     BitMask,3       ; do "convert" (BitMask=00000001)
    OwMatch
            OwReset                 ; reset all 1-wire devices
            OwWrite(OwMatchRom)     ; send "match rom" command
            OwWriteBuffer           ; send + print rom serial number
            btfsc   BitMask,3       ; conversion complete?
            goto    OwScratch       ; yes, branch, else
            OwWrite(OwConvert)      ; send "convert" command
            OwPowerBus              ; power OW pin during conversion
            Send232(0x0D)           ; send <cr> char
            Send232(0x0A)           ; send <lf> char
            bsf     BitMask,3       ; indicate conversion complete
            goto    OwMatch         ; do "match rom" for OwScratch
    OwScratch
            OwWrite(OwReadScratch)  ; send "read scratchpad" command
            Send232(' ')            ; send space char
    ;       movlw   9               ; instructions not needed
    ;       movwf   BitMask         ; BitMask = 9 already from above
    RdLoop  OwReadByte              ; read + print scratchpad byte
            decfsz  BitMask,F       ; all 9 bytes read + printed?
            goto    RdLoop          ; no, branch, else
            goto    OwSearchNext    ; search and process next device
    
    Code:
    OwWriteBuffer   macro
            local   loop
            bcf     FSR,3           ; reset FSR = &RomBuffer (0x10)
    loop    movf    INDF,W          ;
            call    Ow.WriteByte    ; send rom serial number byte
            btfsc   BitMask,3       ; OwConvert pass? yes, skip, else
            call    PutHex          ; print rom ID byte as hex
            incf    FSR,F           ;
            btfss   FSR,3           ;
            goto    loop            ;
            endm
    
    Last edited by Mike, K8LH; 22nd January 2009 at 05:31 PM.

  9. #24
    Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent
    Join Date
    Mar 2005
    Location
    Brisbane Australia
    Posts
    6,773

    Default

    Forget the Double Dabble stuff, I realized that the fractional part can be done by multiplying by 10 and taking the high nibble.

    So, calling this 4 times prints the fraction part,
    Code:
    FracDigit
    	movlw	0x0f
    	andwf	TempFrac,F
    	clrc
    	rlf	TempFrac,W	;*2
    	movwf	temp
    	rlf	temp,W		;*4
    	addwf	TempFrac,F	;*5
    	rlf	TempFrac,F	;*10
    	swapf	TempFrac,W
    	goto	PutNybble
    
    Mike.
    Last edited by Pommie; 23rd January 2009 at 09:30 AM.

  10. #25
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,511

    Default

    That routine works extremely well. Bravo!

    So, we just need to do an ABS() function, process and print the 3 digit whole number (-55..125), suppress leading zeros (?), print a decimal point, then process and print and the 4 digit fraction. Correct?

    Can we do all that with 91 free bytes of memory and our limited RAM resources?

  11. #26
    3v0
    3v0 is offline
    3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent
    Join Date
    Jul 2006
    Location
    USA
    Posts
    6,455
    Blog Entries
    11

    Default

    I have not seen this sort of byte hording since collage days. Nice work.
    Please post questions to the forums. PM's are for personal communication.

    BCHS/3v0's Tutorials
    Junebug USB PIC programmer kit., USB Bit Whacker,
    The 15 Minute Printed Circuit Board! (+drill time)

  12. #27
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,511

    Default

    Quote Originally Posted by 3v0 View Post
    I have not seen this sort of byte hording since collage days. Nice work.
    It's Pommie's fault (grin). He posted this fascinating and clever example of what you can do with only 256 words of program memory and 16 bytes of RAM...
    Last edited by Mike, K8LH; 23rd January 2009 at 09:59 PM.

  13. #28
    3v0
    3v0 is offline
    3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent 3v0 Excellent
    Join Date
    Jul 2006
    Location
    USA
    Posts
    6,455
    Blog Entries
    11

    Default

    Hey, I love to watch this. I may build a few when you get it sorted out.

    I have a friend who would like to do some control work but is too tied down with work to get back in to uC's. I would like to drop one of these on his desk and see what happens.

    3v0
    Last edited by 3v0; 23rd January 2009 at 11:09 PM.
    Please post questions to the forums. PM's are for personal communication.

    BCHS/3v0's Tutorials
    Junebug USB PIC programmer kit., USB Bit Whacker,
    The 15 Minute Printed Circuit Board! (+drill time)

  14. #29
    Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent
    Join Date
    Mar 2005
    Location
    Brisbane Australia
    Posts
    6,773

    Default

    I've quite enjoyed this little exercise in optimization. When I first wrote this I was just pleased to get the code in 256 words and then Mike came along and demonstrated just how lax I had been with optimization. Along the way I've learnt some very interesting techniques, although they are probably more academic than useful.

    Anyway, enough of my ramblings, here's a first go at the full decimal part (7 digits ) with absolute and leading zero suppression,
    Code:
    OwMatch
    		OwReset			; reset all 1-wire devices
    		OwWrite(OwMatchRom) 	; send "match rom" command
    		OwWriteBuffer 		; send + print rom serial number
    		btfsc	BitMask,2	; conversion complete?
    		goto	OwScratch	; yes, branch, else
    		OwWrite(OwConvert) 	; send "convert" command
    		OwPowerBus 		; power OW pin during conversion
    		bcf	DataBit
    		bsf	BitMask,2	; indicate conversion complete
    		goto	OwMatch		; do "match rom" for OwScratch
    OwScratch
    		Send232(' ')		; send <space> char
    		OwWrite(OwReadScratch) 	; send "read scratchpad" command
    		OwReadByte 
    		movfw	OwByte
    		movwf	TempLo
    		OwReadByte 
    		movfw	OwByte
    		movwf	TempHi
    ReadLoop
    		OwReadByte 
    		decfsz	BitMask,F
    		goto	ReadLoop
    
    		movf	RomBuffer,W	; get Family ID byte
    		xorlw	0x28		; is it 12 bit DS18B20?
    		bz	OwTemperature	; yes, branch, else
    		rlf	TempLo,F	;                                 |
    		rlf	TempHi,F	;
    		rlf	TempLo,F	;
    		rlf	TempHi,F	;
    		rlf	TempLo,F	;
    		rlf	TempHi,F	;
    		movlw	0xF0		;
    		andwf	TempLo,F	;
    		movlw	16		;
    		movwf	temp		;
    		movf	OwByte,W	; Count_Remain
    		subwf	temp,W		;
    		iorwf	TempLo,F	; now DS18B20 12 bit format
    		movlw	4
    		subwf	TempLo,F
    		skpc
    		decf	TempHi,F
    OwTemperature
    		OwReadByte 
    		OwReadByte 
    
    		Send232	" "
    		btfss	TempHi,7	;is it negative
    		goto	NoNegate
    		Send232	'-'		;Send minus sign
    		comf	TempLo,F	;and negate temperature
    		comf	TempHi,F
    		incfsz	TempLo,F
    		goto	NoNegate
    		incf	TempHi,F
    NoNegate
    		movfw	TempLo		;keep fraction part
    		movwf	TempFrac	;and move it to seperate var
    		movlw	0x0f
    		andwf	TempHi,F	;move nibbles around so
    		swapf	TempLo,F	;that the temperature is 
    		andwf	TempLo,F	;contained in TempLo
    		swapf	TempHi,W
    		iorwf	TempLo,F
    
    		clrf	TempHi		;will contain tens digit
    		movlw	0x100-.100
    		addwf	TempLo,W
    		bnc	NoHundreds
    		movwf	TempLo
    		Send232	'1'
    		bsf	BitMask,0	;no longer suppressing zeros
    NoHundreds
    		movlw	.10
    		subwf	TempLo,F
    		incf	TempHi,F
    		bc	NoHundreds
    		decfsz	TempHi,F	;is it zero
    		goto	PrintIt		;no so print it
    		btfss	BitMask,0	;are we suppressing zeros
    		goto	SkipZero	;yes so skip it
    PrintIt		movlw	'0'
    		addwf	TempHi,W	;print 10s digit
    		call	Put232
    SkipZero	movlw	'0'+10
    		addwf	TempLo,W
    		call	Put232		;always print units digit
    		Send232	'.'
    		call	FracDigit
    		call	FracDigit
    		call	FracDigit
    		call	FracDigit
    
    		Send232(0x0D) 		; send <cr> char
    		Send232(0x0A) 		; send <lf> char
    		goto	OwSearchNext	; search and process next device
    
    FracDigit
    		movlw	0x0f
    		andwf	TempFrac,F
    		clrc
    		rlf	TempFrac,W	;*2
    		movwf	temp
    		rlf	temp,W		;*4
    		addwf	TempFrac,F	;*5
    		rlf	TempFrac,F	;*10
    		swapf	TempFrac,W
    		goto	PutNybble
    
    It now occupies 254 words so we have a full word free.

    Mike.
    P.S. this is what I see in Hyperterminal,

    You can see where I hit them (3 sensors) with a freezing spray.
    Last edited by Pommie; 24th January 2009 at 06:07 AM.

  15. #30
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,511

    Default

    Excellent work! Incredible work!

    I found some 10F206 samples in PDIP-8 package. Can't wait to try this but would like to print leading spaces to align the decimal points.

    Mike

Closed Thread
Page 2 of 6
First 1 2 3 4 5 6 Last

Similar Threads

  1. 74LS174 2-wire LCD interface
    By futz in forum Micro Controllers
    Replies: 30
    Latest: 29th August 2009, 08:49 AM
  2. DS1820 Temp.sensor
    By alpish in forum Micro Controllers
    Replies: 4
    Latest: 27th October 2007, 07:47 PM
  3. circuit ideas on isolated two wire temperature transmitter
    By madhusudan in forum Electronic Projects Design/Ideas/Reviews
    Replies: 1
    Latest: 11th September 2004, 11:59 AM
  4. PIC code Error checking help (DS1820 temp sensor)
    By NewGeek in forum Micro Controllers
    Replies: 11
    Latest: 10th September 2004, 08:42 PM
  5. temperature sensor Dallas DS1820
    By electricano in forum Micro Controllers
    Replies: 0
    Latest: 30th December 2003, 03:13 PM

Tags for this Thread