(Feb 25, '05). This is currently being developed.
Introduction.
The is a popular relative humdity to DC voltage sensor. True relative humidity varies as a function of temperature and the DS2438 battery monitor which is capable of measuring temperature and performing an A/D measurement is an ideal companion to perform relative humidity meeasurements. I offer an assembled arrangement as the RH #166 RH Sender Module. Other similar arrangements are available and are discussed on the web.
The advantage in using the DS2438 is that it is a member of the Dallas 1-W family and thus many may be accommodated on one or two Dallas 1-W networks.
I offer a number of designs which are controlled via an RS232 COM port (or a USB to RS232 adaptor) which may be used to interface with the Dallas DS2438, in addition to other Dallas devices. These include the TM #128, IOM #135E, IOM #136 and IOM #142A modules.
This application note discusses Serial RS232 communication between a PC running Windows and these modules using to perform relative humidity measurements and calculate the dew point. This is illustrated in the context of the TM #128 temperature module followed by a discussion of how this might be modified for use with the other modules.
Program TM128_2.Bas.
Program TM128_2.Bas initiates a measurement sequence each minute by sending any character to the TM #128. The TM #128 then returns the measurement results. An example is used for a brief explanation;
0 00 10 9DD7 26.12 01 10 BD53 26.12 02 28 3C2C 26.32 03 22 5BFC 26.43 10 10 0C26 27.18 11 10 0AD7 27.25 12 26 09CE 27.18 2.55 5.03The first line of every response is the state of the TTL input on the TM #128 unit. The subsequent lines are the result of measurements made on the two Dallas 1-wire devices. The first digit of field 1 indicates the run. The second digit is a sequential number which is assigned as each sensor is found. Field 2 is the Dallas device code (10 - DS18S20, 22 - DS1822, 28 - DS18B20, 26 - DS2438). Field 3 is an abbreviation of the unique serial number assigned by Dallas.
If the device is a temperature sensor (codes 10, 22 or 28) field 4 is the temperature in degrees C. If the device is a DS2438 battery monitor, fields 4, 5 and 6 are the temperature, Vad and Vdd.
On initiating the sequence, the program writes the descriptor "DT" to the text file. The program reads the date and time off the PC clock and writes this to the file.
On receiving the state of the TTL input, the descriptor "IN" is written to the file followed by the state, either 0 or 1.
As the result for each Dallas device is sent, the program determines if the device is a temperature sensor, and if so, writes the descriptor "TMP" to the file, followed by the temperature.
If the device is a DS2438, the program calculates the relative humidity and the dew point and writes the descriptor "RH" to the file followed by the temperature, the relative humidity and the dewpoint.
Thus, a sample;
DT 02/23/05 14:16:19 IN 0 TMP 00 10 6A0B 21.31 TMP 01 10 9DD7 21.31 TMP 02 22 5BFC 21.68 RH 03 26 1C01 20.75 35.1914613 9.3989388(Note that this sequence was not for the same configuration noted above).
TM128_2.Bas
' TM128_2.Bas (Liberty Basic)
'
' Illustrates an interface with temperature module TM #128.
'
' Initiates a measurment sequence each minute.
' Fetches the time and date off the system clock and writes to a text file with a leading
' "DT" (date-time"). Then reads the status of the single input and writes the state to
' the test file with a leading "IN" indicator.
'
' Then reads the Dallas devices on both Dallas runs.
'
' If a device is a DS18S20 / DS18B20 / DS1822 temerature sensor, the value is read and the
' device number, Dallas device code, an abbreviated Dallas serial number and the temperature
' in degress C is writtent to the text file with the leading "TMP" indicator.
'
' If the device is a DS2438, it is assummed that this is interfaced with a Honeywell HIH-3610. The
' temperature. Vad and Vdd are read. The relative humidity and dew point are calculated. The
' device number, Dallas device code, the abbreviated Dallas serial number, the temperature, relative
' humidity and dewpoint are written to the file with the leading "RH" indicator.
'
' A typical measurement sequence;
'
' DT 02/23/05 14:16:19
' IN 0
' TMP 00 10 6A0B 21.31
' TMP 01 10 9DD7 21.31
' TMP 02 22 5BFC 21.68
' RH 03 26 1C01 20.75 35.1914613 9.3989388
'
' This logging of data continues until a key is pressed. The file is opened for reading and all data
' is displayed to the terminal.
'
' copyright, Peter H Anderson, Baltimore, MD, Feb, '05
Com = 16384 ' size of buffer
' define a box
nomainwin
WindowWidth = 400
WindowHeight = 300
texteditor #window.te, 0, 0, 391, 254 'The handle for our texteditor is #window.te
graphicbox #window.gb, 800, 1, 10, 10
open "kb" for window as #window 'The handle for our window is #window
print #window.gb, "when characterInput [getChar]" 'When the user presses a key go to [getChar]
print #window, "trapclose [quit]" 'When the user closes our terminal window, go to [quit]
print #window.te, "!autoresize"; 'Tell the texteditor to resize with the terminal window
print #window, "font courier_new 9";
[top]
oncomerror [closecomm] ' not sure if this works
open "com2:9600,n,8,1, cs0, ds0" for random as #commhandle
call pause 500 ' wait for unit to settle
open "d:\data.txt" for output as #log ' open the file
close #log
T$ = time$()
Delimiter$ = ":"
TimeoutMinute = Val(ExtractField$(T$, Delimiter$, 2))
[again]
TimeoutMinute = TimeoutMinute + 1
If TimeoutMinute >= 60 Then
TimeoutMinute = TimeoutMinute - 60
End If
d$ = date$("mm/dd/yy")
t$ = time$()
open "d:\data.txt" for append as #log ' date stamp
print #log, "DT "; d$; " "; t$
close #log
print #window.te, "DT "; d$; " "; t$
print #commhandle, "!" ' send any character
x = 0
while x = 0 ' loop until either a string is received or timeout
DataLine$ = GetLine$(NumChars) ' NumChars is passed by reference
select case
case NumChars = -30000
print #window.te, "timeout"
exit while
case (NumChars = 1)
if DataLine$ = ">" then
print #window.te, DataLine$
exit while
end if
if (DataLine$ = "0" OR DataLine$ = "1") Then
InState = Val(DataLine$)
open "d:\data.txt" for append as #log
print #log, "IN "; InState ' and write it to the file
close #log
print #window.te, "IN "; InState
else
open "d:\data.txt" for append as #log
print #log, "?? "; DataLine$
close #log
print #window.te, "?? "; DataLine$
end if
case (NumChars = 1)
print #window.te, DataLine$
' exit while
case (NumChars > 2) ' probably a vaild string
Delimiter$ = Chr$(32)
DevNum$ = ExtractField$(DataLine$, Delimiter$, 1)
DevCode$ = ExtractField$(DataLine$, Delimiter$, 2)
SerNum$ = ExtractField$(DataLine$, Delimiter$, 3)
If (DevCode$ = "10" OR DevCode$ = "22" OR DevCode$ = "28") Then
TCelcius = Val(ExtractField$(DataLine$, Delimiter$, 4))
open "d:\data.txt" for append as #log
print #log, "TMP"; DevNum$; " "; DevCode$; " ";
print #log, SerNum$; " "; TCelcius
close #log
print #window.te, "TMP "; DevNum$; " "; DevCode$; " ";
print #window.te, SerNum$; " "; TCelcius
End If
If DevCode$ = "26" Then
TCelcius = Val(ExtractField$(DataLine$, Delimiter$, 4))
Vad = Val(ExtractField$(DataLine$, Delimiter$, 5))
Vref = Val(ExtractField$(DataLine$, Delimiter$, 6))
RH = CalcRH(TCelcius, Vad, Vref)
DewPoint = CalcDewPoint(TCelcius, RH)
open "d:\data.txt" for append as #log
print #log, "RH "; DevNum$; " "; DevCode$; " ";
print #log, SerNum$; " "; TCelcius; " "; RH; " "; DewPoint
close #log
print #window.te, "RH "; DevNum$; " "; DevCode$; " ";
print #window.te, SerNum$; " "; TCelcius; " "; RH; " "; DewPoint
End If
case else
print "Unknown error" ' probably an overkill
exit while
end select
wend
do
print #window.gb, "setfocus"
scan ' used for check if activity from the keyboard
T$ = time$()
Delimiter$ = ":"
CurrentMinute = Val(ExtractField$(T$, Delimiter$, 2))
loop until (CurrentMinute = TimeoutMinute)
goto [again]
[display]
' now open the file display the data
open "d:\data.txt" for input as #log
while eof(#log) = 0
line input #log, datain$
print #window.te, datain$
wend
close #log
[Done]
Goto [Done]
[getChar]
'Whenever the user presses a key, we go here to process it.
c$ = Inkey$
' print #window.te, "at getChar"
goto [display]
[closecomm]
print "Error code: ";ComErrorNumber
close #commhandle
goto [top]
function GetLine$(ByRef StatusFlag)
TimeOutTime = time$("milliseconds")
TimeOutDate = date$("days")
TimeOutTime = TimeOutTime + 3000 ' three seconds
if (TimeOutTime >= 86400000) then
TimeOutDate = TimeOutDate + 1
TimeOutTime = TimeOutTime - 86400000
end if
DataLine$ = ""
StatusFlag = 0
NumChars = 0
x=0
while x=0
if lof(#commhandle) <>0 then
c$ = input$(#commhandle, 1)
select case
case c$ = ">"
DataLine$ = c$
StatusFlag = 1 ' prompt
exit while
case c$ = chr$(13)
StatusFlag = NumChars
exit while
case c$ = chr$(10) ' ignore it
case else
DataLine$ = DataLine$ + c$
NumChars = NumChars + 1
end select
else
CurrentDate = date$("days")
CurrentTime = time$("milliseconds")
If (CurrentTime >= TimeOutTime) AND (CurrentDate >= TimeOutDate) Then
StatusFlag = -30000
exit while
end if
end if
wend
GetLine$ = DataLine$
End Function
Function CalcRH(Tc, Vad, Vref)
RHRaw = 161.29 * Vad / Vref - 25.8
RHTrue = RHRaw * (1.0 / (1.0546-0.00216 * Tc))
CalcRH = RHTrue
End Function
Function CalcDewPoint(RH, Tc)
EW = exp10(0.6607 + 7.5 * Tc / (237.3 + Tc)) * RH / 100.0
CalcDewPoint = ((0.6607 - log10(EW)) * 237.3) / (log10(EW) - 8.16077)
End Function
Function exp10(x)
exp10 = exp(2.303 *x)
End Function
Function log10(x)
log10 = log(x) / 2.303
End Function
function ExtractField$(Var$, Delimiter$, NumField)
for Num = 1 to NumField
Index = FindDelimiter(Var$, Delimiter$)
LeftStr$ = Left$(Var$, Index - 1) ' everything to the left of the space
Var$ = Mid$(Var$, Index+1) ' to the right of the space
If Num = NumField Then
exit for
End If
next
ExtractField$ = LeftStr$
end function
function FindDelimiter(Var$, Delimiter$)
for n = 1 to len(Var$)
ch$ = Mid$(Var$, n, 1)
If ch$ = Delimiter$ then
exit for
End If
If ch$ = Chr$(13) then
exit for
End If
If ch$ = Chr$(10) then
exit for
End If
next
FindDelimiter = n
end function
sub pause mil
tcurrent = time$("milliseconds")
timeout = tcurrent + mil
if timeout > 86400000 then ' roll over at midnight
timeout = timeout - 86400000
do
tcurrent = time$("milliseconds")
loop until (86400000 - tcurrent) > 1000000
end if
do
tcurrent = time$("milliseconds")
loop until (tcurrent >= timeout)
end sub
end