Imports System.IO.Ports Imports Microsoft.VisualBasic.Logging Public Class Form1 Private formIsLoaded As Boolean = False Private formStartingWidth As Integer Private textBoxesStartingWidth As Integer Private connectButtonsStartingLeft As Integer Private powerGroupStartingLeft As Integer Private ControlCodeMap As New Dictionary(Of Integer, String) From { {0, "NUL"}, {1, "SOH"}, {2, "STX"}, {3, "ETX"}, {4, "EOT"}, {5, "ENQ"}, {6, "ACK"}, {7, "BEL"}, {8, "BS"}, {9, "TAB"}, {10, "LF"}, {11, "VT"}, {12, "FF"}, {13, "CR"}, {14, "SO"}, {15, "SI"}, {16, "DLE"}, {17, "DC1"}, {18, "DC2"}, {19, "DC3"}, {20, "DC4"}, {21, "NAK"}, {22, "SYN"}, {23, "ETB"}, {24, "CAN"}, {25, "EM"}, {26, "SUB"}, {27, "ESC"}, {28, "FS"}, {29, "GS"}, {30, "RS"}, {31, "US"}, {127, "DEL"} } Private WithEvents SerialPort1 As New SerialPort() Private Sub Form1_SizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged If (formIsLoaded) Then If (Me.Width < formStartingWidth) Then Me.Width = formStartingWidth End If Dim formCurrentWidth As Integer = Me.Width Dim xDelta As Integer = formCurrentWidth - formStartingWidth txtPartialInput.Width = textBoxesStartingWidth + xDelta ListBoxReceived.Width = textBoxesStartingWidth + xDelta ButtonConnect.Left = connectButtonsStartingLeft + xDelta ButtonDisconnect.Left = connectButtonsStartingLeft + xDelta GroupBoxPower.Left = powerGroupStartingLeft + xDelta End If End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Startup formStartingWidth = Width Dim fixedHeight As Integer = Height ' Allow width to change, but lock height MinimumSize = New Size(formStartingWidth, fixedHeight) ' Minimum width 200 MaximumSize = New Size(1200, fixedHeight) ' Unlimited width, fixed height textBoxesStartingWidth = txtPartialInput.Width connectButtonsStartingLeft = ButtonConnect.Left powerGroupStartingLeft = GroupBoxPower.Left FormBorderStyle = FormBorderStyle.Sizable WindowState = FormWindowState.Normal ' Timer to check CTS status TimerCTS.Interval = 500 TimerCTS.Start() ' Populate COM ports ComboBoxPorts.Items.AddRange(SerialPort.GetPortNames()) ' Populate baud rates ComboBoxBaud.Items.AddRange(New Object() {9600, 19200, 38400, 57600, 115200}) ComboBoxBaud.SelectedIndex = 0 ' Populate handshake options ComboBoxHandshake.Items.AddRange([Enum].GetNames(GetType(Handshake))) ComboBoxHandshake.SelectedItem = "RequestToSend" ' RTS/CTS default formIsLoaded = True End Sub ' Poll CTS state Private Sub TimerCTS_Tick(sender As Object, e As EventArgs) Handles TimerCTS.Tick If SerialPort1.IsOpen Then CheckBoxCTS.CheckState = IIf(SerialPort1.CtsHolding = True, CheckState.Checked, CheckState.Unchecked) Else CheckBoxCTS.CheckState = CheckState.Indeterminate End If End Sub Private Sub ButtonConnect_Click(sender As Object, e As EventArgs) Handles ButtonConnect.Click Try If Not SerialPort1.IsOpen And ComboBoxPorts.SelectedItem <> Nothing Then SerialPort1.PortName = ComboBoxPorts.SelectedItem.ToString() SerialPort1.BaudRate = CInt(ComboBoxBaud.SelectedItem) SerialPort1.Handshake = CType([Enum].Parse(GetType(Handshake), ComboBoxHandshake.SelectedItem.ToString()), Handshake) SerialPort1.Parity = Parity.None SerialPort1.DataBits = 8 SerialPort1.StopBits = StopBits.One SerialPort1.Open() LabelStatus.Text = "Connected" CheckBoxRTS.Enabled = IIf(ComboBoxHandshake.SelectedItem = "None", True, False) ButtonConnect.Enabled = False ButtonDisconnect.Enabled = True End If Catch ex As Exception MessageBox.Show("Error opening port: " & ex.Message) End Try End Sub Private Sub ButtonDisconnect_Click(sender As Object, e As EventArgs) Handles ButtonDisconnect.Click If SerialPort1.IsOpen Then SerialPort1.Close() LabelStatus.Text = "Disconnected" ButtonDisconnect.Enabled = False ButtonConnect.Enabled = True End If End Sub ' Send buttons Private Sub ButtonSend1_Click(sender As Object, e As EventArgs) Handles btnSendReady.Click If SerialPort1.IsOpen Then Dim msg As String = Chr(17) & "000" & Chr(3) SerialPort1.WriteLine(msg) ListBoxReceived.Items.Add("> " & ExpandControlCodes(msg)) ListBoxReceived.SelectedIndex = ListBoxReceived.Items.Count - 1 End If End Sub ' Handle incoming data Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) _ Handles SerialPort1.DataReceived Static Dim receivedMessage As String = "" Try receivedMessage &= SerialPort1.ReadExisting() Dim pos As Integer = InStr(receivedMessage, Chr(3), CompareMethod.Binary) ' ETX If (pos > 0) Then While (pos > 0) Dim oneMessage As String = "" Debug.Print("ETX at pos: " & pos.ToString() & " in '" & receivedMessage & "'") oneMessage = Mid(receivedMessage, 1, pos) Dim parsed As String = ExpandControlCodes(oneMessage) ' ' Analyze and deal with the message ' ProcessAVRMessage(oneMessage) Me.Invoke(Sub() ListBoxReceived.Items.Add("< " & parsed)) Me.Invoke(Sub() ListBoxReceived.SelectedIndex = ListBoxReceived.Items.Count - 1) receivedMessage = Mid(receivedMessage, pos + 1) Me.Invoke(Sub() txtPartialInput.Text = receivedMessage) pos = InStr(receivedMessage, Chr(3), CompareMethod.Binary) End While Else 'Debug.Print("No ETX in '" & receivedMessage & "'") Me.Invoke(Sub() txtPartialInput.Text = receivedMessage) End If Catch ex As Exception ' Handle errors Debug.Print("Exception caught and ignored?") End Try End Sub Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing If SerialPort1.IsOpen Then SerialPort1.Close() End Sub Private Function ExpandControlCodes(input As String) As String Dim sb As New Text.StringBuilder() For Each ch As Char In input Dim code As Integer = Asc(ch) If ControlCodeMap.ContainsKey(code) Then sb.Append("[" & ControlCodeMap(code) & "]") Else sb.Append(ch) End If Next Return sb.ToString() End Function Private Sub CheckBoxRTS_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBoxRTS.CheckedChanged SerialPort1.RtsEnable = CheckBoxRTS.Checked End Sub Private Sub ButtonMasterVolUp_Click(sender As Object, e As EventArgs) Handles ButtonMasterVolUp.Click SendMessageToAVR(Chr(2) & "07A1A" & Chr(3)) End Sub Private Sub ButtonMasterVolDown_Click(sender As Object, e As EventArgs) Handles ButtonMasterVolDown.Click SendMessageToAVR(Chr(2) & "07A1B" & Chr(3)) End Sub Private Sub CheckBoxMasterMute_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBoxMasterMute.CheckedChanged SendMessageToAVR(IIf(CheckBoxMasterMute.Checked, Chr(2) & "07EA2" & Chr(3), "07EA3")) End Sub Private Sub ButtonZone2VolUp_Click(sender As Object, e As EventArgs) Handles ButtonZone2VolUp.Click SendMessageToAVR(Chr(2) & "07ADA" & Chr(3)) End Sub Private Sub ButtonZone2VolDown_Click(sender As Object, e As EventArgs) Handles ButtonZone2VolDown.Click SendMessageToAVR(Chr(2) & "07ADB" & Chr(3)) End Sub Private Sub CheckBoxZone2Mute_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBoxZone2Mute.CheckedChanged SendMessageToAVR(IIf(CheckBoxZone2Mute.Checked, Chr(2) & "07EA0" & Chr(3), "07EA1")) End Sub Private Sub SendMessageToAVR(msg As String) If Not ButtonConnect.Enabled Then SerialPort1.WriteLine(msg) ListBoxReceived.Items.Add("> " & ExpandControlCodes(msg)) ListBoxReceived.SelectedIndex = ListBoxReceived.Items.Count - 1 End If End Sub ' ' Power - main and zone ' Private Sub btnPowerOn_Click(sender As Object, e As EventArgs) Handles btnPowerOn.Click SendMessageToAVR(Chr(2) & "07A1D" & Chr(3)) End Sub Private Sub btnPowerOff_Click(sender As Object, e As EventArgs) Handles btnPowerOff.Click SendMessageToAVR(Chr(2) & "07A1E" & Chr(3)) End Sub Private Sub btnPowerZone1On_Click(sender As Object, e As EventArgs) Handles btnPowerZone1On.Click SendMessageToAVR(Chr(2) & "07E7E" & Chr(3)) End Sub Private Sub btnPowerZone1Off_Click(sender As Object, e As EventArgs) Handles btnPowerZone1Off.Click SendMessageToAVR(Chr(2) & "07E7F" & Chr(3)) End Sub Private Sub btnPowerZone2On_Click(sender As Object, e As EventArgs) Handles btnPowerZone2On.Click SendMessageToAVR(Chr(2) & "07EBa" & Chr(3)) End Sub Private Sub btnPowerZone2Off_Click(sender As Object, e As EventArgs) Handles btnPowerZone2Off.Click SendMessageToAVR(Chr(2) & "07EBA" & Chr(3)) End Sub ' ' Other stuff ' Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize Debug.Print("Resize") End Sub Private Sub ComboBoxPorts_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBoxPorts.SelectedIndexChanged If ComboBoxPorts.Text <> "" Then ButtonConnect.Enabled = True Else ButtonConnect.Enabled = False End If End Sub Private Sub ProcessAVRMessage(msg As String) ' Process incoming messages from AVR here Debug.Print("Processing AVR message: " & ExpandControlCodes(msg)) Dim response As String = Mid(msg, 2, Len(msg) - 2) Debug.Print(" : " & response) If (Mid(response, 1, 4) = "0026") Then ' Volume in the next byte Dim vol As Single = Convert.ToInt16(Mid(response, 5, 2), 16) ' C7 is 0db If (vol > &HC7) Then Debug.Print((vol - &HC7) / 2) Else Debug.Print((vol - &HC7) / 2.5) End If End If End Sub End Class