PC (Windows) Control of teh WX175 Wx Package Using Liberty Basic

copyright, Peter H. Anderson, Baltimore, MD, Mar, '05

(Mar 5, '05).

Introduction.

This discussion presents sample code using Liberty Basic 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 Sensirion 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