1.
One Wire Temperature sensor (DS1820) to PC interface.
Here is a project I worked on a while ago that Ive 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.
And a closer look,
The Schematic,
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,
I've attached a monochrome image. See below. If you run hyperterminal you will get this,
Not very useful and so Ive 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.
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: ;******************************************************************* ; Title One Wire temperature reader ; Author Mike Webb ; Date 10th January 2009 ; Pic 10F200 or 12F509 ;******************************************************************* errorlevel radix dec #ifdef __12F509 -302,-224
include "p12f509.inc" __CONFIG _MCLRE_ON & _CP_OFF & _WDT_ON & _IntRC_OSC OW_Bit equ 4 RS_Bit equ 2 #defineDataLow
b'11111111' - (1<<OW_Bit) - (1<<RS_Bit)
#defineDataHigh b'11111111' - (1<<RS_Bit) #defineDataBit GPIO,OW_Bit #defineb_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 #defineDataLow b'11111111' - (1<<OW_Bit) - (1<<RS_Bit) #defineDataHigh b'11111111' - (1<<RS_Bit) #defineDataBit GPIO,OW_Bit #defineb_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 #defineOwSkipRom #defineOwConvert #defineOwReadScratchPad #defineOwSearchRom #defineOwMatchRom 0xcc 0x44 0xbe 0xf0 0x55
#defineb_OwPresent OwFlags,7 #defineb_ClrBit OwFlags,6 #defineb_Done OwFlags,5 #defineb_IsGetBit OwFlags,4 #defineb_SendRom OwFlags,3 org movwf 0 OSCCAL
start
First Next
GetBits
clrf movlw tris movlw option clrf bcf bcf btfsc goto clrf call movlw call clrf clrf call rlf call rlf movlw xorwf btfsc goto xorlw btfss goto
7 ;turn of comparators (10f204/6) DataHigh ;release line GPIO 0xdf ;make GPIO2 I/O LastDiscrepency ;restart search rom b_Done DataBit b_Done ;Have we completed list start ;Yes so restart BitIndex ;start at first bit OwReset OwSearchRom ;Send search rom command OwWriteByte Discrepency OwFlags ;clear all bit variables OwReadBit ;get bit A OwFlags,f OwReadBit ;get bit B OwFlags,f 0x03 OwFlags,w ;If A=1 && B=1 then no devices STATUS,Z start 0x03 STATUS,Z Not00 ;Restart
present
;A=0 and B=0 movfw subwf btfsc goto btfss goto call btfss goto goto Not00 btfsc call btfss call goto RomIndexGTLD call SetMarker movfw movwf goto RomIndexEqualLD call SendRomBit call call incf btfss goto movfw movwf btfsc bsf bsf lack of BitIndex LastDiscrepency,w STATUS,Z RomIndexEqualLD STATUS,C RomIndexGTLD GetBit ;RomIndex < LastDiscrepency STATUS,C SetMarker SendRomBit OwFlags,1 ;set ROM bit to match Bit A SetBit OwFlags,1 ClrBit SendRomBit ClrBit ;RomIndex > LastDiscrepency BitIndex Discrepency SendRomBit SetBit ;RomIndex = LastDiscrepency GetBit OwSendCarry BitIndex,f BitIndex,6 GetBits Discrepency LastDiscrepency STATUS,Z b_Done b_SendRom ;this was a subroutine but due to
OwMatch a flag
call movlw call movlw movwf movfw call incf btfss goto btfss goto movlw call bcf bsf movlw tris call movlw tris
OwReset
;stack space it was put in line and
SendRom
OwMatchRom ;used to indicate the return address OwWriteByte RomBuffer ;=0x10 = 0001 0000 FSR INDF OwWriteByte FSR,F FSR,3 ;bodgey, FSR=0x18 SendRom b_SendRom Continue ;taken 2nd time around OwConvert OwWriteByte b_SendRom DataBit ;drive data line high by DataLow ;setting to output for GPIO ;parasitic power devices Delay1 ;wait for conversion DataHigh ;release data line GPIO ;by setting to input FSR,F FSR,4 OwMatch INDF,W SendNibble INDF SendNibble SendSerial ;FSR=0x18 when entering ;will be clear when FSR=0x0f
SendSerial
decf btfss goto swapf call movfw call goto movlw call call movlw movwf call swapf call movfw call incfsz goto movlw call movlw call goto bsf goto bsf btfss bcf bcf rrf movwf rrf
Continue
OwReadScratchPad OwWriteByte SendSpace 0x100-9 FSR ;very dodgey - relies on unused bits OwReadByte OwByte,W SendNibble OwByte SendNibble FSR,F ReadLoop 0x0d Send 0x0a Send Next ;but no choice as out of RAM!!
being 1 ReadLoop
;send cr/lf
;go get next rom ID
GetBit ClrBit SetBit DoBit
b_IsGetBit ;Get bit RomBuffer[BitIndex] DoBit b_ClrBit ;Clear bit RomBuffer[BitIndex] b_ClrBit b_ClrBit ;Set bit RomBuffer[BitIndex] b_IsGetBit BitIndex,W OwTemp OwTemp,f
GetBitLoop
IsClrBit DoGetBit
rrf andlw iorlw movwf movfw andlw clrf movwf bsf rlf decf btfss goto movfw btfsc goto btfsc goto iorwf retlw xorlw andwf retlw andwf btfss bsf retlw movlw tris movlw movwf decfsz goto movlw tris movlw movwf decfsz goto bcf btfss bsf movlw movlw movwf decfsz goto retlw movwf movlw movwf rrf call decfsz goto retlw
OwTemp,W 0x07 RomBuffer FSR BitIndex 0x07 OwTemp OwCount STATUS,C OwTemp,f ;will clear the carry bit OwCount,F OwCount,7 GetBitLoop OwTemp b_IsGetBit DoGetBit ;carry must be clear b_ClrBit IsClrBit INDF,f 0 0xff INDF,f 0 INDF,w STATUS,Z STATUS,C 0 DataLow GPIO .750/4 temp temp,W $-2 DataHigh ;release GPIO .68/4 temp temp,W $-2 b_OwPresent DataBit b_OwPresent .480/4 .548/4 temp temp,W $-2 0 ;pull line low ;delay 750uS
OwReset
line ;delay 68uS
; ; ; ; ; ; ; ; ExitDelay
;pulled low? ;yes so chip present ;delay 480uS ;combined times
OwWriteByte OwWriteLoop
OwByte ;store byte to write .8 ;send 8 bits OwCount OwByte,f ;move bit to carry OwSendCarry ;send it OwCount,F ;sent all bits OwWriteLoop ;no, so loop 0 .8 OwCount OwReadBit ;get 8 bits ;returns bit in carry
OwReadByte
movlw movwf OwReadByteLoop call
rrf decfsz goto retlw OwSendCarry OwSend1 btfss goto movlw tris goto goto movlw tris movlw goto movlw tris movlw movwf decfsz goto movlw tris movlw goto movlw tris goto goto movlw tris movlw movwf decfsz goto bcf btfsc bsf movlw goto movlw goto andlw movwf movlw addwf movlw btfsc movlw addwf movwf bsf call bsf rrf bsf
OwByte,F ;move carry into byte OwCount,F ;finished? OwReadByteLoop ;no, so carry on 0 STATUS,C ;is carry clear OwSend0 ;yes, so goto send zero DataLow ;pull line low GPIO $+1 ;wait 4uS $+1 DataHigh ;release line GPIO .60/4 ;wait 60uS ExitDelay DataLow ;pull line low GPIO .60/4 ;wait 60uS temp temp,W $-2 DataHigh ;release line GPIO .4/4 ExitDelay DataLow ;pull line low GPIO $+1 ;wait 4uS $+1 DataHigh ;release line GPIO .12/4 ;Wait 12uS temp temp,W $-2 STATUS,C DataBit STATUS,C .60/4 ;Wait 60uS Exit60 ;Delay ' ' Send ;0x20
Exit60 OwSend0
OwReadBit
; SendSpace SendNibble
0fh ;keep lower nibble temp ;save for later 0x100-10 ;test if greater temp,W ;than 10 "0" ;add "0" STATUS,C ;or, if greater than 10 "0"+7 ;add "A"-10 temp,W ;do add and fall through to send it OutByte ;sends data inverted so no MAX232
Send needed
SendLoop
b_RS232Out ;start bit BitDelay STATUS,C ;will be first stop bit OutByte,F ;move bit to carry b_RS232Out
btfsc bcf call bcf movfw bit sent btfss goto bcf
STATUS,C b_RS232Out BitDelay STATUS,C ;ensure 0 shifted into outbyte OutByte ;will be zero when 8 bits + 1 stop STATUS,Z SendLoop 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 movlw movwf decfsz goto clrwdt retlw clrf movlw movwf call decfsz goto decfsz goto retlw .30 temp temp,F; DelayLoop 0 OwTemp .40 OwCount BitDelay OwTemp,F del OwCount,F del 0 ;approx 1 second delay
BitDelay DelayLoop
(3*30)-1 = 89 + 2 = 91 ;kick the dog
Delay1 del
if messg endif end
($>0xff) "Memory Overflow"