Sample DS18B20 Code Inc Negatives

rbright

Member
'******************************* SAMPLE DS18B20 CODE (Final Version) *******************************************************
'
' The Dallas Semiconductor DS18B20 has a used definable resolution of down to 4 decimal points
' although the published accuracy is +/- 0.5C in range -10C to +85C which suits most applications.
'
' The following text from the data sheet describes using the DS18B20 configured for 12 bits & which corresponds to 0.0625 degree C per bit
'
' w1 equates to b3 & b2 where b3 = MSB & b2 = LSB Least Significant Byte and contains the returned sensor value
'
' think of w1 as a double byte (8 bits = byte) width 16 bit word commencing with the contents of b3 representing
' bits b15 - b8 or the Most Significant Byte (MSB) followed by contents of b2 representing bits b7 - b0 or LSB
' where b2 LSB = bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
' 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 where 2^3 = 2 raised to power of 3
' where b3 MSB = bit15 bit14 bit13 bit12 bit11 bit10 bit9 bit8
' S S S S S 2^6 2^5 2^4
'
' NOTE: S = sign bits indicate if the temperature is pos or neg.where if positive then S = 0 & for negative S = 1
' NOTE: Negative temperature values need to be calculated by determining "2's Compliment' then alling a value of 1
' NOTE: b2 LSB bits B3 - B0 represent the fraction part of the value
'
' RANGE OF DS1B20
' DS18B20 has published max range of +125C (being in range 0000H @ 0C to 07D0H @ +125C)
' DS18B20 has published min range of -55C (being in range FFFFH @ -0.0625C to FC90H @ -55C)
'
' SAMPLE VALUES
' In following examples first 5 bits from left in MSB (15-11) are sign bits so they don't get used in example calculations below.
'
' Positive temperature examples
' Example: +125C = 0000 0111 1101 0000 (bits 10-0)=$07D0 = Decimal 2000 (2000 x 0.0625 degrees per bit = 125 degrees)
' Example: +25.0625C = 0000 0001 1001 0001 (bits 10-0)=$0191 = Decimal 401 (401 x 0.0625 degrees per bit = 25.0625)
'
' Negative temperature examples
' Example: -0.5C = 1111 1111 1111 1000 (bits 10-0)=$07F8 = Decimal 2040. Subtract from max value of 2048 - 2040 &
' multiply result by 0.0625 (8 x 0.0625 degrees = 0.5 & because of sign bits = 1 value = -0.5 deg C)
' Example: -10.125C = 1111 1111 0101 1110 (bits 10-0)=$075E = Decimal 1886. Subtract from max value of 2048 - 1886 &
' multiply result by 0.0625 (162 x 0.0625 degrees = 10.125 & because of sign bits = 1 value = -10.125
'
' The following sample code will run in the simulator.
'
' Notice some lines of code "commented out" using "'" at the start of a line
' These additional lines represent where I've used this final code to drive a LCD display through the serial out command on I/O 4 using "serout 4,N2400"
' of a 08M PICAXE to make an accurate decimal thermometer and also experiments using strings received from a remote sensor using 434 MHz UHF.
'
' **************** CODE STARTS HERE ******************
'
'parts of code from Peter Anderson and other postings
'
Symbol SensorIn = w1 ' this is where input data value is stored
Symbol Fraction = w3 ' this is where we store fraction
Symbol Whole = w4 ' this is where we store whole integer
Symbol LoopCount = B10
Symbol SignBit = B11 ' test bit b15 & if H then negative temperature reading

LoopCount = 0 'set loop counter for diagnostic purposes only
'
MEASURE: ' 434MHz UHF transmitter control (when connected) & DS18B20 temp reading routine
high 2 ' turn on DS18B20 temp sensor for sampling period - connected to I/O pin 2
pause 100 ' settling time pre temp reading
'readtemp12 1,w1 ' direct Celsius value returned into w1 16 bits 0 - 15 from a sensor connected to I/O 1
SensorIn = $FE6F ' for debugging specify value - only used in simulator mode the value 0191H emulates a reading of +25.0625 degrees
'
'
serout 4,N2400, ("Temp = ") ' First part of output string for negative temperatures to simulator


SignBit = SensorIn / 256 / 128 'Test if b15 is H
If SignBit = 0 Then Calc_Pos_Int 'Branch to calculate integer value of sensor reading
'else it's a negative value and needs to be determined by 2's compliment and add value of 1

'calc_neg:
w1 = w1 ^ $FFFF + 1 ' take 2's compliment

serout 4,N2400, ("minus ") 'First part of output string for negative temperatures to simulator the continue on to Calc_Pos_Int

Calc_Pos_Int:

Whole = SensorIn / 16 ' strip out integer part in b10 - b4

goto Calc_Fract
'
NoLeadZero: ' enter with w3 = fraction
'sertxd(#w3,CR,LF) 'on LCD display value after decimal point as ascii on LCD
serout 4,N2400,(#Fraction," ") 'display on simulator the fraction of value
'serout 4,N2400, ("?k") 'on LCD display - down cursor to next line
'serout 4,N2400, ("?l") 'on LCD clear current line - move cursor to beginning of line
goto BYE ' this end displaying temperature value

Calc_Fract: 'calc fraction from bits b0-3 of w1 and accumulate into w3
Fraction = SensorIn & %0001 MAX 1 * 0625 ' calc dec value of w1 bit 0
'i.e. if bit 0 = 1 then decimal value = .0625 degrees & store in w3
Fraction = SensorIn & %0010 MAX 1 * 1250 + w3 ' calc dec value of w1 bit 1
'i.e. if bit 1 = 1 then decimal for this bit is 0.1250 so add this to w3
Fraction = SensorIn & %0100 MAX 1 * 2500 + w3 ' calc dec value of w1 bit 2
' i.e. if bit 2 = 1 then decimal for this bit is 0.2500 so add this to w3
Fraction = SensorIn & %1000 MAX 1 * 5000 + w3 ' calc dec value of w1 bit 3
'i.e. if bit 3 = 1 then decimal for this bit is 0.5000 so add this to w3
goto DISPLAY

DISPLAY: ' enter this with w4 = integer & w3 = fraction
'serout 4,N2400, ("?f") ' this clears LCD & homes the cursor
'serout 4,N2400,("Temp = ") ' text to LCD
serout 4,N2400,(#Whole,".") ' send integer part followed by decimal point - display as text
'
If Fraction>=1000 THEN NoLeadZero ' don't send leading zero after decimal point
serout 4,N2400,("0") ' send leading zero
goto NoLeadZero


BYE:
serout 4,N2400,("Loop Count = ",#LoopCount,LF) ' display a loop count value
low 2 ' turn off DS18B20 temp sensor to save power
LoopCount = LoopCount + 1 ' increment loop count
sleep 1 ' power down (adjust to suit SLEEP units 2.3 sec) use 26 for 1 min sampling delay
goto measure ' loop to resample DS18B20 temperature & start again
 
Top