This is the simplest aspect of the design and you will find this is mostly a copy paste effort. All you need to understand how to do the first one. Everything else will simply follow. Remember what we need to do is fill a five byte packet and then send it through the serial port. I will now teach you how to do this using Visual Studio’s Visual Basic of the 2010 release.
When it comes to building your VB Net application, you will need a few blocks:
- A serial COM Port object
- A series of Text Box objects to hold the bytes to be sent
- A Button Command object to execute the action of stuffing the five bytes and sending them over the serial port.
Here is how it looks on my typical startup application place holder:
I have called my COM Port object Comillo (don’t ask me why…) and what it is, is an instance of the class System.IO.Ports.SerialPort. It will have all the properties relevant to a serial COM port such as number of data bits, start bits, stop bits, parity bits, etc, as well as the event handling necessary to the transmission of data.
When it comes to serial ports, there are a few things you need to do. First, you need to find the available COM ports. We do this, with this piece of code which runs during form loading (application startup):
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim stringarray() As String = IO.Ports.SerialPort.GetPortNames
Dim ComPortLocation As Integer
For i = 0 To UBound(stringarray)
If stringarray(i) = “COM4” Then
ComPortLocation = i
cmbCOMPorts.SelectedIndex = ComPortLocation
InitComplete = True
CommError = False
Notice we have created an array of strings called stringarray which is meant to hold all the available COM ports on the computer. Each computer is unique, so we can not just assume a given COM Port resource will be available. The IO.Ports.SerialPort.GetPortNames method grabs the available COM Port resources and dumps the result on the array. We can then take this array and extract each element into a Combo Box object I have called cmbCOMPorts.
The idea behind this move is to make all available COM Ports so the user can select the one they want use for communications. Notice I have added some code to select the COM4 as default. This is just a personal decision as I always program all my modules to be COM4. Hence, I do not need to select from within the Combo Box object whenever the application is started.
Once you have selected the COM Port you will use, we must open the resource. Do note that before doing this you may want to configure all parameters such as start bits, stop bits, data bit width, parity and such. Since I always use the same parameters, I have hard coded them into the application. Its up to you whether you want to add this flexibility or not. We are ready to open up that COM Port, and for that I created a simple MENU item called CONNECT. Kind of a DUH!…
Private Sub ConnectToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuConnect.Click
If mnuConnect.Text = “Connect” Then
On Error Resume Next
.DataBits = 8
.Parity = IO.Ports.Parity.None
.StopBits = IO.Ports.StopBits.One
.BaudRate = 9600
.PortName = cmbCOMPorts.SelectedItem
If Err.Number <> 0 Then
MsgBox(“Please Select COM Port from Drop Down List” & vbCrLf & Err.Description)
‘Dim megatest() As String = Comillo.GetType
If Err.Number <> 0 Then
MsgBox(“Com” & Comillo.PortName & ” is not available.” & vbCrLf & Err.Description)
mnuConnect.Text = “Disconnect”
mnuConnect.Text = “Connect”
Do not let this code scare you away. It is really not that complex. As you can see, what I am doing is configuring the Serial Port parameters as I explained before. I extract the actual COM Port name from the Combo Box and then we open the COM Port. There are some error checks to make sure we don’t send too much junk to the Open() method and if everything works OK (e.g. there is such a thing as the COM Port that you have specified), the resource is opened and made available for usage. Notice that when the COM Port is opened successfully, I change the caption of the menu item from “Connect” to “Disconnect”. This way I can use the same menu item for both opening and closing the serial port.
Dudes, we are SET!!! Now all we have to do is put stuff into the serial stream and watch those bits go.
Like I explained before, we have generated a series of place holders for the data to be sent. These are the txtBytex.Text text box objects. Now you may be wondering why actually create an object to hold this data and not just an internal array? When I show you what I do you may even feel compelled to call me Mega Dumb considering the Text Box contents are in fact transferred into an internal array before they are sent through the serial port. Ehh, WHAT???
Believe me, you will feel grateful the very first time you want to troubleshoot the application and see what on Earth you are sending through the serial port. Because it is super easy to assume you are sending the right thing but somehow you forgot to change from decimal to hex, and now nothing works. Thank god for those text boxes!
So here is an example of what I do. Notice the Start Motor button at the top left. Here is its code:
Private Sub cmnStartMotorCommand(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmnStartMotor.Click
txtByte0.Text = Int2Hex(START_MOTOR)
txtByte1.Text = Int2Hex(CInt((txtPWMDutyCycle.Text And &HFF00) / 256))
txtByte2.Text = Int2Hex(CInt(txtPWMDutyCycle.Text And &HFF))
txtByte3.Text = 0
txtByte4.Text = 0
If CommError Then
CommError = False
MsgBox(“Text Boxes Can Not Be Empty”, vbOKOnly, “Data Error”)
When I press the Start Motor button, all I do is stuff the Text Box objects with the data that I want to send but in hexadecimal format. Notice the first byte will be the opcode, and the subsequent bytes are the parameters. Assuming the duty cycle is a 16 bit number, I must segregate it into two 8 bit numbers as shown above. The last two bytes will not be used, so I just put zeroes. Remember, they must still be sent!
Once the Text Box objects have been filled with the values I want to submit, now I call the Send Command Button function, for which we can see the code below:
Private Sub btnSendCommand_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSendCommand.Click
Dim i As Integer
newMsg(0) = Convert.ToByte(Convert.ToInt32(txtByte0.Text.ToString, 16))
newMsg(1) = Convert.ToByte(Convert.ToInt32(txtByte1.Text.ToString, 16))
newMsg(2) = Convert.ToByte(Convert.ToInt32(txtByte2.Text.ToString, 16))
newMsg(3) = Convert.ToByte(Convert.ToInt32(txtByte3.Text.ToString, 16))
newMsg(4) = Convert.ToByte(Convert.ToInt32(txtByte4.Text.ToString, 16))
On Error GoTo ButtonSendErrorHandler
Comillo.Write(newMsg, 0, 5)
On Error GoTo ReceiveErrorHandler
Comillo.Read(buffer, 0, 3)
Dim Response As Integer
Response = MsgBox(“No COM Port Open.”, vbOKOnly, “Connect Error”)
CommError = True
This is the function we will call every time we want to submit data through the serial port. The newMsg() array is filled with the bytes and then the entire array is offered into the Comillo’s Write() method. The five bytes are sent and 3 bytes should be received. If so, these bytes are placed inside Comillo’s read buffer and are extracted by means of its Read() method.
Do note that one of Comillo’s object parameter is the ReadTimeOut which I have configured to be 100 ms. If you make this infinite, the code may hang at this point as it will be forever waiting for bytes to be sent back.
On this application I do nothing with the bytes received from the serial communications but you can use them if you need them to.
And that’s it! You can now generate more commands using different Objects like Sliders, Check Boxes, etc. If there is interest, I can document what is the coding style for these objects. But we must now take a little bit of a look to the hardware, which I bet some people may be interested in studying.