' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' This code is supplied as-is with no warranties expressed or implied. ' Dr. Dan Wedding is not responsible for any harm direct or indirect as a result ' of the use of this (or any other) code supplied by me in any way and from any ' source. You have the source code, what you do with it is your business. ' ' This program will call the operating system and get a list of the Com ports ' This list is put on a ComboBox. ' The user will select the desired port and press the connect button. ' Once open the program demonstrates how to write to the port and read from the port. ' The program also demonstrates how to eliminate the "Illegal Cross Thread Error" ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ////////////////////////////////////////////////////////////////////////////// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' UPDATED CODE: This code is slightly different than the code presented in ' my video VB22. ' ' Update 1: Filters out phones that are connected to the computer. Some phones ' will appear as a com port to the searchers and the port counter. ' Searcher2 has been updated to eliminate the phones from the list. ' ' Update 2: A refresh button has been added so you can plug in more devices and ' refresh the list on the combobox. ' ' Update 3: The connect button is set to not visible if no com ports are found. ' ' Update 4: Moved the if serialport1.IsOpen to the top of the connect button ' because you may need to "search" for the correct port on an HC05 ' ' Update 5: HC-05 modules are slow. So a While loop was added to the ' receive subroutine. ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 'This code is supplied as-is with no warranties expressed or implied. ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 'In order to search for the com ports attached to the computer - this command needs to be 'added above the Public Class Form1 line: Imports System.Management ' Next you have to go to Project, add reference, select System.Managment, and when the checkbox ' appears, check it. Public Class Form1 Dim SerialDataIn As Char Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Load_ComboBox() End Sub 'Button to refresh the combobox list Private Sub btnRefresh_Click(sender As Object, e As EventArgs) Handles btnRefresh.Click Load_ComboBox() End Sub 'Subroutine to populate the combobox. If there is something attached to the com port - call "GetAllSerialPortNames" Sub Load_ComboBox() Dim intPortCount As Integer Try ComboBox1.Items.Clear() 'UPDATED CODE: The line below will erase the visible text after the information is cleared from the combobox. 'This became necessary when a refresh button was added. ComboBox1.ResetText() intPortCount = System.IO.Ports.SerialPort.GetPortNames.Count If intPortCount = 0 Then btnConnect.Visible = False MessageBox.Show("There is nothing connected to the com port.", "No Ports Found", MessageBoxButtons.OK, MessageBoxIcon.Error) Else 'Get com port names and fill the combo box 'This is a subroutine – it is not a system command GetAllSerialPortNames() End If Catch ex As Exception MessageBox.Show("PORT ERROR: " & ex.Message, "Serial Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub 'Subroutine to ask the OS what is attached as a PnP device and add it to the combobox. Then as what is a real com port. 'If there is any duplicaion between the first list and the second list, do not add the duplicate entry. Sub GetAllSerialPortNames() Try ' 1) Find all USB "Plug and pray" DEVICES ACTING LIKE COM PORTS Dim searcher As New ManagementObjectSearcher("root\cimv2", "SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%'") For Each queryObj As ManagementObject In searcher.Get() ComboBox1.Items.Add(queryObj("name").ToString) Next ' 2) Find all REAL COM ports (Real com port plugs on a mobo) ' UPDATED CODE: The old search is shown below. It will also find phones without an accessible com port. ' The new search should NOT find phones. '(Old search) Dim searcher2 As New ManagementObjectSearcher("root\cimv2", "SELECT * FROM Win32_SerialPort") ' Dim searcher2 As New ManagementObjectSearcher("root\cimv2", "SELECT * FROM Win32_SerialPort WHERE Name LIKE '%(COM%'") For Each queryObj As ManagementObject In searcher2.Get() ' Do not add duplicates (just in case it sees the com both ways If Not ComboBox1.Items.Contains(queryObj("name").ToString) Then ComboBox1.Items.Add(queryObj("name").ToString) End If Next ' 'UPDATED CODE: Will make the connect button invisible if no com ports are found. ' This is necessary in this routine because phones connected to the computer may cause an inaccurate count ' of the com ports connected to the computer. ' If ComboBox1.Items.Count >= 1 Then btnConnect.Visible = True 'The combobox works like an array, so set the index to 0 (the starting position) ComboBox1.SelectedIndex = 0 Else btnConnect.Visible = False MessageBox.Show("PORT ERROR: No accessible com ports found.", "Serial Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End If Catch err As ManagementException MessageBox.Show("Com Port Error: " & err.Message, "Com Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub 'When the com port is selected, and this button is clicked, the project will open the selected com port. Private Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click Dim com_port As String Dim start_text, text_length As Integer Try ' Get the current combobox text, it will look something like this: ' Silicon Labs CP210x USB to UART Bridge (COM8) ' ' 1) find the locaton of the '(' that is in front of the COM ' 2) find the length of the COM port name, it might be 4 (COMX), 5 (COMXX), or 6 (COMXXX) chars long ' a) Get total length because COM number is at the end ' b) Remove the closging ')' by subtracting 1 ' c) Subract the starting location of '(' to get how long the name is ' 3) Lastly, get the substring that starts 1 char after the ( and then how many letters you need to copy ' Allows the port to be changed when the program is already running. ' This command was just moved before SerialPort1.PortName = com_port ' The need to check more than one com port when using an HC-05 caused this to move here. ' If SerialPort1.IsOpen Then SerialPort1.Close() End If 'Get the com port from the combobox com_port = ComboBox1.Text start_text = com_port.IndexOf("(") + 1 text_length = com_port.Length - 1 - start_text com_port = com_port.Substring(start_text, text_length) SerialPort1.PortName = com_port 'These can be assigned in the properties window. But, in advanced code, these can be assigned with radio buttons. SerialPort1.BaudRate = 9600 SerialPort1.Parity = IO.Ports.Parity.None SerialPort1.DataBits = 8 SerialPort1.StopBits = 1 SerialPort1.Handshake = IO.Ports.Handshake.None 'If reading or writing takes more than 1/2 a second something is wrong. SerialPort1.WriteTimeout = 500 SerialPort1.ReadTimeout = 500 'Finally, open the port. SerialPort1.Open() 'MessageBox.Show(com_port & " successfully opened ", "Serial Port Open", MessageBoxButtons.OK, MessageBoxIcon.Information) Catch ex As Exception MessageBox.Show("Serial port failed to open: " & ex.Message, "Serial Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try TabControl1.SelectedIndex = 1 End Sub Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing SerialPort1.Close() End Sub 'To generate this subroutine - on the form design, select the serial port. Go to the properties window And press the events button (lightning bolt). 'Then double click on DataReceived. Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived ' If you want to read in an 8-bit intger instead of a character, then you need to: ' Declare your variable as a byte: Dim SerialDataIn as Byte ' Use this read command in the SerialPort1_DataReceived subroutine: SerialDataIn = serialport1.readbyte ( ) ' ' If you are reading in an 8-bit intger - but you want to convert it to a string: ' Declare your variable as a String: Dim SerialDataIn as String ' Use this read command in the SerialPort1_DataReceived subroutine: SerialDataIn = serialport1.readbyte ( ).ToString ' ' If you are reading in an character - but you want to convert it to a string: ' Declare your variable as a String: Dim SerialDataIn as String ' Use this read command in the SerialPort1_DataReceived subroutine: SerialDataIn = SerialDataIn & ChrW(SerialPort1.ReadChar()) Try ' Update: this is because HC05 modules are slow and get out of sync. Do While (SerialPort1.BytesToRead > 0) SerialDataIn = ChrW(SerialPort1.ReadChar()) 'Debug to verify the port is receiving, this can be removed. 'MessageBox.Show("You received: " & SerialDataIn) 'The Invoke command eliminates the "Illegal Cross Thread Error" Invoke(Sub() TextBox1.AppendText(SerialDataIn & " ") Refresh() End Sub) Loop Catch ex As Exception MessageBox.Show("Serial receive error: " & ex.Message, "Serial Port Read Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub 'To send a character, put the desired character between the double quotes as shown below: ' SerialPort1.Write("W") ' 'To send a string, put the desired string between the double quotes as shown below: ' SerialPort1.Write("W is a pretty cool letter.") ' 'To send a byte (number), tell the program to send the number as a character as shown below: ' SerialPort1.Write(chr(65)) ' Private Sub btnGreen_Click(sender As Object, e As EventArgs) Handles btnGreen.Click SerialPort1.Write("A") End Sub Private Sub btnRed_Click(sender As Object, e As EventArgs) Handles btnRed.Click SerialPort1.Write("B") End Sub Private Sub btnBlue_Click(sender As Object, e As EventArgs) Handles btnBlue.Click SerialPort1.Write("C") End Sub Private Sub btnYellow_Click(sender As Object, e As EventArgs) Handles btnYellow.Click SerialPort1.Write("D") End Sub End Class