14.2 DS18B20 Temperature Sensor
#PICAXE 40X1
#NO_DATA ; these commands prevent the Programming Editor over writing valid 1-Wire serial numbers
#NO_TABLE ; that have previously been saved to EEROM
#TERMINAL 4800
SETFREQ m4 ; this can be adjusted to m8 but then need to change the Terminal command above to 9600
;
;
; -----[ EEPROM Data ]-----------------------------------------------------
;
; -----[ Variables ]-------------------------------------------------------
;
SYMBOL device = b4
SYMBOL res_bits = b5
SYMBOL delay = b14
SYMBOL datasize = b15
SYMBOL tempsign = b16
SYMBOL loop_prt = b17
SYMBOL resolution = b18
SYMBOL OW_Net = b19 ; The permanent inbuilt DS18B20 temp sensor data input is pin 2, for one-wire network
use pin 7
SYMBOL EEmem_ptr = b20
;
; next variables used for binary/decimal for ASCII conversion
SYMBOL empty = b23
SYMBOL tenth = b24
SYMBOL hund = b25
SYMBOL thou = b26
SYMBOL tentho = b27
;
; -----[ Initialization ]--------------------------------------------------
;
Init:
PAUSE 1000 ; this delay is to give the Programming Editor terminal Window time to establish
;
WA55 1-Wire Tutorial_RevE with TOC.doc Page 29 of 75 15/06/2010
;
; -----[ Program Code ]----------------------------------------------------
;
Main:
FOR resolution = 9 to 12 ; try each of the resolutions the BS18B20 has available
datasize = resolution - 9 ; a value 0 to 3 which is used to part of setting up the DS18B20 config
register for resolution
SERTXD (CR, LF, CR, LF, "Resolution = ", #resolution, " bits", CR, LF)
FOR device = 1 to 6 ; First we set up the resolution configuration register for every device
we know about
OW_Net = 7
IF device = 1 THEN
OW_Net = 2 ; device 1 is a single device on pin 2. the other 5 are multidrop on pin
7
ENDIF
GOSUB Get_Dev_Sn_From_EE ; Places the device family type, serial number and CRC into variables
b6 to b13 with the family type in b6 and the CRC in b13
GOSUB Set_Res ; set the temp sensor config register for the desired resolution ( 9 to 12
bits)
NEXT device
; the following part addresses each temp sensor one at a time and sends the Convert T command, pauses then reads in
the temp data
FOR device = 1 to 6 ; for every available device on the system
OW_Net = 7
IF device = 1 THEN
OW_Net = 2 ; device 1 is a single device on pin 2. the other 5 are multidrop on pin
7
ENDIF
GOSUB Get_Dev_Sn_From_EE ; Places the device family type, serial number and CRC into variables
b6 to b13 with the family type in b6 and the CRC in b13
SERTXD(CR, LF, "Dev ", #device, " S/N = ", #b6, " ", #b7," ", #b8," ", #b9," ", #b10," ", #b11, " ",#b12," ",
#b13, " & Dev Temp is: ")
IF b6 = $28 THEN ; check that it is a DS18B20 Temp sensor $28 = 40 as family type
OWOUT OW_Net, %1001,($55, b6, b7, b8, b9, b10, b11, b12, b13, $44 ) ; send ‘reset before’ then
‘Match ROM’ and then S/N for device then ‘convert T’ then apply ‘pullup’
PAUSE delay ; wait the necessary period with extra/strong data line pull-up while
conversion takes place
OWOUT OW_Net, %1001,($55, b6, b7, b8, b9, b10, b11, b12, b13, $BE ) ; send ‘reset before’ then
‘Match ROM’ and then S/N for device then ‘Read Scratchpad’ then apply ‘pullup’
OWIN OW_Net, %1010,(b0,b1) ; read the temperature data into word variable w0 (w0 = b1:b0 -
NOTE 1-Wire systems do the lsb first)
GOSUB DisplayTheTemp
IF OW_Net = 2 THEN ; only for the a single DS18B20 then also do a comparative
READTEMP12 command
READTEMP12 OW_Net, w1
WA55 1-Wire Tutorial_RevE with TOC.doc Page 30 of 75 15/06/2010
w1 = w1 / 16 ; assumes positive range only and extracts only the integer portion
sertxd (" and = ", #w1 ) ; transmit the integer temperature value to the PC
ENDIF
ENDIF
NEXT device
SERTXD (CR,LF) ; skip a line for ease of viewing
; the following part broadcasts the converts T to all the devices, waits the delay period just once and them indivdually
reads each temp back
OW_Net = 2 ; set up to send COnvert T to the one device on pin 2
OWOUT OW_net,%1001,($CC,$44) ; send ‘reset’ then ‘skip ROM’ ‘ then ‘convert T’ then apply ‘pullup’
OW_Net = 7 ; set up to send Convert T to all the devices on pin 7
OWOUT OW_net,%1001,($CC,$44) ; send ‘reset’ then ‘skip ROM’ ‘ then ‘convert T’ then apply ‘pullup’
PAUSE delay ; wait the necessary period with extra/strong data line pull-up while
conversion takes place
FOR device = 1 to 6 ; now read the temp back individually from every available device on
the system
OW_Net = 7
IF device = 1 THEN
OW_Net = 2 ; device 1 is a single device on pin 2. the other 5 are multidrop on pin
7
ENDIF
GOSUB Get_Dev_Sn_From_EE ; Places the device family type, serial number and CRC into variables
b6 to b13 with the family type in b6 and the CRC in b13
SERTXD(CR, LF, "Dev ", #device, " S/N = ", #b6, " ", #b7," ", #b8," ", #b9," ", #b10," ", #b11, " ",#b12," ",
#b13, " & Dev Temp is: ")
IF b6 = $28 THEN ; check that it is a DS18B20 Temp sensor $28 = 40 as family type
OWOUT OW_Net, %1001,($55, b6, b7, b8, b9, b10, b11, b12, b13, $44 ) ; send ‘reset before’ then
‘Match ROM’ and then S/N for device then ‘convert T’ then apply ‘pullup’
PAUSE delay ; wait the necessary period with extra/strong data line pull-up while
conversion takes place
OWOUT OW_Net, %1001,($55, b6, b7, b8, b9, b10, b11, b12, b13, $BE ) ; send ‘reset before’ then
‘Match ROM’ and then S/N for device then ‘Read Scratchpad’ then apply ‘pullup’
OWIN OW_Net, %1010,(b0,b1) ; read the temperature data into word variable w0 (w0 = b1:b0 - NOTE 1-
Wire systems do the lsb first)
GOSUB DisplayTheTemp
IF OW_Net = 2 THEN ; only for the a single DS18B20 then also do a comparative
READTEMP12 command
READTEMP12 OW_Net, w1
w1 = w1 / 16 ; assumes positive range only and extracts only the integer portion
SERTXD (" and = ", #w1 ) ; transmit the integer temperature value to the PC
ENDIF
ENDIF
WA55 1-Wire Tutorial_RevE with TOC.doc Page 31 of 75 15/06/2010
NEXT device
SERTXD (CR,LF)
NEXT resolution
GOTO Main
;
; -----[ Subroutines ]-----------------------------------------------------
;
;
;
Get_Dev_Sn_From_EE:
EEmem_ptr = device - 1 * 8 + 1
READ EEmem_ptr, b6
INC EEmem_ptr
READ EEmem_ptr, b7
INC EEmem_ptr
READ EEmem_ptr, b8
INC EEmem_ptr
READ EEmem_ptr, b9
INC EEmem_ptr
READ EEmem_ptr, b10
INC EEmem_ptr
READ EEmem_ptr, b11
INC EEmem_ptr
READ EEmem_ptr, b12
INC EEmem_ptr
READ EEmem_ptr, b13
RETURN
;
; ---------------------------------------------------------------------------
;
Set_Res:
IF b6 = $28 THEN ; check that it is a DS18B20 Temp sensor $28 = 40
delay = 760 >> datasize ; 12 bit = 760ms, 11 bit = 380ms, 10 bit = 190ms and 9 bit =
95ms
res_bits = datasize * $20 OR $1F
OWOUT OW_Net, %1001,($55, b6, b7, b8, b9, b10, b11, b12, b13 ) ; send ‘reset before’ then ‘Match
ROM’ then SN for device then apply ‘pullup’
OWOUT OW_Net, %1010,($4E, 0,0, res_bits) ; send ‘Write to Scratchpad‘ to write to TH, TL and config
register. Set config to specified resolution
ENDIF
RETURN
;
; ---------------------------------------------------------------------------
;
DisplayTheTemp:
; this dislays the temperature in variable w0
IF bit15 <> 0 THEN
tempsign ="-"
w0 = -w0 ; two's complement the value read in to get the absolute
portion with no sign bit
ELSE
tempsign ="+"
ENDIF
WA55 1-Wire Tutorial_RevE with TOC.doc Page 32 of 75 15/06/2010
;
; now work out decimal fractional portion to suit the required resolution
w1 = 0
On datasize GOTO Bits09, Bits10, Bits11, Bits12 ; jump to appropriate point and exclude unneccesary bits
Bits12: IF bit0 = 1 THEN : w1 = w1 + 0625 : ENDIF
Bits11: IF bit1 = 1 THEN : w1 = w1 + 1250 : ENDIF
Bits10: IF bit2 = 1 THEN : w1 = w1 + 2500 : ENDIF
Bits09: IF bit3 = 1 THEN : w1 = w1 + 5000 : ENDIF
; now fractional pasrt doen we can alter w0 to work out the whole/Integer portion to suit the required resolution
w0 = w0 AND $07FF >> 4 ; mask off all the 5 sign bits and shift right 4 bits to leave only integer portion
; break out the digits into ASCII codes and diplay the relevant digits corresponding to accuracy
BINTOASCII w1 , empty, tenth, hund, thou, tentho
; now display the temperature as reported by the current sensor
SERTXD( tempsign, #w0, ".") ; display the sign and integer/whole part
SERTXD (tenth)
IF datasize > 0 THEN : SERTXD (hund) : ENDIF
IF datasize > 1 THEN : SERTXD (thou) : ENDIF
IF datasize > 2 THEN : SERTXD (tentho) : ENDIF
RETURN
;
;
; -----[ Interrupt Routine (if used) ]-------------------------------------
;
;Interrupt:
; RETURN
; =================================================
; THE END
; =================================================