DS18B20 Code Examples

marks

Senior Member
Celsius -55.00 C to +125.00 C
Code:
Celsius:
owout c.7,%1001,($CC,$44)                     ' reset(send skip rom ,send convert t)
  
owout c.7,%0001,($CC,$BE)                     ' reset(send skip rom ,send read lsb msb)
                          
owin c.7,%0000,(b2,b3)                        ' read in result ds18b20

     Convert:                                      '  info     + 125 degrees / 0.0625 =  2000
       let b9 =43                                      ' Display + (43) space (32)
     IF W1 > 64655 THEN                            '  info     -  55 degrees = 64656
       let b9 =45                                      ' Display - (45)
     W1 = - W1                                     '  info  if - ie w1=5500  Display -  55.00 C
     ENDIF                                
     W1 = W1 * 25 / 4                              '  info     + ie w1=12500 Display + 125.00 C
                                          
BINTOASCII w1,b8,b7,b6,b5,b4 
IF b8 = "0" THEN  : b8 = " "  :ENDIF                   ' zero blanking b8
IF b8 =  " "  AND  b7 =  "0"  THEN : b7 = " "  :ENDIF  ' zero blanking b7
  
SERTXD (CR, LF, "Temperature  ",b9,b8,b7,b6,".",b5,b4,"  Degrees C", CR, LF) ' resolution to 0.06

pause 1000
goto celsius
Fahrenheit -67.0 F to +257.0 F
Code:
Fahrenheit:
owout c.7,%1001,($CC,$44)                      ' reset(send skip rom ,send convert t)
  
owout c.7,%0001,($CC,$BE)                      ' reset(send skip rom ,send read lsb msb)
                           
owin c.7,%0000,(b2,b3)                         ' read in result ds18b20

     Convert:                                    '  info     + 225 degrees / 0.1125 =  2000
        let b9 =43                                   ' Display + (43) space (32)
     W1 =  W1 +880 * 9 / 8 -670                  '  info     + ie w1=2570 Display + 257.0 C
     IF W1 >  64865 THEN                         '  info     -  67 degrees = 64866
     W1 = -W1                                    '  info  if - ie w1=670  Display -  67.0 C
        let b9 =45                                   ' Display - (45)
     ENDIF
      
BINTOASCII w1,b8,b7,b6,b5,b4
IF b7 = "0" THEN  :  B7 = " "  :  ENDIF              ' zero blanking b7
IF b7 = " " AND b6 = "0"  THEN : B6 = " " : ENDIF    ' zero blanking b6

SERTXD (CR, LF, "Temperature  ",b9,b7,b6,b5,".",b4,"  Degrees F", CR, LF)'resolution to 0.1

PAUSE 1000
GOTO fahrenheit
Readtemp12 example
Code:
Celsius:
Readtemp12 c.7,w1                                   'read in result ds18b20

 convert:                                           
  let b9 =43                                       'Display + (43)   space (32)
IF W1 > 64655 THEN                                  '  info     - 55 degrees          = 64656
  let b9 =45                                       'Display - (45)
W1 = - W1                                           '  info   if - ie w1=1000   display   - 10.00 C
ENDIF                                
W1 = W1 * 25 / 4                                    '  info      + ie w1=8500   display     85.00 C
                                          
BINTOASCII w1,b8,b7,b6,b5,b4 
IF b8 = "0" THEN  : b8 = " "  :ENDIF                       ' zero blanking b8
IF b8 =  " "  AND  b7 =  "0"  THEN : b7 = " "  :ENDIF      ' zero blanking b7
  
SERTXD (CR, LF, "Temperature  ",b9,b8,b7,b6,".",b5,b4,"  Degrees C", CR, LF)'resolution to 0.06

PAUSE 1000
GOTO celsius
convert is just converting the sensor data as a word in original form
its easier than converting the bytes seperately will be the same for 9,10,11,12 bit reading
but if our convert code is not as good we can also loose resolution in the maths also
luckily our ds18b20 scales easily.

(when using above owin commands)
by default is set to 12 bit which we get as soon as we can read it

if using other functions alarm and eprom this will take longer

if using external supply and requiring read time slots
this can take up to a MAX 750ms for 12bit
if we need this quicker we can reduce the bit read.

the above code is abit of trick lol because we are not waiting for the conversion
we are infact reading from the previous one so if we update every minute
the data is one minute old.
it was found a PAUSE 510 was needed after the convert command
owout c.7,%1001,($CC,$44) to get the instant update
and when first powered up you would need longer
its probaly why readtemp12 takes 750ms you dont need to pause
and it guarentees instant update even when first powered up.
 
Last edited:

matherp

Senior Member
Many thanks - just what I needed to use the DS18B20 non-blocking. This has saved me at least a couple of hours pouring over the datasheets.

Best regards

Peter
 

johndimo

New Member
Good stuff. I'll contribute some code for those who don't mind 1* resolution. Done with an 08M
My code below will use the readtemp command to gather the temp represented to the nearest whole degree C.

It will then convert into F and display the results. The math will work for the entire range of the sensor, even negative temps. I tested it by attaching a long wire to the sensor and sticking it into the freezer while my circuit and laptop sat on the counter. Everything should be working bug free.

Code:
symbol celsius = w0
symbol frnht = w1
readtemp 4,Celsius 							;get temp reading from sensor
		
if Celsius < 127 Then 							;check to see if temp is above 0
	Frnht = Celsius * 9 / 5 + 32 			        ;covert temp to F
	sertxd ("Temp is: ",#Celsius,"C",cr,lf) 	                ;display C temp
	sertxd ("Temp is: ",#Frnht,"F",cr,lf) 		        ;display F temp
else
	Celsius = Celsius - 128 					;domath since temp is below 0
	sertxd("Temp is: -",#Celsius,"C",cr,lf)           	;display C temp 
	if Celsius <= 18 then 						;check if temp is betweem -18 and 0 (since F is still +)
		Frnht = Celsius * 9 / 5 				;convert temp
		Frnht = 32 - Frnht 					;convert temp
		sertxd ("Temp is: ",#Frnht,"F",cr,lf)      	;display F temp
	endif
	if Celsius > 18 then 						;check if temp is below -18 (since F is now - also)
		Frnht = Celsius - 18 					;convert temp
		Frnht = Frnht * 9 / 5 					;convert temp
		sertxd("Temp is: -",#Frnht,"F",cr,lf) 	        ;display F temp
	endif
endif
 
Last edited:

william47316

New Member
heres the code i used on an 08M it will read the 18b20 and send out the temperature via serial this code is made for my 8 digit display and hence has a limited character set so null is a space, colons show the negative symbol and the K shows a degrees symbol on the 7 segments of the display. this code should do the full temperature range of the 18b20 to 0.1°C and uses around 80 something bytes on an 08M
Code:
symbol degcelraw = w3
symbol degcel = b1
symbol degceldec = b0
eeprom 0,(9,8,7,6,5,4,3,2,1,0) 'lookup table for the negitive decimals
main:
readtemp12 1,degcelraw

degcel = degcelraw/16 'calculate into deg celcius
degceldec = degcelraw//16*10/16
b3 = 0 'for positive temperatures default to show blank

'negitive temperature code
if degcel >= $7F then' if the degcel var is above 127 (max reading for +'ve is 125°C below zero "underflows" to 65535 @ -0.1 ish °C)
degcel = 255 - degcel 'take it from 255
b2 = degceldec
read b2, degceldec 'read the value of the decimal point from eeprom
b3 = 58 ' set b3 to show the "colon" character (dash)
end if
'end of negitive temperature processing

'decimal point selection code
b2 = 83
if degcel < 10 then
b2 = 82
end if
if degcel >= 100 then
b2 = 84
end if
'end of decimal point selection code
sertxd (b2,b3,#degcel,#degceldec,"KCEL") 'serial out the lot and some filler
'sertxd (#degcelraw,"RAKC") 'uncomment this and (or) comment above out for debugging code
goto main
 
Last edited:
DS18B20 readtemp command not working

Does Marks' code alter the settings of the DS18B20?
It seems to work fine with Marks' code, but when I try using the regular readtemp command in my datalogger program, I get values in the 40-43 range at room temp. Just trying to figure out what's going on with this thing.

Thanks,
Brian
 

eclectic

Moderator
Does Marks' code alter the settings of the DS18B20?
It seems to work fine with Marks' code, but when I try using the regular readtemp command in my datalogger program, I get values in the 40-43 range at room temp. Just trying to figure out what's going on with this thing.

Thanks,
Brian
Brian.
It's probably best if you post your full code
and circuit.

e
 

marks

Senior Member
Readtemp reads raw data from the DS18B20 and converts it to whole degrees Celsius for you
negative values will appear as(128 + temperature Celsius value).

Celsius -55C to +125C
Code:
Celsius:
Readtemp b.6,b1                                   'read in result ds18b20

 convert:                                           
  let b9 =43                                      'Display + (43)   space (32)
IF b1 > 127 THEN                                  ' If negative                              
  let b9 =45                                      ' Display - (45)
b1 = b1 - 128                                           
ENDIF                                
                                          
BINTOASCII b1,b8,b7,b6 
IF b8 = "0" THEN : b8 = " "                       ' zero blanking b8
 IF b7 = "0" THEN : b7 = " "                      ' zero blanking b7
 ENDIF
ENDIF 
SERTXD (CR, LF, b9,b8,b7,b6,"  Degrees C", CR, LF)'resolution to 1

PAUSE 1000
GOTO celsius
Readtemp12 reads raw data only from the DS18B20 this makes it easier to use and write code to convert to Fahreheit.

Fahrenheit -67 F to +257 F
Code:
Fahrenheit:
Readtemp12 b.6,w0                                 'read in result ds18b20

 convert:
w0 = w0+880/16*9/5-67                                    
  let b9 =43                                      'Display + (43)   space (32)
IF w0 > 65468 THEN                                ' If negative                              
  let b9 =45                                      ' Display - (45)
w0 = -w0                                         
ENDIF                                
                                          
BINTOASCII w0,b8,b7,b6 
IF b8 = "0" THEN : b8 = " "                       ' zero blanking b8
 IF b7 = "0" THEN : b7 = " "                      ' zero blanking b7
 ENDIF
ENDIF 
SERTXD (CR, LF, b9,b8,b7,b6,"  Degrees F", CR, LF)'resolution to 1

PAUSE 1000
GOTO Fahrenheit
 

westaust55

Moderator
Please post your program listing/code which is giving you difficulties.

Which PICAXE chip are you using?

If your DS18B20 works properly with Marks code, then I would suggest there is not problem with the DS18B20.
 

hippy

Technical Support
Staff member
I must have a bad DS18B20 Sensor. I'm getting erratic readings.
Go right back to basics - a simple loop with a READTEMP or READTEMP10 into a variable ( remembering it needs to be a word variable for READTEMP10 ) and DEBUG or SERTXD to report what the reading was.
 
I'm using a 20x2 chip with a homemade PCB (with proper pullup resistor).
Here's my test code..

Code:
main:
readtemp c.7, b0
pause 100
debug b0
goto main
debug window shows b0 variable from 6 to 9 and is unstable.

Marks Farenhiet code gives 55 to 62 degrees f. see attached.
My room thermometer is reading 71 degrees f.

I'm guessing either my board is messed up, or I have a bad sensor.
I'll test the sensor in a breadboard with a 20m chip.
 

Attachments

Vroom

Member
I want use serial LCD, how change use serout? example serout 1,T9600, (254,192,"Temp= ",#b1,".",#b0,"°C") and use neg serout 1,T9600, (254,192,"Temp= -",#b1,".",#b0,"°C")



heres the code i used on an 08M it will read the 18b20 and send out the temperature via serial this code is made for my 8 digit display and hence has a limited character set so null is a space, colons show the negative symbol and the K shows a degrees symbol on the 7 segments of the display. this code should do the full temperature range of the 18b20 to 0.1°C and uses around 80 something bytes on an 08M
Code:
symbol degcelraw = w3
symbol degcel = b1
symbol degceldec = b0
eeprom 0,(9,8,7,6,5,4,3,2,1,0) 'lookup table for the negitive decimals
main:
readtemp12 1,degcelraw

degcel = degcelraw/16 'calculate into deg celcius
degceldec = degcelraw//16*10/16
b3 = 0 'for positive temperatures default to show blank

'negitive temperature code
if degcel >= $7F then' if the degcel var is above 127 (max reading for +'ve is 125°C below zero "underflows" to 65535 @ -0.1 ish °C)
degcel = 255 - degcel 'take it from 255
b2 = degceldec
read b2, degceldec 'read the value of the decimal point from eeprom
b3 = 58 ' set b3 to show the "colon" character (dash)
end if
'end of negitive temperature processing

'decimal point selection code
b2 = 83
if degcel < 10 then
b2 = 82
end if
if degcel >= 100 then
b2 = 84
end if
'end of decimal point selection code
sertxd (b2,b3,#degcel,#degceldec,"KCEL") 'serial out the lot and some filler
'sertxd (#degcelraw,"RAKC") 'uncomment this and (or) comment above out for debugging code
goto main
 

william47316

New Member
I want use serial LCD, how change use serout? example serout 1,T9600, (254,192,"Temp= ",#b1,".",#b0,"°C") and use neg serout 1,T9600, (254,192,"Temp= -",#b1,".",#b0,"°C")
change
Code:
sertxd (b2,b3,#degcel,#degceldec,"KCEL") 'serial out the lot and some filler
to
Code:
serout 1, t9600, (254,192,"Temp = ",b3,#degcel,"."#degceldec,"°C")
full revised code below
Code:
symbol degcelraw = w3
symbol degcel = b1
symbol degceldec = b0
eeprom 0,(9,8,7,6,5,4,3,2,1,0) 'lookup table for the negitive decimals
main:
readtemp12 2,degcelraw

degcel = degcelraw/16 'calculate into deg celcius
degceldec = degcelraw//16*10/16
b3 = 43 'for positive temperatures default to show a plus sign

'negitive temperature code
if degcel >= $7F then' if the degcel var is above 127 (max reading for +'ve is 125°C below zero "underflows" to 65535 @ -0.1 ish °C)
degcel = 255 - degcel 'take it from 255
b2 = degceldec
read b2, degceldec 'read the value of the decimal point from eeprom
b3 = 45 ' set b3 to show the minus character
end if
'end of negitive temperature processing

serout 1, t9600, (254,192,"Temp = ",b3,#degcel,46,#degceldec,"°C") 'serial out the lot
goto main
this should show (for example) Temp = +22.6°C on the LCD for positive temperatures you can set the first b3 to 32 if you want a blank space on positive temperatures and it will show (for example) Temp = -18.5°C for negative temperatures. you may have to consult the LCD manual for the degree's symbol character code as 176 may be assigned to something else on the LCD
 
Last edited:

Vroom

Member
Thanks, its working with 0.1 resolution, great. but I use wireless temp sender its good working well. Other normally 1 resolution code if b1 > 127 then neg, and let b1 = b1 -128, I want degcel = b1 which your code put single b1, and b0 without b3 space(32)/neg(45) because receiver and sender RF wireless rather less than two variables b1 and b0 enough not three too many. Could you make change just b1 and b0 along without b3? I could make a code receiver with use if b1 > 127 then..., and let b1 = b1 -128 include rest b2 for degceldec from serin.

change
Code:
sertxd (b2,b3,#degcel,#degceldec,"KCEL") 'serial out the lot and some filler
to
Code:
serout 1, t9600, (254,192,"Temp = ",b3,#degcel,"."#degceldec,"°C")
full revised code below
Code:
symbol degcelraw = w3
symbol degcel = b1
symbol degceldec = b0
eeprom 0,(9,8,7,6,5,4,3,2,1,0) 'lookup table for the negitive decimals
main:
readtemp12 2,degcelraw

degcel = degcelraw/16 'calculate into deg celcius
degceldec = degcelraw//16*10/16
b3 = 43 'for positive temperatures default to show a plus sign

'negitive temperature code
if degcel >= $7F then' if the degcel var is above 127 (max reading for +'ve is 125°C below zero "underflows" to 65535 @ -0.1 ish °C)
degcel = 255 - degcel 'take it from 255
b2 = degceldec
read b2, degceldec 'read the value of the decimal point from eeprom
b3 = 45 ' set b3 to show the minus character
end if
'end of negitive temperature processing

serout 1, t9600, (254,192,"Temp = ",b3,#degcel,46,#degceldec,"°C") 'serial out the lot
goto main
this should show (for example) Temp = +22.6°C on the LCD for positive temperatures you can set the first b3 to 32 if you want a blank space on positive temperatures and it will show (for example) Temp = -18.5°C for negative temperatures. you may have to consult the LCD manual for the degree's symbol character code as 176 may be assigned to something else on the LCD
 
Last edited:

william47316

New Member
the b3 just changes the ASCII code when its positive or negative it will work if removed it just wont indicate on the display if its a positive or negative temperature.
im sorry but i cant quite understand what your after. i write my code to be reasonably lean while still doing an intended function, some details of this wireless unit would help a bit too. is it something pre-made eg just a drop in thing, or did you make it yourself
 

Vroom

Member
Right. Yes I did make it myself like example;

main:
serin 2, N600, ("adt"), b1
if b1 > 127 then neg
serout 1, t9600, (254,192,"Temp = ",#b1,"°C")
wait 2
goto main

neg:
let b1 = b1 - 128
serout 1, t9600, (254,192,"Temp = -",#b1,"°C")
wait 2
goto main

But I try change code for receiver like this;

main:
serin 2, N600, ("adt"), b1,b0
if b1 > 127 then neg
serout 1, t9600, (254,192,"Temp = ",#b1,46,#b0,"°C")
wait 2
goto main

neg:
let b1 = b1 - 128
serout 1, t9600, (254,192,"Temp = -",#b1,46,#b0,"°C")
wait 2
goto main

I'm trying to change of your code only two b1 and b0 without b3 likely readtemp, RF wireless is no good too many long variable, rather two variables enough.

the b3 just changes the ASCII code when its positive or negative it will work if removed it just wont indicate on the display if its a positive or negative temperature.
im sorry but i cant quite understand what your after. i write my code to be reasonably lean while still doing an intended function, some details of this wireless unit would help a bit too. is it something pre-made eg just a drop in thing, or did you make it yourself
 

marks

Senior Member
Heres some simplified code to try with the terminal

Code:
Celsius:
Readtemp12 b.6,W0                             '  (b1,b0)  read in result ds18b20
                               
Convert:                                      
       let b9 =32                                      ' Display + (43) space (32)
     IF B1 > 127 THEN                       
       let b9 =45                                      ' Display - (45)
     W0 = - W0                                     
     ENDIF                                 
     W0 = W0 * 16                                           
     B0 = B0 / 16 * 10 / 16 
                             
sertxd (CR,LF,"Temp is ",b9,#B1,".",#B0," .C")

PAUSE 1000
GOTO celsius
I'm guessing a bit here as i havent tryied any RF yet! lol hopefully it may help.
Code:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
mainRx:
serin 2,n1200,("abc"),w0
Convert:                                      
       let b9 =32                                      ' Display + (43) space (32)
     IF B1 > 127 THEN                       
       let b9 =45                                      ' Display - (45)
     W0 = - W0                                     
     ENDIF                                 
     W0 = W0 * 16                                           
     B0 = B0 / 16 * 10 / 16 
                             
serout 1,t9600, (254,192,"Temp is ",b9,#B1,".",#B0," .C")
wait 2

goto mainrx 

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

mainTx:
readtemp12 0,w0
serout 4,n1200,(85,85,85,85,"abc",w0)
wait 2 
goto mainTx
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
 
Last edited:

william47316

New Member
you can transmit word variables via the wireless, also what is the transmitter doing. get the transmitter to just send the preamble qualifier and raw 18b20 reading in a word variable and get the receiver to receive and make sense of it. eg

transmitter
Code:
main:
readtemp12 (pin), w2
 serout (pin), n600,(85,85,85,85,85,85,"adt",w2)
pause 1000
goto main
and basically use my code as is except replace the readtemp12 with serin (input),n600, ("adt"),degcelraw the rest can stay as is
 

Vroom

Member
Thanks Marks,

I tried to make change code like READTEMP12 if say -1.0-1.9oC so mean 127 to sender by wireless with two variables, receiver use IF B1 > 127 THEN, how work out code use B1=127> for negative for sender from READTEMP12? I little a bit confuse with W0= - W0 what meaning? like B0 = - B0 and B1 = - B1 both?

Heres some simplified code to try with the terminal

Code:
Celsius:
Readtemp12 b.6,W0                             '  (b1,b0)  read in result ds18b20
                               
Convert:                                      
       let b9 =32                                      ' Display + (43) space (32)
     IF B1 > 127 THEN                       
       let b9 =45                                      ' Display - (45)
     W0 = - W0                                     
     ENDIF                                 
     W0 = W0 * 16                                           
     B0 = B0 / 16 * 10 / 16 
                             
sertxd (CR,LF,"Temp is ",b9,#B1,".",#B0," .C")

PAUSE 1000
GOTO celsius
I'm guessing a bit here as i havent tryied any RF yet! lol hopefully it may help.
Code:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
mainRx:
serin 2,n1200,("abc"),w0
Convert:                                      
       let b9 =32                                      ' Display + (43) space (32)
     IF B1 > 127 THEN                       
       let b9 =45                                      ' Display - (45)
     W0 = - W0                                     
     ENDIF                                 
     W0 = W0 * 16                                           
     B0 = B0 / 16 * 10 / 16 
                             
serout 1,t9600, (254,192,"Temp is ",b9,#B1,".",#B0," .C")
wait 2

goto mainrx 

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

mainTx:
readtemp12 0,w0
serout 4,n1200,(85,85,85,85,"abc",w0)
wait 2 
goto mainTx
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
 

lbenson

Senior Member
You could try this in the simulator.
Code:
Celsius:
'Readtemp12 b.6,W0                             '  (b1,b0)  read in result ds18b20
  w0 = %1111111111100010
  gosub Convert
  w0 = %1111111111110010
  gosub Convert
  w0 = %0000000000000010
  gosub Convert
  w0 = %0000000000010010
  gosub Convert
  w0 = %0000000000100010
  gosub Convert
  pause 5000
  goto Celsius
                                
Convert:                                      
       let b9 =32                                      ' Display + (43) space (32)
     IF B1 > 127 THEN                       
       let b9 =45                                      ' Display - (45)
       W0 = - W0                                     
     ENDIF                                 
     W0 = W0 * 16                                           
     B0 = B0 / 16 * 10 / 16 
                             
sertxd (CR,LF,"Temp is ",b9,#B1,".",#B0," .C")

     RETURN
Step through in the simulator to see whether b9 (the sign indicator) is space (" ") or minus ("-").

Note that the 4 least significant bits are represented as the decimal part of the temperature. If you change the "0010" that I have used, you will see a change in the decimal part of the displayed number.

Change the last 4 bits to "0000" and you will see whole numbers displayed.

When w0 is negative, the "w0 = - w0" converts the number to positive (and you've already determined that the b9 sign is "-").

See what the readings are if you put the DS18B20 in an icebox.
 
Last edited:

Vroom

Member
Right, thanks, that not my question. Finally I worked out how use less than only two variables into sender by wireless as not three variables. Likely same READTEMP use 'IF B1 > 127 then' for negative values (ie negative values will appear as 128 + numeric value). READTEMP12 can use 'IF B1 > 127 then' for RF wireless, I have done my code its working, I edited show example;

TX:
readtemp12 1,w0
IF B1 > 127 THEN Let b2=1 W0 = - W0 endif
W1 = W1 * 16
B0 = B0 / 16 * 10 / 16

if b2=1 then let b1=b1 + 127 b2=0 endif 'if use negative

if b1 = b4 then sleep 54 goto TX endif 'if every same degcel so not send as save battery sleep for 2 mins every check degcel if different number so send.

for b3 = 1 to 20
serout 0,N600,(85,85,85,85,85,85,"adt",b0,b1)
pause 10
next b3
let b4 = b1 'make remember number degcel after sent
goto TX

'-----------------------------------------------

RX:
serin C.7, N600_4, ("adt"), b0, b1
if b1=127 then let b1 = 0 b2 = 45 goto ahead endif 'show -0.1 to -0.9
if b1 > 127 then let b1 = b1 - 127 b2 = 45 goto ahead endif 'show -1.0 to -55
b2=32 'space

ahead:
serout 1,T9600, (254,192,"Temp= ",b2,#b1,46,#b0,"oC")
pause 50
goto RX

'-------------------------------------------------

I glad that done for RF wireless.
 
Last edited:

marks

Senior Member
I was also a little confused until i saw your code quite clever!
requiring whole degrees so it would rest until there was change.

w0=-w0 can be different than performing b0=-b0 and b1=-b1 seperately

this shoud work hope you try it .
Code:
TX:
readtemp12 1,w0

W0=W0+880*16

if b1 = b4 then sleep 54 goto TX endif 'if whole degrees same do not send save battery sleep for 2 mins  if different send.

for b3 = 1 to 20
serout 0,N600,(85,85,85,85,85,85,"adt",b0,b1) 
pause 10
next b3
let b4 = b1 ' remember Whole degrees after sending
goto TX

'-----------------------------------------------

RX:
serin C.7, N600_4, ("adt"), b0, b1

          let b2 =32
          B1=B1-55
             if b1 >127 then
             let b2 =45
             w0=-w0
             endif   
          B0=B0/16*10/16

ahead:
serout 1,T9600, (254,192,"Temp= ",b2,#b1,46,#b0,"oC")
pause 50
 

Vroom

Member
Thanks, Marks. That beautiful your code look short. I will try test with them tonight, I see that look different W0=W0+880*16 I'm curious calculator how work look like, glad that possible still use my code 'if b1 = b4 then sleep 54 goto TX endif' in your code changed, good save battery not often send if same number waste power. Thank you very much. I remember saw your coded muiltpex display clock and temp LED use 20X2 I Like it and will make one also extra code temp for outside by wireless RF later then will put in Post.
 

marks

Senior Member
Here's some new examples for our DS18B20 using Celsius,Fahrenheit and Kelvin degrees.
Code:
SYMBOL Ds18b20      = C.0
SYMBOL Temperature  = W0  SYMBOL TempMsb  = b1  SYMBOL TempLsb = b0
SYMBOL Sign         = b2
SYMBOL D0           = b3
SYMBOL D1           = b4 
SYMBOL D2           = b5 
SYMBOL D3           = b6 
SYMBOL D4           = b7

Main:
Readtemp12 Ds18b20,Temperature 
            
  Convert:                                      
       Sign = " "                                                   '  Display +                                  
'    Temperature = Temperature  + 880 * 9 / 5 - 1072                 ' *uncomment for Fahrenheit (-67.0 to 257.0)
'    Temperature =  Temperature + 4370                               ' *uncomment for Kelvin     (218.1 to 398.1)    
     IF TempMsb > 127 THEN                       
       Sign = "-"                                                   '  Display - 
     Temperature = - Temperature                                     
     ENDIF 
    Temperature = Temperature  * 5 / 4 * 5 + 5                      '  Celsius (-55.0 to 125.0) rounding up 0.05 to 0.09    
     
     BINTOASCII Temperature,D4,D3,D2,D1,D0  
      IF  D4 = "0" THEN : D4 = " "                                  ' leading zero blanking 
       IF D3 = "0" THEN : D3 = " " : ENDIF                          ' leading zero blanking 
      ENDIF                          
                          
 SERTXD (CR, LF, "Temperature ",Sign,D4,D3,D2,".",D1," degrees", CR, LF) '  (0.1)resolutuion
   
PAUSE 1000
GOTO Main
Code:
SYMBOL Ds18b20       = C.1
SYMBOL Temperature   = W0  SYMBOL whole_degrees  = b1  SYMBOL decimal_degrees = b0
SYMBOL Sign          = b2

Main:
Readtemp12 Ds18b20,Temperature                               
                            
  Convert:                                      
       Sign = " "                                               '  Display +                                      
     IF whole_degrees > 127 THEN                       
       Sign = "-"                                               '  Display - 
     Temperature = - Temperature                                     
     ENDIF

                                      
     Temperature = Temperature * 16                             'Celsius -55.0C to 125.0C              
     decimal_degrees = decimal_degrees / 4 * 25 / 16 + 5 / 10 'rounding up 0.05 to 0.09 (0.1)resolutuion

    
                     
   SERTXD (CR, LF, "Temperature  ",Sign,#whole_degrees,".",#decimal_degrees,"  Degrees C", CR, LF)
   
PAUSE 1000
GOTO Main
Code:
SYMBOL Ds18b20       = C.1
SYMBOL Temperature   = W0  SYMBOL whole_degrees  = b1  SYMBOL decimal_degrees = b0
SYMBOL Sign          = b2

Main:
Readtemp12 Ds18b20,Temperature                               
                           
  Convert:                                      
       Sign = " "                                               '  Display +                                
     Temperature = Temperature + 880 * 18 /10 - 1072            '  conversion to Fahrenheit  
     
     IF whole_degrees > 127 THEN                       
       Sign = "-"                                               '  Display - 
     Temperature = - Temperature                                     
     ENDIF

     
     Temperature = Temperature * 16                             'Fahrenheit -67.0F to 255.9F    
     decimal_degrees = decimal_degrees / 4 * 25 / 16 + 5 / 10 'rounding up 0.05 to 0.09 (0.1)resolutuion

                         
   SERTXD (CR, LF, "Temperature  ",Sign,#whole_degrees,".",#decimal_degrees,"  Degrees F", CR, LF)
   
PAUSE 1000
GOTO Main
Code:
SYMBOL Ds18b20         = C.1
SYMBOL Temperature     = W0  SYMBOL whole_degrees  = b1  SYMBOL decimal_degrees = b0
SYMBOL Kwhole_degrees  = W1

Main:
Readtemp12 Ds18b20,Temperature 
                              
                           
Convert:                                          
Temperature = Temperature +880 * 16 + 4646 : Kwhole_degrees = whole_degrees + 200 'Kelvin 218.1K to 398.1K                                     
decimal_degrees = decimal_degrees / 4 * 25 / 16 + 5 / 10      'rounding up 0.05 to 0.09 (0.1)resolutuion

                         
  SERTXD (CR, LF, "Temperature  ",#Kwhole_degrees,".",#decimal_degrees,"  Degrees K", CR, LF)

PAUSE 1000
GOTO Main
 
Last edited:

marks

Senior Member
After seeing westaust55 use HIGH WORDS in a few posts
it was time to use this new commandment ** from the Bible(manual 2) lol! arhh just a few hundred more to learn.


Celsius -55.0 C to +125.0 C
Code:
SYMBOL Ds18b20      = C.0
SYMBOL Temperature  = W0  SYMBOL TempMsb  = b1  SYMBOL TempLsb = b0
SYMBOL Sign         = b2
SYMBOL D0           = b3
SYMBOL D1           = b4 
SYMBOL D2           = b5 
SYMBOL D3           = b6 
SYMBOL D4           = b7

Main:
Readtemp12 Ds18b20,Temperature 
      
  Convert:                                      
       Sign = " "                                                  '  Display +   
     IF TempMsb > 127 THEN                       
       Sign = "-"                                                  '  Display - 
       Temperature = - Temperature                                     
     ENDIF 
   Temperature = Temperature **40960                               '  Celsius (-55.0 to 125.0) 
     
     BINTOASCII Temperature,D4,D4,D3,D2,D1  
      IF  D4 = "0" THEN : D4 = " "                                 ' leading zero blanking 
      IF D3 = "0" THEN : D3 = " " : ENDIF                          ' leading zero blanking 
      ENDIF                          
                          
 SERTXD (CR, LF, "Temperature ",Sign,D4,D3,D2,".",D1," degrees C", CR, LF) '  (0.1)resolutuion
   
GOTO Main
Code:
SYMBOL Ds18b20       = C.1
SYMBOL Temperature   = W0  SYMBOL whole_degrees  = b1  SYMBOL decimal_degrees = b0
SYMBOL Sign          = b2

Main:
Readtemp12 Ds18b20,Temperature                               
                           
  Convert:                                      
       Sign = " "                                               '  Display +                                      
     IF whole_degrees > 127 THEN                       
       Sign = "-"                                               '  Display - 
     Temperature = - Temperature                                     
     ENDIF

                                      
     Temperature = Temperature * 16                             'Celsius (-55.0C to 125.0C)              
     decimal_degrees = decimal_degrees **2560
    
                     
   SERTXD (CR, LF, "Temperature  ",Sign,#whole_degrees,".",#decimal_degrees,"  Degrees C", CR, LF)
   
PAUSE 1000
GOTO Main

Fahrenheit -67.0 F to +257.0 F
Code:
SYMBOL Ds18b20      = C.0
SYMBOL Temperature  = W0  SYMBOL TempMsb  = b1  SYMBOL TempLsb = b0
SYMBOL Sign         = b2
SYMBOL D0           = b3
SYMBOL D1           = b4 
SYMBOL D2           = b5 
SYMBOL D3           = b6 
SYMBOL D4           = b7

Main:
Readtemp12 Ds18b20,Temperature 
       
  Convert:                                      
       Sign = " "                                                  '  Display + 
  Temperature = Temperature  +880 *16 **4608 -670                  '  Fahrenheit (-67.0F to 257.0F)
     IF TempMsb > 127 THEN                       
       Sign = "-"                                                  '  Display - 
       Temperature = - Temperature                                     
     ENDIF 
    
     BINTOASCII Temperature,D4,D4,D3,D2,D1  
      IF  D4 = "0" THEN : D4 = " "                                 ' leading zero blanking 
      IF D3 = "0" THEN : D3 = " " : ENDIF                          ' leading zero blanking 
      ENDIF                          
                          
 SERTXD (CR, LF, "Temperature ",Sign,D4,D3,D2,".",D1," degrees F", CR, LF) '  (0.1)resolutuion
   
GOTO Main
Code:
SYMBOL Ds18b20      = C.0
SYMBOL Temperature  = W0 
SYMBOL units        = b4 
SYMBOL tens         = b5 
SYMBOL hunds        = b6 
SYMBOL thous        = b7

Main:
Readtemp12 Ds18b20,Temperature 
 
  Convert:                                             
  Temperature = Temperature  +880 *9 /8 -670                  '  Fahrenheit (0.0F to 257.0F)
        units = temperature  //10  
        tens  = temperature   /10 //10
       hunds  = temperature  /100 //10
       thous  = temperature /1000 
     
 SERTXD (CR, LF, "Temperature ",#thous,#hunds,#tens,".",#units," degrees F", CR, LF) '   no blanking
 GOTO Main
Code:
SYMBOL Ds18b20       = C.1
SYMBOL Temperature   = W0  SYMBOL whole_degrees  = b1  SYMBOL decimal_degrees = b0

Main:
Readtemp12 Ds18b20,Temperature                               
                           
  Convert:                                      
                                
     Temperature = Temperature +880 *9 /5 - 1072 *16             'Fahrenheit (0.0F to 255.9F)                 
     decimal_degrees = decimal_degrees **2560                    ' (0.1)resolutuion
                      
   SERTXD (CR, LF, "Temperature  ",#whole_degrees,".",#decimal_degrees,"  Degrees F", CR, LF)
   
PAUSE 1000
GOTO Main
Code:
SYMBOL Ds18b20       = C.1
SYMBOL Temperature   = W0  

Main:
Readtemp12 Ds18b20,Temperature                               
                          
  Convert:                                      
                                
     Temperature = Temperature +880 **7373 -67             'Fahrenheit (0F to 257F)                 
                         
   SERTXD (CR, LF, "Temperature  ",#Temperature,"  Degrees F", CR, LF)
   
PAUSE 1000
GOTO Main
 
Last edited:

marks

Senior Member
Here's an example using multiple DS18B20's onewire

Each DS18B20 has a unique 64bit serial code which we can obtain using our first program.
b6(familycode) b7-b12(serialnumber) b13(checksum)
Only one device can be connected or our numbers will be corrupt!
once we have all our device numbers we can use them in our next program.
Code:
#terminal 9600                                                  ' x2(9600)  m2(4800)
SYMBOL Ds18b20      = B.6

Main:
READOWSN Ds18b20                                                ' note b6 - b13 used for READOWSN command

SERTXD (CR, LF, "Serial number  ",#b6," ",#b7," ",#b8," ",#b9," ",#b10," ",#b11," ",#b12," ",#b13, CR, LF)
pause 1000

 GOTO main
With the numbers retrieved from our first device ( 40,51,247,61,3,0,0,108 )
just insert them into our OWOUT command as shown below.
Example using 3 DS18B20's on the same 1-Wire bus.
Code:
#terminal 9600                                                      'x2(9600)  
SYMBOL OnewireDS18B20 = B.6
SYMBOL Temperature    = W0  SYMBOL TempMsb  = b1  SYMBOL TempLsb = b0  
SYMBOL Sign           = b2
SYMBOL D0             = b3
SYMBOL D1             = b4 
SYMBOL D2             = b5 
SYMBOL D3             = b6 
SYMBOL D4             = b7
SYMBOL Sensor         = b8

Main:

 OWOUT OnewireDS18B20,%1001,($CC,$44)                        ' pullup,reset(send skip rom ,send convert t)

 OWOUT OnewireDS18B20,%0001,($55,40,51,247,61,3,0,0,108,$BE) ' reset(rom serial No ,send read lsb msb)
 sensor =1
            GOSUB Convert
            
 OWOUT OnewireDS18B20,%0001,($55,40,238,12,62,3,0,0,188,$BE) ' reset(rom serial No ,send read lsb msb)
 sensor =2
            GOSUB Convert
            
 OWOUT OnewireDS18B20,%0001,($55,40,36,44,62,3,0,0,20,$BE)   ' reset(rom serial No ,send read lsb msb)
 sensor =3
            GOSUB Convert
           
  PAUSE 1000 
GOTO Main


Convert:
     OWIN OnewireDS18B20,%0000,(TempLsb,TempMsb)                                     '  read in result ds18b20                                  
       Sign = " "                                                                    '  Display +   
     IF TempMsb > 127 THEN                         
       Sign = "-"                                                                    '  Display - 
       Temperature = - Temperature                                     
     ENDIF 
     Temperature = Temperature **40960                                               '  Celsius (-55.0 to 125.0) 
     
     BINTOASCII Temperature,D4,D4,D3,D2,D1  
      IF  D4 = "0" THEN : D4 = " "                                                   ' leading zero blanking 
      IF D3 = "0" THEN : D3 = " " : ENDIF                                            ' leading zero blanking 
      ENDIF                                  
     SERTXD (CR, LF, "TempSensor",#Sensor,Sign,D4,D3,D2,".",D1," degrees C", CR, LF) '  (0.1)resolutuion       
                            
            RETURN
 
Last edited:

lewisg

Senior Member
I couldn't find this anywhere else. I'm sure there is an easier way to do it...

Code:
'convert whole number temperature values from READTEMP to Fahrenheit
'mostly stolen from marks and ehow.com 
'www.ehow.com/how_7414093_convert-negative-celsius-fahrenheit.html


SYMBOL TCin = b0
SYMBOL Temp = b1
SYMBOL Sign = b2

Main:
  
  sertxd ("Enter DS18B20 value", cr,lf)
  Serin C.1,N9600_8,TCin

  Sign = " "

  IF TCin > 145 THEN        'below 0F 
    Sign = "-"
    Temp = TCin - 128
    Temp = Temp * 9
    Temp = Temp - 160
    Temp = Temp /5
  ELSE IF TCin > 128 THEN   'below 0C but above 0F
    Sign = " "
    Temp = TCin - 128
    Temp = Temp * 9
    Temp = 160 - Temp
    Temp = Temp /5
  ELSE                      'above 0C
    Temp = TCin * 9 / 5 + 32
  ENDIF

  SERTXD (#TCin,"C = ",Sign, #Temp,"F", cr, lf) 

GOTO Main
Here is the same thing (with sign fixes) as a subroutine:
Code:
SYMBOL Temp = b0
SYMBOL Sign = b1

Main:
   
  sertxd ("Enter DS18B20 value", cr,lf)
  Serin C.1,N9600_8,Temp

  ptr = 0
  @ptr = Temp
  
  gosub ConvertDS18B20toF

  ptr = 0
  Temp = @ptr
  ptr = 1
  Sign = @ptr
    
  SERTXD (Sign, #Temp,"F", cr, lf) 

GOTO Main

ConvertDS18B20toF:

   if @ptr = 146 then        '0F
    ptr = 1
    @ptr = " "
    ptr = 0 
    @ptr = 0
  else if @ptr > 145 then   'below 0F
    ptr = 1 
    sign = "-"
    ptr = 0
    @ptr = @ptr - 128
    @ptr = @ptr * 9
    @ptr = @ptr - 160
    @ptr = @ptr /5
  else if @ptr > 128 then   'below 0C but above 0F
    ptr = 1 
    sign = "+"
    ptr = 0
    @ptr = @ptr - 128
    @ptr = @ptr * 9
    @ptr = 160 - @ptr
    @ptr = @ptr /5
  else                      'above 0C
    ptr = 1 
    sign = "+"
    ptr = 0
    @ptr = @ptr * 9 / 5 + 32
  endif

Return
 
Last edited:

the old fart

Senior Member
3 temperature inputs , output to 4 line display
20M2 chip
Code:
;temp test 3


;b0 reading from sensor
;b1 ascii of b0 
;b2 ascii of b0
;b3 ascii of b0
;b4 "-" or "+"
;b5 WARNING FREEZING
;b6 line start address
;b7
;b8
;b9
;b10 read eeprom address
;b11 read eeprom data
;b12 eeprom start address of message
;b13 length of message to send


	
	eeprom 00,("   Air Temp ")
	eeprom 20,("   Top Temp ")
	eeprom 40,("Bottom Temp ")
	eeprom 60,("-WARNING FREEZING-")
	EEPROM 80,("..................")


symbol baud=N2400



low b.2	; Initialise OLED output 
pause 500 ; Waif for OLED to initialise

serout b.2,baud,(254,1)
pause 30


main: 
 
 b5=80  ;clear freezing message
 
 readtemp c.0, b0	; Read DS18B20 on pin C.0 
 b6=128 ; line 1
 b12=0 ; eprom 00
 b13=12 ;length of message
 gosub mainsub
 
 readtemp c.1, b0	; Read DS18B20 on pin C.1 
 b6=192 ;line 2
 b12=20 ; eprom 20
 b13=12
 gosub mainsub
 
 readtemp c.2, b0	; Read DS18B20 on pin C.2 
 b6=148
 b12=40
 b13=12
 gosub mainsub
 
 
 
 ; freezing message selection

 b6=212 ;line 4
 b12=b5 ; message
 b13=20 ; length
 gosub mess
 
 
 
 
 if b5=80 then low 7:else: high 7:endif
 
 
 
goto main 


mainsub:
 if b0>127 or b0<4 then let b5=60:end if ; select freezing eeprom message

 if b0>127 then let b4="-" let b0=b0-127:else:b4="+":endif ; select + or - sign
 
 bintoascii b0, b1,b2,b3	; Convert temperature to 3 ascii digits
 
 if b1=48 then let b1=32:end if  ; blank leading zeros
 if b1>48 then skip
 if b2=48 then let b2=32:end if
skip:
  
 gosub mess
 

 serout b.2, baud, (b4,b1,b2,b3,"C"); line data
 
 

return

; eeprom messages

mess:

       serout b.2, baud, (254,b6);line select 
       b13=b13+b12
       for b10 = b12 to b13	     	; start a loop
	  read b10,b11			; read value from EEPROM
	  serout b.2,baud,(b11)		; transmit to serial LCD module
	next b10				; next character
return
 

marks

Senior Member
using DALLAS 1 _WIRE 8_BIT CRC table

The quickest method of checking data on the DS18B20 using CRC is usually achieved through READing from a TABLE.
If we unplug the sensor it will also bring up a CheckSum Fail.

An easy choice of cabling giving good results is usually unscreened CAT 5 or telephone wire.
Increase of cabling distance will require the pullups to be reduced from 5K to 1K ohm
for best results using the pullup close to the picaxe master and supply @ 5v.

Code:
#picaxe 20x2 'version C.1 *marks
#terminal 9600
EEPROM   0,(  0, 94 , 188, 226,  97,  63, 221, 131, 194, 156)
EEPROM  10,(126,  32, 163, 253,  31,  65, 157, 195,  33, 127) 
EEPROM  20,(252, 162,  64,  30,  95,   1, 227, 189,  62,  96)
EEPROM  30,(130, 220,  35, 125, 159, 193,  66,  28, 254, 160) 
EEPROM  40,(225, 191,  93,   3, 128, 222,  60,  98, 190, 224) 
EEPROM  50,(  2,  92, 223, 129,  99,  61, 124,  34, 192, 158)
EEPROM  60,( 29,  67, 161, 255,  70,  24, 250, 164,  39, 121)
EEPROM  70,(155, 197, 132, 218,  56, 102, 229, 187,  89,   7)
EEPROM  80,(219, 133, 103,  57, 186, 228,   6,  88,  25,  71) 
EEPROM  90,(165, 251, 120,  38, 196, 154, 101,  59, 217, 135)
EEPROM 100,(  4,  90, 184, 230, 167, 249,  27,  69, 198, 152)
EEPROM 110,(122,  36, 248, 166,  68,  26, 153, 199,  37, 123)
EEPROM 120,( 58, 100, 134, 216,  91,   5, 231, 185, 140, 210)
EEPROM 130,( 48, 110, 237, 179,  81,  15,  78,  16, 242, 172)
EEPROM 140,( 47, 113, 147, 205,  17,  79, 173, 243, 112,  46)
EEPROM 150,(204, 146, 211, 141, 111,  49, 178, 236,  14,  80)
EEPROM 160,(175, 241,  19,  77, 206, 144, 114,  44, 109,  51)
EEPROM 170,(209, 143,  12,  82, 176, 238,  50, 108, 142, 208)
EEPROM 180,( 83,  13, 239, 177, 240, 174,  76,  18, 145, 207)
EEPROM 190,( 45,  115,202, 148, 118,  40, 171, 245,  23,  73)
EEPROM 200,(  8,  86, 180, 234, 105,  55, 213, 139,  87,   9)
EEPROM 210,(235, 181,  54, 104, 138, 212, 149, 203,  41, 119)
EEPROM 220,(244, 170,  72,  22, 233, 183,  85,  11, 136, 214)
EEPROM 230,( 52, 106,  43, 117, 151, 201,  74,  20, 246, 168)
EEPROM 240,(116,  42, 200, 150,  21,  75, 169, 247, 182, 232)
EEPROM 250,( 10,  84, 215, 137, 107,  53)

   SYMBOL OnewireDS18B20 = C.7
   SYMBOL CRC            = B1
   SYMBOL CRCbyte        = B2         
   SYMBOL Temperature    = W2    SYMBOL TempLSB       = B4   ' byte0
                                 SYMBOL TempMSB       = B5   ' byte1
   SYMBOL Sign           = B6    SYMBOL UserByte1     = B6   ' byte2
   SYMBOL D0             = B7    SYMBOL UserByte2     = B7   ' byte3
   SYMBOL D1             = B8    SYMBOL Configuration = B8   ' byte4
   SYMBOL D2             = B9    SYMBOL Reserved255   = B9   ' byte5
   SYMBOL D3             = B10   SYMBOL Reserved      = B10  ' byte6
   SYMBOL D4             = B11   SYMBOL Reserved16    = B11  ' byte7
                                 SYMBOL CRCchecksum   = B12  ' byte8      
Main:
 OWOUT OnewireDS18B20,%1001,($CC,$44) ' pullup,reset(send skip rom ,send   convert t )

 OWOUT OnewireDS18B20,%0001,($CC,$BE) '        reset(send skip rom ,send read lsb msb)
 
CyclicRedundancyCheck:                ' DALLIS 1_WIRE 8_BIT CRC
bptr = 4  
 OWIN OnewireDS18B20,%0000,(@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr) ' read 9 bytes from  DS18B20 
CRC=0
FOR bptr = 4 to 11
  CRCbyte= @bptr
   CRCbyte = CRC XOR CRCbyte 
  READ CRCbyte,CRC      
NEXT bptr

IF CRC <> CRCchecksum OR Reserved16 = 0 THEN : SERTXD (CR,LF, "Checksum Fail") : GOTO Main : ENDIF

ConvertTemperature:                                     
      Sign = " "                                                     ' Display +
       Temperature = Temperature +880 *16**46080 -6700               ' Fahrenheit(-67.0'F to 257.0'F)   
     IF TempMsb > 127 THEN                       
       Sign = "-"                                                    ' Display - 
       Temperature = - Temperature                                    
     ENDIF    
       Temperature =   Temperature +5                                ' round up                                                  
                  BinTOASCII Temperature,D4,D3,D2,D1,D0 
                  IF  D4 = "0" THEN : D4 = " "                       ' leading zero blanking 
                   IF D3 = "0" THEN : D3 = " " : ENDIF               ' leading zero blanking 
                  ENDIF  
            sertxd (CR, LF, "  Temperature ",Sign,D4,D3,D2,".",D1,"'F")
    
PAUSE 1000 : GOTO Main
 
Last edited:

marks

Senior Member
DALLAS 1 _WIRE 8_BIT CRC polynomial

If we need our EEPROM space elsewhere we can also use a polynomial
it is still fairly quick as it needs to shift through through each bit of the 8bytes (64bits)
that makeup the CheckSum.
Rich (BB code):
#picaxe 20x2 'version C.1 *marks
#terminal 9600
   SYMBOL OnewireDS18B20 = C.7
   SYMBOL Check          = B0   ' bit0
   SYMBOL CRC            = B1
   SYMBOL CRCbyte        = B2   
   SYMBOL Index          = B3     
   SYMBOL Temperature    = W2    SYMBOL TempLSB       = B4   ' byte0
                                 SYMBOL TempMSB       = B5   ' byte1
   SYMBOL Sign           = B6    SYMBOL UserByte1     = B6   ' byte2
   SYMBOL D0             = B7    SYMBOL UserByte2     = B7   ' byte3
   SYMBOL D1             = B8    SYMBOL Configuration = B8   ' byte4
   SYMBOL D2             = B9    SYMBOL Reserved255   = B9   ' byte5
   SYMBOL D3             = B10   SYMBOL Reserved      = B10  ' byte6
   SYMBOL D4             = B11   SYMBOL Reserved16    = B11  ' byte7
                                 SYMBOL CRCchecksum   = B12  ' byte8
   SYMBOL CRCerrors      = W7     
Main:
OWOUT OnewireDS18B20,%1001,($CC,$44) ' pullup,reset(send skip rom ,send   convert t )

OWOUT OnewireDS18B20,%0001,($CC,$BE) '        reset(send skip rom ,send read lsb msb)

CyclicRedundancyCheck:                ' DALLIS 1_WIRE 8_BIT CRC
bptr = 4 
OWIN OnewireDS18B20,%0000,(@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr) ' read 9 bytes from  DS18B20 
CRC=0
FOR bptr = 4 to 11
  CRCbyte= @bptr
  FOR  Index = 0 to 7
  Check = CRC XOR CRCbyte
   CRC = CRC >>1 : CRCbyte = CRCbyte >>1  
    IF bit0 = 1 THEN : CRC = CRC XOR %10001100 : ENDIF ' Polynomial  x^8 + x^5 + x^4 + 1 = 10001100
  NEXT Index    
NEXT bptr

IF CRC <> CRCchecksum OR Reserved16 = 0 THEN :INC CRCerrors :  SERTXD (CR,LF, "Checksum Fail") : GOTO Main : ENDIF

ConvertTemperature:                                    
       Sign = " "                                                    ' Display +  
     IF TempMsb > 127 THEN                      
       Sign = "-"                                                    ' Display -
       Temperature = - Temperature                                   
     ENDIF
            Temperature = Temperature *8**51200 +5                   ' Celsius(-55.0'C to 125.0'C)rounded up
                  BinTOASCII Temperature,D4,D3,D2,D1,D0
                  IF  D4 = "0" THEN : D4 = " "                       ' leading zero blanking
                   IF D3 = "0" THEN : D3 = " " : ENDIF               ' leading zero blanking
                  ENDIF
     SERTXD (CR, LF, "  Temperature ",Sign,D4,D3,D2,".",D1," 'C    ",#CRCerrors)
   
GOTO Main
edit change
Code:
too [code="rich"]
 

Attachments

Last edited:

westaust55

Moderator
If you are going down the path of using 1-Wire network commands to allow multiple devices on a single PICAXE IO pin you may wish to have a look at some of the work which I did previously.
See here:http://www.picaxeforum.co.uk/showthread.php?15306-One-Wire-Devices-Networks

Early examples cover CRC checks (ultimately there are 8-bit and 16-bit CRC routines) and multiple DS18B20's also demonstrating sending the CONVERT command to all simultaneously, waiting the required time depending upon the desired 9 to 12 bit resolution and then reading each back sequentially.
By the end of the thread I had covered quite a few 1-Wire devices and had developed a network with remote:
  • Keypads
  • LCD displays
  • LED’s
  • Switches
  • Temp sensors
  • memory chips
  • ADC channels.


Even the ability to write to EPROM (as opposed to EEPROM) where a higher voltage was needed.
 
Hi, I was getting all excited while reading this really helpful & interesting thread, because I need to make a fan controller for two large sealed battery boxes which will turn the Cooling/venting fan on during charging or during discharge if the internal temperature is more than a few degrees above ambient. I've bought several 08M2s for this and other associated projects, so have limited pins to play with, but plenty of code space.

The READOWSN function works fine with my example of a DS18b20 but it seems that all the other routines for using multiple DS18b20s on one pin won't work on an 08M2. Is this right?
 

hippy

Technical Support
Staff member
The READOWSN function works fine with my example of a DS18b20 but it seems that all the other routines for using multiple DS18b20s on one pin won't work on an 08M2. Is this right?
That is correct; the M2 devices do not cater for multiple 1-wire devices on a pin and do not support OWIN or OWOUT command.
 

marks

Senior Member
When after an accurate temperature sensor most will recommend the si7051
maximum error just plus or minus 0.1'C but the data sheet reveals this is between
just 35.8 to 41"C and from 20 to 70'C(+-0.13).ideal for battery use and good resolution (0.01)
drop in replacements should all perform the same but does break the piggybank.

Time to compare a few sensors a new DS18B20 , SI7051 , BMP180 , DS3231SN all on the same supply 3.3v
all are easy plug in boards on I2C except the ds18b20 breadboarded with 3300 ohm pullup on the data
and a 4uf tant on its nearby supply pins and regulated supply for accurate performance.

To my surprise all performed quite well. Most digital sensors are BANDGAP BASED
The ds18b20 is well within the (+-0.5) range. Maxim have a mean error chart on their site
here I've produced a modded version, the form of the curve is always the same for all Ds18b20's
the offset may vary depending on the batch and calibration.
We can try and improve accuracy by compensating for the offset and curvature error characteristic of the device.
using the default offset value the results seem quite close to what i would expect.
I guess just being lucky with the last batch I received !
Now I'll just wait for a 38'C day to check or calibrate with the si7051 lol.
Code:
#picaxe 18m2         'marks
#no_data
pause 4000
#terminal 4800
SETFREQ M4
   
  TABLE 9,(101,81,64,47,35,24,18,9,4,2,0,2,4,9,14,25,36,48,62,78,98) ' DS18B20  @ 3.3v  (-10'C to 90'C )
SYMBOL Temperature = W0    SYMBOL UT  = W0   SYMBOL Temp = W0      SYMBOL TempMsb = b1   SYMBOL TempLsb = b0                    
SYMBOL TempDecimal = W1    SYMBOL MC  = W1                         SYMBOL      rr = b3   SYMBOL       R = b2
  SYMBOL inX2 = W2    SYMBOL MD  = W2                         SYMBOL      D1 = b5   SYMBOL      D0 = b4
  SYMBOL   X1 = W3    SYMBOL AC5 = W3   SYMBOL CurveData = b6 SYMBOL      D3 = b7   SYMBOL      D2 = b6
  SYMBOL   X2 = W4    SYMBOL AC6 = W4   SYMBOL Offset = b8    SYMBOL      D5 = b9   SYMBOL      D4 = b8
                                             SYMBOL   index = b11  SYMBOL    sign = b11  SYMBOL      D6 = b10
Main: sertxd  (cr,"Temperature  ")
DS18B20:                                               ' -55.00 to 125.00'C 12bit 0.0625 +-2'C (-10 to 85'C +-0.5'C)
   ReadTemp12 C.1,Temperature  
   Temperature = Temperature *16
 sign=" " : IF TempMsb >127 THEN : Temperature = -Temperature : sign="-" : ENDIF
      TempDecimal = TempLsb *64 **40000
 Gosub Display0
 
DS18B20calibrated: SYMBOL ZEROoffset = 239             ' Mean Error  @ 40'C (-0.2386) 3.5v
   ReadTemp12 C.1,Temperature      
   Temperature = Temperature +880*16
   CurveData = TempMsb                                                         ' Error Curve correction (-10 to 90'C)
     index = CurveData/5 : READtable index,D0 : INC index : READtable index,D1 ' Tabled values every 5 degrees
       CurveData = CurveData //5  :IF D0 > D1 THEN : SWAP D0,D1:CurveData =5 -CurveData :ENDIF : CurveData = D1 -D0 *CurveData /5 +D0
     Offset = ZEROoffset **16778                                                  
   Temperature = Temperature -14080
     IF Temperature >23280 AND Temperature <62976 THEN : CurveData = 110 : ENDIF ' maximum correction 0.43 -offset for ungraphed data >90 <-10
 sign=" " : IF TempMsb >127 THEN : Temperature = -Temperature : sign="-" : ENDIF
       Temperature = Temperature +Offset -CurveData :IF TempMsb =255 THEN : Temperature = -Temperature : sign="-" : ENDIF
     TempDecimal = TempLsb *64 **40000
 Gosub Display0
   
SI7051:  HI2CSETUP I2CMASTER, $80, I2Cslow_4, I2CBYTE  ' -40.00 to 125.00'C 14bit 0.01 +-0.25'C (  20 to 70'C +-0.13'C )          
  Hi2Cin $E3, (TempMsb,TempLsb)                        '                                        ( 35.8 to 41'C +-0.1'C )          
 Temperature = Temperature **17572 -4685                          
 sign=" " : IF TempMsb >127 THEN : Temperature = -Temperature : sign="-" : ENDIF          
 Gosub Display                
             
BMP180:  HI2CSETUP I2CMASTER, $EE, I2Cslow_4, I2CBYTE  ' -40.00 to 85.00'C 16bit 0.01 (0 to 65'C +-2'C)
  Hi2Cin  $B4,(b9,b8)            '       AC6 calibration data from EEPROM
  Hi2Cin  $B2,(b7,b6)            '       AC5 calibration data from EEPROM
  Hi2Cin  $BE,(b5,b4)            '       MD  calibration data from EEPROM
  Hi2Cout $F4,($2E) : pause 100  '       UT start conversion wait 4.5ms
  Hi2Cin  $F6,(B1,B0) : pause 20 '       UT read 16 bit data
 X1 = UT -AC6 *2 **AC5          
 X2 =  X1 +MD
    inX2 = $FFFF /X2 : Temp = $FFFF //X2 +1
     rr = X2 //10 : X2 = X2 /10
      FOR index = 1 TO 3
       inX2 = inX2 *10 : inX2 = Temp /X2 +inX2
       r = inX2 //10 *rr
       Temp = Temp //X2 *10 -r
      NEXT index
  Hi2Cin $BC,(b3,b2) : pause 20 '      MC calibration data from EEPROM
 X2 = -MC *3 **44740 **inX2  
       Temperature = X1 -X2 : sign=" " : IF TempMsb >127 THEN : Temperature = -Temperature : sign="-" : ENDIF
       Temperature = Temperature **40960
       Gosub Display
 
DS3231:  HI2CSETUP I2CMASTER, $D0, I2Cslow_4, I2CBYTE  ' -40.00 to 85.00'C 10bit 0.25 +-3'C
   Hi2Cin $11,(TempMsb,TempLsb)
      sign=" " : IF TempMsb >127 THEN : Temperature = -Temperature : sign="-" : ENDIF
      Temperature = Temperature **25600
 Hi2Cout $0E,($20) ' Convert Temperature
      Gosub Display
 
  GOTO Main
    DISPLAY0:
           BinTOASCII TempMsb,D6,D5,D4
            IF  D6 = "0" THEN : D6 = Sign                      ' leading zero blanking
        IF D5 = "0" THEN : D6 = " " : D5 = Sign : ENDIF   ' leading zero blanking
  ENDIF                          
   BinTOASCII TempDecimal,D3,D3,D2,D1,D0
   
           sertxd (D6,D5,D4,".",D3,D2,D1,D0,"'C  ")
  Return
  DISPLAY:
           BinTOASCII Temperature,D4,D3,D2,D1,D0
                   IF  D4 = "0" THEN : D4 = " "                ' leading zero blanking
                    IF D3 = "0" THEN : D3 = " " : ENDIF        ' leading zero blanking
                   ENDIF                                                                                                            
           sertxd (Sign,D4,D3,D2,".",D1,D0,"'C  ")
  Return
 

Attachments

RSanger

New Member
EQUATIONS EXPLAINED - for the curious
I was fascinated by the simplicity of Marks post 2/8/2011 using the equation
w0 = w0+880/16*9/5-67 to convert from C to F.
what is the 880 and -67?
why not the usual C*9/5 +32? I see now he has divided W0 by 16, thus shifting away the fractional part.
in other words: (w0+880)/16*9/5 - 67 = w0/16*9/5 + 880/16*9/5 -67 = (w0/16)*9/5 +32.... oh!
Another one that baffled me was the late, great PH Anderson's equation
F=(C * 11.25 + 3200 ) /100
which was implemented as shown at the end of this post.
NOTE NOTE NOTE this solution doen't just ignore the fractional component, but rather uses it in the conversion to Fahrenheit before truncating off the integer part. but what is the 11.25 and the 3200?
insight:
he first multiplies the raw data by 100 to preserve the fractional part in his whole number calculations. but the raw data can be thought of as the total number of .0625 increments in the measurement. so mathematically: .0625*9/5*100 is 11.25!!
here's how he programs it:
SignBit = Temp_Raw/ 256 / 128

IF SignBit = 1 THEN ' its negative
Temp_Raw = Temp_Raw ^ $ffff + 1 ' take the two's comp to make it positive
ENDIF

'Multiply by 11.25 - This is 100 * Tf
Y = Temp_Raw / 4 '0.25
X = Temp_Raw * 11 + Y

IF SignBit = 1 THEN ' its negative
X = X ^ $ffff + 1 ' take the two's comp to make X negative, if needed
ENDIF

x = x + 3200 'Add 32 degrees ************
Whole = X / 100
Fract = X // 100

This was my approach
TempWord2 = TempWord1 * 11 ' Temp = value * 11.25 + 3200
TempWord1 = TempWord1 * 25 / 100
TempWord1 = TempWord1+TempWord2+3200 / 100 ' truncate to whole degree
 

marks

Senior Member
Hi RSanger,
thanks for your interest !
The DS18B20 is a 12bit (4096) signed sensor so our positve data is from 0 to 2047
to obtain our whole degree Celsius we divide by /16
the Operating Temperature Range is quoted as -55°C to +125°C (-67°F to +257°F)
with the negative range its a lot easier to do our picaxe maths with positive numbers.
so -55°C x16 = -880 so we add 880
for 125°C x16 gives us 2000 steps and 125/2000 gives us our stepvalue 0.0625°C for °F x9/5 = 0.1125°F
because we added 880 we need to subtract again(above you can see at -55°C its -67°F) so we just need to subtract 67°F
If we can fit the full value in a word we only really need to place a sign in our code when we wish to display negative values.
The small trick with that previous code w0 = w0+880/16*9/5-67 we're not worried about the fractional part
because every °C is precise but can be rewritten as w0 = w0+880*9/80-67
Rich (BB code):
#picaxe 08m2 'marks         
#no_data 
#terminal 19200
SETFREQ M16 
SYMBOL DS18B20 = C.1
SYMBOL temp_raw = W0 
SYMBOL Whole    = W1
SYMBOL Decimal  = W2
SYMBOL SensorCheck = b6 ' FamilyCode for DS18B20 = 40
SYMBOL signF       = b7

Checksensor: sertxd("CheckSensor",cr,lf) : pause 4000 ' message if reset , sensor disconnected or low voltage
Main:                       ' best accuracy with 5v Regulated Supply , 4uF Tant decouplin and pullup close to sensor 
                                ' erratic readings or 185.0'F check for Hardware problem usually supply and pullup related                                                    
  B6=255 : READOWSN Ds18b20 : If SensorCheck <>40 THEN Checksensor ' note b6 - b13 used for READOWSN command
     Readtemp12 Ds18b20,temp_raw                               
       B6=255 : READOWSN Ds18b20 : If SensorCheck <>40 THEN Checksensor ' note b6 - b13 used for READOWSN command 
    
Convert:                      ' Fahrenheit(-67.0000'F to 257.0000'F)
      Whole = temp_raw +880 *9      
      Decimal = Whole //80*125
      Whole = Whole /80 -67  
      
        signF= " " : IF Whole > 262 THEN : Whole = - Whole -1 : signF = "-"
           IF Decimal = 0 THEN INC Whole ELSE : Decimal = 10000 -Decimal : ENDIF
                     ENDIF 

sertxd (#temp_raw,"   ",signF,#Whole,".")
IF Decimal = 0 THEN  :  sertxd("00") : ENDIF
IF Decimal < 1000 THEN : sertxd("0") : ENDIF
sertxd (#Decimal,"'F    ")     ' 262.2875'F 

Convert1:                     ' Fahrenheit(0.05'F to 257.00'F)+5/10 roundedup
  Whole = temp_raw +284 *16 **46080 +10 /10  '  *16**46080 is equivalent to *11.25
    Decimal = Whole // 10 
      Whole = Whole / 10  
      IF Whole >262 THEN Checksensor ' (minus Fahrenheit)
sertxd (#Whole,".",#Decimal,"'F ",cr,lf)     ' 257.0'F

pause 1000
goto main
 
Last edited:
Top