'********************************************************************
'* Relay controller
'* Language:    BASCOM-AVR 1.11.8.3
'* Date:        2007.Mar.22
'* Version:     V1.00
'********************************************************************

$regfile = "2313def.dat"
$crystal = 8000000
 
$baud = 9600
 
Declare Sub Avr_os()
Declare Sub Initialize()
Declare Sub Printprompt()
Declare Sub Docommand()
Declare Sub Getinput(byval Pbbyte As Byte)
Declare Sub Status()
Declare Sub Help()
Declare Sub Poweron(byval Relay As Byte)
Declare Sub Poweroff(byval Relay As Byte)
Declare Sub Powertoggle(byval Relay As Byte)
 
' If you change this number you must setup the PORT mappings
' in the initalize section.
Const Relays = 4
 
Const Cpcinput_len = 20                                     ' max. length of user-Input

Dim Rport(relays) As Byte
Dim Gbinp As Byte                                           ' holds user input
Dim Gspcinput As String * Cpcinput_len                      ' holds user-input
Dim Gspcinp(cpcinput_len) As Byte At Gspcinput Overlay
Dim Gbpcinputpointer As Byte                                ' string-pointer during user-input
Dim I As Byte
Dim J As Byte
 
Config Portb = Output
 
Open "Com1:" As Binary As #1
Enable Interrupts
 
Initialize
Avr_os
End
 
 
Sub Initialize
  ' Setup Port to relay mapping
  Rport(1) = 2 : Rport(2) = 3 : Rport(3) = 4 : Rport(4) = 7
  ' Set all Relays OFF
  For I = 1 To Relays
    Set Portb.rport(i)
  Next I
End Sub
 
 
Sub Avr_os
  Print #1 , ""
  Print #1 , "RELAY: Ready for commands"
  Printprompt
  Do
    Gbinp = Inkey(#1)                                       ' get user input
    If Gbinp <> 0 Then                                      ' something typed in?
      Getinput Gbinp                                        ' give input to interpreter
    End If
  Loop                                                      ' do forever
End Sub
 
Sub Printprompt
  Gbpcinputpointer = 1
  Gspcinput = ""
  Print #1 , ">";
End Sub
 
 
Sub Getinput(pbbyte As Byte)
   ' stores bytes from user and wait for CR (&H13)
   Select Case Pbbyte
      Case &H0A                                             ' do nothing
      Case &H0D                                             ' Line-end?
         Print #1 , Chr(&H0d) ; Chr(&H0a) ;
         Docommand                                          ' analyse command and execute
         Printprompt
      Case &H08                                             ' backspace ?
         If Gbpcinputpointer > 1 Then
            Print #1 , Chr(&H08);
            Decr Gbpcinputpointer
         End If
      Case Else                                             ' store user-input
         If Gbpcinputpointer <= Cpcinput_len Then
            Mid(gspcinput , Gbpcinputpointer , 1) = Pbbyte
            Incr Gbpcinputpointer
            Mid(gspcinput , Gbpcinputpointer , 1) = &H00    ' string-terminator
            Print #1 , Chr(pbbyte);                         ' echo back to user
         End If
   End Select
End Sub
 
Sub Docommand
      Gspcinput = Ucase(gspcinput)
 
      Select Case Gspcinput
         Case "?" : Help
         Case "HELP" : Help
         Case "S" : Status
         Case "STATUS" : Status
         Case "ON ALL"
            For I = 1 To Relays
               Poweron I
            Next I
 
         Case "OFF ALL"
            For I = 1 To Relays
               Poweroff I
            Next I
 
         Case "TOGGLE ALL"
            For I = 1 To Relays
               Powertoggle I
            Next I
 
         Case Else
             ' Terminate string after the SPACE
             For I = 1 To Gbpcinputpointer
               If Gspcinp(i) = 32 Then
                Gspcinp(i) = 0
                Exit For
               End If
             Next I
 
            ' What is the port?
            ' Next character after the space (convert from ASC to integer)
             J = Gspcinp(i + 1) - 48
 
             ' Number out of range replace String terminator with SPACE again
             ' This will cause a failure on the CASE statement below.
             If J > Relays Then
                 Gspcinp(i) = 32
             End If
 
             Select Case Gspcinput
                Case "ON" : Poweron J
                Case "O" : Poweron J
                Case "OFF" : Poweroff J
                Case "F" : Poweroff J
                Case "TOGGLE" : Powertoggle J
                Case "T" : Powertoggle J
                Case Else
                  ' Put the SPACE back
                  Gspcinp(i) = 32
                  Print #1 , "Command '" ; Gspcinput ; "' not recognized"
             End Select
      End Select
 
End Sub
 
'*****************************************************************************

Sub Poweron(relay As Byte)
  Reset Portb.rport(relay)
End Sub
 
Sub Poweroff(relay As Byte)
  Set Portb.rport(relay)
End Sub
 
Sub Powertoggle(relay As Byte)
  Toggle Portb.rport(relay)
End Sub
 
Sub Status
  For I = 1 To Relays
    Print #1 , "     Relay " ; I ; ") is ";
    If Portb.rport(i) = 1 Then
       Print "Off"
    Else
       Print "On"
    End If
  Next I
End Sub
 
 
Sub Help
  Print #1 , "Available Commands:"
  Print #1 , "<relay> = 1-" , Relays , " or ALL"
  Print #1 , "  HELP or ?"
  Print #1 , "  [S]TATUS"
  Print #1 , "  [T]OGGLE <relay>"
  Print #1 , "  [O]N <relay>"
  Print #1 , "  O[F]F <relay>"
End Sub