Periodic Temperature Measurements using the DS1820
' DS1820_2.Bas (BX-24)
'
' Performs a temperature measurement using a DS1820 every 15 seconds and
' displays. Performs an 8-bit cyclic redundancy check on the data
' received from the DS1820.
'
' Illustrates the use of 1-Wire commands and use of the on-board real time
' clock to perfrom periodic measurements.
'
' Note that Timer is used to fetch the elapsed time since midnight and thus
' periodicity is achieved using;
'
' do
' TimeCurrent = Timer()
' until (TimeCurrent >= TimeOut)
'
' However, a problem occurs when TimeOut >= 86400.0. That is, TimeOut
' is in a new day. In this case, TimeOut = TimeOut - 86400.0 and the
' timing is performed in two steps;
'
' do
' TimeCurrent = Timer()
' until (TimeCurrent <= TimeOut) ' wait for clock to roll over
'
' do
' TimeCurrent = Timer()
' until (TimeCurrent >= TimeOut)
'
' For a more complete discussion of the implemenation of the calculation of
' the 8-bit CRC, see http://www.phanderson.com/PIC
'
' BX24 DS1820
' +5
' |
' * 4.7K
' |
' RA.7 (Term 13) ---------------------- DQ (term 2)
' Terms 1 and 3 to GRD
'
'
' copyright, Peter H. Anderson, Baltimore, MD, Dec, '99
Const TEST as Byte = 1
Sub Main()
Dim Str as String *15
Dim T_C as Single
Dim TimeCurrent as Single, TimeOut as Single, Tperiod as Single
Tperiod = 15.0
Call OpenSerialPort(1, 19200)
Call PutTime(0, 0, 0.0)
TimeOut = Timer()
Do ' continually perform measurements
T_C = MakeTempMeas(13)
If (T_C < -80.00) Then
Str="CRC Error"
Call PutStr(str)
Else
Call PutS(T_C)
End If
Call NewLine()
TimeOut = TimeOut + Tperiod
If (TimeOut >= 86400.0) Then ' rollover
TimeOut = TimeOut - 86400.0
Do ' wait for RTC to roll over
TimeCurrent = Timer() ' 86398, 86399, 0
Loop Until (TimeCurrent <= TimeOut)
End If
Do
TimeCurrent = Timer()
Loop Until (TimeCurrent >= TimeOut)
Loop
End Sub
Function MakeTempMeas(ByVal Pin as Byte) as Single
' Returns temperature. Returns -89.99 if CRC error
Dim N as Integer
Dim Dat(1 To 9) as Byte, CRC as Byte
Dim T_C as Single
Call Init_1W(Pin)
Call OutByte_1W(Pin, &Hcc) ' skip ROM
Call OutByte_1W(Pin, &H44) ' perform temperature conversion
Call StrongPullup_1W(Pin) ' strong pullup
Call Init_1W(Pin)
Call OutByte_1W(Pin, &Hcc) ' skip ROM
Call OutByte_1W(Pin, &Hbe) ' get temperature data
For N = 1 to 9
Dat(N) = InByte_1W(Pin) ' fetch the nine bytes
Next
If (TEST <> 0) Then
For N = 1 to 9
Call PutHexB(Dat(N))
Call PutByte(Asc(" "))
Next
Call NewLine()
End If
CRC = CalcCRC(Dat, 9) ' calculate CRC of the 9 bytes
If (CRC <>0) Then ' CRC failure
T_C = -89.99
Else
If (Dat(2) = 0) Then ' its postive
T_C = CSng(Dat(1)) / 2.0
Else
Dat(1) = (Dat(1) XOR &Hff) + 1 ' takes the 2's comp
T_C = CSng(Dat(1)) / 2.0
End If
End If
MakeTempMeas = T_C
End Function
Sub Init_1W(ByVal Pin as Byte) ' bring Pin low for 500 usecs and then back
' high
Dim N as Integer
Call PutPin(Pin, 2) ' be sure DQ is an input
Call PutPin(Pin, 0)
For N = 1 to 3 ' adjust for 500 usec delay
Next
Call PutPin(Pin, 2)
For N = 1 to 3
Next
End Sub
Function InByte_1W(ByVal Pin as Byte) as Byte
Dim N as Integer, IByte as Byte, B as Byte
For N =1 to 8
B = Get1Wire(Pin)
If (B=1) then
IByte = (IByte\2) OR bx10000000
Else
IByte = IByte\2
End If
Next
InByte_1W = IByte
End Function
Sub OutByte_1W(ByVal Pin as Byte, ByVal OByte as Byte)
Dim N as Integer, B as Byte
For N = 1 to 8
B = OByte AND bx00000001
If (B=1) Then
Call Put1Wire(Pin, 1)
Else
Call Put1Wire(Pin, 0)
End If
OByte = OByte \ 2
Next
End Sub
Sub StrongPullUp_1W(ByVal Pin as Byte)
' Provide a hard logic one for 0.5 secs
Call PutPin(Pin, 1)
Call Sleep(0.5)
Call PutPin(Pin, 2)
End Sub
Sub PutHexB(ByVal X as Byte) ' display a byte in hex format
Dim Y as Byte
Y= X \ 16 ' convert high nibble to character
If (Y < 10) then
Y = Y + Asc("0")
Else
Y = Y - 10 + Asc ("A")
End If
Call PutByte(Y)
Y= X And bx00001111 ' same for low nibble
If (Y < 10) then
Y = Y + Asc("0")
Else
Y = Y - 10 + Asc ("A")
End If
Call PutByte(Y)
End Sub
Function CalcCRC(ByRef Buff() as Byte, _
ByVal NumVals as Integer) as Byte
Dim ShiftReg as Byte, SRlsb as Byte, DataBit as Byte, V as Byte
Dim FBbit as Byte, I as Integer, J as Integer
ShiftReg = 0 ' initialize the shift regsiter
For I = 1 to NumVals ' for each byte in the array
V = Buff(I)
For J = 1 to 8 ' for each bit
DataBit = V AND &H01 ' isolate least sign bit
SRlsb = ShiftReg AND &H01
FBbit = (DataBit XOR SRlsb) AND &H01
' calculate the feed back bit
ShiftReg = ShiftReg \ 2 ' shift right
If (FBbit = 1) then
ShiftReg = ShiftReg XOR &H8c
End if
'Call PutB(Shift_Reg) ' for debugging
'Call NewLine()
V = V \ 2 ' next bit now in least sig bit position
Next
' Call PutB(Shift_Reg)
' Call NewLine()
Next
CalcCRC = ShiftReg ' return the result
End Function