' RH160_1.Bas, Liberty Basic
'
' Illustrates an interface with a PC running Windows and the RH #160 Module.
'
' Each minute, sends a character to the RH #160 unit initiating a measurement.
' The line is read and the values of Tc and RH are extracted.  The dewpoint is
' calculated.  The date, time, Tc, RH and the dewpoint are written to the text box
' and also to a text file.
'
' When any character is input in the text box, logging ceases and the content of
' the file is displayed to the user.
'
' Uses Com2, 9600 baud.
'
' 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 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

    print #commhandle, "!"  ' send any character

    x = 0
    while x = 0       ' loop until either a string is received or timeout

       DataLine$ = GetLine$(NumChars) ' NuChars is passed by reference

       select case

          case NumChars = -30000
              print #window.te, "timeout"
              exit while

          case (NumChars = 1)
              print #window.te, DataLine$
              exit while

          case (NumChars > 2)        ' probably a vaild string
              d$ = date$("mm/dd/yy")
              t$ = time$()

              Delimiter$ = " "

              TCelcius$ = ExtractField$(DataLine$, Delimiter$, 1)
              RH$ = ExtractField$(DataLine$, Delimiter$, 2)

              TCelcius = Val(TCelcius$)
              RH = Val(RH$)
              DewPoint = CalcDewPoint(TCelcius, RH)

              OutStr$ = d$; " "; t$; " "; TCelcius; " "; RH; " "; DewPoint
              print #window.te, OutStr$

              open "d:\data.txt" for append as #log
          print #log, OutStr$       '  write it to the file
              close #log

          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 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 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 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