(Mar 5, '05).
Introduction.
This discussion presents sample code using to control and collect data from the WX #175 weather package. I have found that Liberty Basic provides an inexpensive means to interface with a PC Com Port, it seems well supported, and I found the learning curve not to be severe. I am not too sure I am very experienced with it, but you may opt to use snippets and modify them for whatever platform you are using.
Program WX175_1 is intended to illustrate all capabilities of the WX #175 (Firmware Version B). A text window is opened, the COM port is opened and each minute a measurement sequence is performed. Note that the details of the text window, writing to and reading from the Com port, initiating a periodic process and extracting fields from a string and converting the string fields to numeric valuses are discussed in the context of my TM #125 module. The TM #125 is similar to the WX #175 in concept in that the PC initiates a measurement command and the TM #125 returns data.
In this program, subroutines are called to measure pressure, relative humidity on each of the two RH channels, perform 12-bit A/D conversion on all six channels and perform temperature measurements on each of the two Dallas 1-W runs. It also illustrates how to read the events from a DS2423 dual 32-bit counter which may share either of the Dallas 1-W runs with temperature sensors. It also illustrares how to perform counting measurements over a period of seconds, and how to turn either of the two TTL outputs on and off and read the state of the two TTL inputs.
In this routine, I did not log data to a text file. However, this is discussed in the TM #125 discussion.
Note that when measuring relative humidity, the dewpoint is also calculated and displayed. The expressions for calculating dewpoint were taken from the web site.
' WX175_1.Bas
'
' Illustrates an interface between a PC (Wondows) and the EX175 using Liberty Basic.
'
' Every two minutes, reads pressure, relative humidity on both units, A/D vales on all channels and
' all temperatures on both of the Dallas 1-W runs.
'
' copyright, Peter H. Anderson, Baltimore, MD, Mar, '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 a file for logging
close #log ' actually no logging is done in this program
T$ = time$()
Delimiter$ = ":"
TimeoutMinute = Val(ExtractField$(T$, Delimiter$, 2))
[again]
TimeoutMinute = TimeoutMinute + 2
If TimeoutMinute >= 60 Then
TimeoutMinute = TimeoutMinute - 60
End If
Call pause 1000
Call MeasurePressure 3000 ' 500 ms timeout
Call pause 1000
Call MeasRH 0, 3000
Call pause 1000
Call MeasRH 1, 3000
For N = 0 to 5
Call pause 1000
Call MeasADC N, 3000
Next
Call pause 1000
Call MeasT 0, 3000
Call pause 1000
Call MeasT 1, 3000
Call pause 1000
Call MeasEvents 0, 3000 ' address all DS2423 dual counters on Dallas Run 0. There is probably only one!
Call pause 1000
'Call MeasEvents 1 ' address all DS2423 dual counters on Dallas Run 1 if applicable.
'Call pause 1000
Call MeasCount 5, 6000 ' measure count over a 5 sec period
Call pause 1000
Call ReadTTLInputs 500
Call FlashTTLOuts
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]
[closecomm]
print "Error code: ";ComErrorNumber
close #commhandle
goto [top]
Sub FlashTTLOuts
For N = 1 to 5 ' flash TTL out 0 five times
print #commhandle, "N0"
call pause 500
print #commhandle, "F0"
call pause 500
Next
For N = 1 to 10 ' flash TTL out 1 ten times
print #commhandle, "N1"
call pause 500
print #commhandle, "F1"
call pause 500
Next
End Sub
Sub ReadTTLInputs TimeOutVal
For TTLIn = 0 to 1
call FlushBuffer
OutStr$ = "I" + Str$(TTLIn)
print #commhandle, OutStr$
x = 0
while x = 0 ' loop until either a string is received or timeout
DataLine$ = GetLine$(NumChars, TimeOutVal) ' NumChars is passed by reference
if NumChars = -30000 Then
print #window.te, "timeout"
exit while
end if
If NumChars = 0 Then ' probably a new line
End If
If NumChars >=1 Then
State = Val(DataLine$)
print #window.te, "I"; TTLIn; " "; State
exit while
end if
wend
next
end sub
Sub MeasCount NumSecs, TimeOutVal
call FlushBuffer
OutStr$ = "C" + Str$(NumSecs)
print #commhandle, OutStr$
x = 0
while x = 0 ' loop until either a string is received or timeout
DataLine$ = GetLine$(NumChars, TimeOutVal) ' NumChars is passed by reference
if NumChars = -30000 Then
print #window.te, "timeout"
exit while
end if
If NumChars = 0 Then ' probably a new line
End If
If NumChars >=1 Then
Counts = Val(DataLine$)
print #window.te, "C"; NumSecs; " "; Counts
exit while
end if
wend
end sub
Sub MeasEvents DallasRun, TimeOutVal
call FlushBuffer
OutStr$ = "E" + Str$(TRun)
print #commhandle, OutStr$
x = 0
while x = 0 ' loop until either a string is received or timeout
DataLine$ = GetLine$(NumChars, TimeOutVal) ' NumChars is passed by reference
if NumChars = -30000 Then
print #window.te, "timeout"
exit while
end if
If NumChars = 0 Then ' probably a new line
End If
If NumChars = 1 Then
exit while
End If
If NumChars >1 Then
Delimiter$ = " "
DevNum = Val(ExtractField$(DataLine$, Delimiter$, 1))
EventCount$ = ExtractField$(DataLine$, Delimiter$, 2)
EventCount0 = hexdec(EventCount$)
EventCount$ = ExtractField$(DataLine$, Delimiter$, 3)
EventCount1 = hexdec(EventCount$)
print #window.te, "E"; DallasRun; DevNum; " "; EventCount0; " "; EventCount1
end if
wend
end sub
Sub MeasT TRun, TimeOutVal
call FlushBuffer
OutStr$ = "T" + Str$(TRun)
print #commhandle, OutStr$
x = 0
while x = 0 ' loop until either a string is received or timeout
DataLine$ = GetLine$(NumChars, TimeOutVal) ' NumChars is passed by reference
if NumChars = -30000 Then
print #window.te, "timeout"
exit while
end if
If NumChars = 0 Then ' probably a new line
End If
If NumChars = 1 Then
exit while
End If
If NumChars >1 Then
Delimiter$ = " "
DevNum = Val(ExtractField$(DataLine$, Delimiter$, 1))
Tc = Val(ExtractField$(DataLine$, Delimiter$, 2))
print #window.te, "T"; TRun; DevNum; " "; Tc
end if
wend
end sub
Sub MeasADC Channel, TimeOutVal
call FlushBuffer
OutStr$ = "A" + Str$(Channel)
print #commhandle, OutStr$
x = 0
while x = 0 ' loop until either a string is received or timeout
DataLine$ = GetLine$(NumChars, TimeOutVal) ' NumChars is passed by reference
if NumChars = -30000 Then
print #window.te, "timeout"
exit while
end if
If NumChars = 0 Then ' probably a new line
End If
If NumChars >= 1 Then
ADVal = val(DataLine$)
print #window.te, "A"; Channel; " "; ADVal
exit while
end if
wend
end sub
Sub MeasurePressure TimeOutVal
call FlushBuffer
print #commhandle, "P" ' measure atmospheric pressure
x = 0
while x = 0 ' loop until either a string is received or timeout
DataLine$ = GetLine$(NumChars, TimeOutVal) ' NumChars is passed by reference
if NumChars = -30000 Then
print #window.te, "timeout"
exit while
end if
If NumChars = 0 Then ' probably a new line
End If
if NumChars = 1 Then ' probably a prompt
' print #window.te, DataLine$ ' used for debugging
exit while
end if
If NumChars > 1 Then
Pressure = val(DataLine$)
print #window.te, "P "; Pressure
exit while
end if
wend
end sub
Sub MeasRH RHUnit, TimeOutVal
Call FlushBuffer
If RHUnit = 0 Then
print #commhandle, "H0" ' measure atmospheric pressure
Else
print #commhandle, "H1"
End If
x = 0
while x = 0 ' loop until either a string is received or timeout
DataLine$ = GetLine$(NumChars, TimeOutVal) ' NumChars is passed by reference
if NumChars = -30000 Then
print #window.te, "timeout"
exit while
end if
If NumChars = 0 Then ' probably a new line
End If
if NumChars = 1 Then ' probably a prompt
' print #window.te, DataLine$ ' used for debugging
exit while
end if
If NumChars > 1 Then
delimiter$ = " "
Tc$ = ExtractField$(DataLine$, delimiter$, 1)
RH$ = ExtractField$(DataLine$, delimiter$, 2)
Tc = Val(Tc$)
RH = Val(RH$)
If (RH > 0) Then
DewPoint = CalcDewPoint(Tc, RH)
print #window.te, "H"; RHUnit; " "; Tc; " "; RH; " "; DewPoint
Else ' probably an error when performing RH measurement
print #window.te, "H"; RHUnit; " "; Tc; " "; RH
End if
exit while
end if
wend
end sub
sub FlushBuffer
x = 0
while x=0
if lof(#commhandle) <> 0 then
c$ = input$(#commhandle, 1)
else
exit while
end if
wend
end sub
function GetLine$(ByRef StatusFlag, TimeOutVal)
TimeOutTime = time$("milliseconds")
TimeOutDate = date$("days")
TimeOutTime = TimeOutTime + TimeOutVal ' 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 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