שתף באמצעות


How to read from serial port and display to textbox in vb 2008 and store data in DB?

Question

Saturday, June 22, 2013 12:38 AM

I am new to VB, I am developing a small application done with other parts but the one I present to you now I have failed to accomplish for almost two weeks, have tried different codes from net but none seems to be helpful; I am now having 48 hours to the deadline.

I have three different data coming from PIC16F877A (in simulation) and I have installed virtual com port; now I want to do the following

=The information from serial port is like this "pulse:160 temp: 31C Resp: 92p/min"

(1)To display three data to three different textboxes in vb (2008); from the serial port new information is loaded after every 15 sec so the change has to be reflected to my application 

(2)After the information is loaded to textboxes respectively, each has to be compared to reference value as follows 120<pulse>150, 36<temp>37.5, 20<respiration>30 if any reading is not in the range then a button which is used as LED has to turn color to red otherwise it has to be green. I have placed these buttons (three) adjacent to textboxes

(3)I have a table in my sql db, with information of temp, pulse, respiration, date and time: Now I want every time new information is loaded to be stored in db with date and time.

NB: PIC is transporting data through comport1, baudrate 9600, parity bit NONE, data bit 8 and I have COM 1 and 2 as com ports in device manager. (I know and am using visual basic as a language)

Thanks so much in advance, hopeful I will be helped soon.

Regards

All replies (33)

Saturday, June 22, 2013 1:07 AM

"I am new to VB, I am developing a small application done with other parts but the one I present to you now I have failed to accomplish for almost two weeks, have tried different codes from net but none seems to be helpful; I am now having 48 hours to the deadline."

Basically that would require someone to write your entire application for you or stay on these threads coaching you along for the next 48 hours until you figured out what you were doing possibly. Especially since you didn't post your code (which can copy and paste into a post using the Insert Code Block function to the right of the letters HTML in the top of an open post) and nobody knows your proficiency with serial interfaces, getting specific information from a textbox string to convert to a decimal or something to find if they are in the range of two other decimals or something and whatever else your doing and communicating with an SQL database.

You've taught me everything I know but not everything you know.


Saturday, June 22, 2013 1:16 AM

I have three different data coming from PIC16F877A (in simulation) and I have installed virtual com port; now I want to do the following

=The information from serial port is like this "pulse:160 temp: 31C Resp: 92p/min"

You need to post the code you are using and indicate the problem that you are having with it.

There is a simple example of serial port rceiving here, but that code assumes that the data stream is continuous (as with a GPS) with something like Cr/Lf used to separate the transmissions. It's not clear whether or not your device is configured like that.
http://vbdotnetblog.wordpress.com/serial-port/simple-data-receiving/

That would enable you to confirm data receiving is working, and to see the exact data that is being received.

Then you need code to split the data stream into complete sentences.  How you do that depends on the sentence separator used by your device, but the appearance of "pulse" could be used to indicate the end of one sentence and the start of the next.

If you can display the complete sentence in the text box, then you need to extract the separate readings.  The String Split command (using space as the separator) could do that, provided there is a typo in your example ("pulse:160 temp:31C Resp:92p/min" not "pulse:160 temp: 31C Resp: 92p/min"). Otherwise it is a bit trickier.

You can then examine each string and parse out the numeric value using ":" as the indicator.


Saturday, June 22, 2013 7:29 PM

Hello Acamar and  MonkeyBoy!

This is the code I tried recently. I expected to see three readings in txtTemp..but nothing is happening.

Please help

Imports System.IO.Ports

Public Class new_monitor

    Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
        txtTemp.Multiline = True
        txtTemp.Dock = DockStyle.Fill
        Try
            SerialPort1.Open()
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        End Try
    End Sub
    Delegate Sub AddText(ByVal Text As String)
    Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        txtTemp.Invoke(New AddText(AddressOf txtTemp.AppendText), SerialPort1.ReadLine + Environment.NewLine)
    End Sub
End Class

Saturday, June 22, 2013 10:09 PM

You need to get rid of the Try/Catch because it is masking your errors and making it difficult to debug the code. Also, the concatenator opertor for strings is & not +.  You are relying on the default settings for the serial port, and that's unlikely to be suitable for your device - set the databits and baudrate etc to exactly what your device requires.

Then start debugging from the beginning - if you insert a breakpoint at the code in the data received event, does the breakpoint get hit?


Saturday, June 22, 2013 10:29 PM

"Also, the concatenator opertor for strings is & not +."

Many forum responders have the same misconception.  The .NET concatenator is "+".  The legacy VB concatenater is "&".  It is generally preferable to use the more general .NET syntax when the legacy VB syntax offers no advantage.


Saturday, June 22, 2013 11:54 PM

The .NET concatenator is "+".  The legacy VB concatenater is "&".

I don't know where that comes from, but it's not the MSDN documentation:

"The + Operator (Visual Basic) has the primary purpose of adding two numbers. However, it can also concatenate numeric operands with string operands. The + operator has a complex set of rules that determine whether to add, concatenate, signal a compiler error, or throw a run-time InvalidCastException exception.

"The & Operator (Visual Basic) is defined only for String operands, and it always widens its operands to String, regardless of the setting of Option Strict. The & operator is recommended for string concatenation because it is defined exclusively for strings and reduces your chances of generating an unintended conversion."
http://msdn.microsoft.com/en-us/library/te2585xw(v=vs.110).aspx (emphasis added)


Sunday, June 23, 2013 1:18 AM

The .NET concatenator is "+".  The legacy VB concatenater is "&".

I don't know where that comes from, but it's not the MSDN documentation:

"The + Operator (Visual Basic) has the primary purpose of adding two numbers. However, it can also concatenate numeric operands with string operands. The + operator has a complex set of rules that determine whether to add, concatenate, signal a compiler error, or throw a run-time InvalidCastException exception.

"The & Operator (Visual Basic) is defined only for String operands, and it always widens its operands to String, regardless of the setting of Option Strict. The & operator is recommended for string concatenation because it is defined exclusively for strings and reduces your chances of generating an unintended conversion."
http://msdn.microsoft.com/en-us/library/te2585xw(v=vs.110).aspx (emphasis added)

Yes. A much better recommendation than changing "+" to "&" for string concatenation would be to ensure that "Option Strict On" is specified.


Sunday, June 23, 2013 6:50 AM

Hi again!

I have changed the operator to & and removed try/catch; on the electronic simulation part I set baudrate to 9600, databit to 8, stop bit 1 and parity none. Here my doubt: My simulation is giving out new readings after every 15 sec...is there anything that am suppose to do with read timeout and write timeout?

Now am getting this warning 'Microsoft.VisualBasic.ComClassAttribute' is specified for class 'new_monitor' but 'new_monitor' has no public members that can be exposed to COM; therefore, no COM interfaces are generated.


Sunday, June 23, 2013 7:19 AM

What was the result when you inserted the breakpoint in the data received event?  Did the breakpoint get hit?

You do not need to worry about a read timeout because you are not doing a synchronous read.  You are not writing to the port so there is no need to worry about a write timeout.

What is new_monitor?  As it has a button click event I assumed it was you form, that you had added SerialPort1 to that form, that the form was being loaded at startup and you were clicking the button to start the receiving.  The message you are now getting would be more typical of a class library than a Windows form.
http://msdn.microsoft.com/en-us/library/429t72z9(v=vs.90).aspx


Sunday, June 23, 2013 9:29 AM

Thanks Acamar

After I inserted the breakpoint at data received event, the yellow arrow point at "serialport1.open()" othe code and am getting this msg "InvalidOperationException was unhandled" "port is already open"


Sunday, June 23, 2013 10:59 AM

Inserting the breakpoint will not create that error - there must be something else happening to cause that error.  What are you doing differently when you run the program with the breakpoint inserted?

Note that you can only press the button once each time you run the program.  So you must insert the breakpoint before you start the program.


Sunday, June 23, 2013 11:13 AM

I inserted breakpoint before running the program and I only pressed the connect button once as I want new readings to show up after connect button is pressed. This is how the code looks like now.

Imports System.IO.Ports

Public Class new_monitor


    Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
        txtTemp.Multiline = True
        txtTemp.Dock = DockStyle.Fill
        ' Try
        SerialPort1.Open()
        ' Catch ex As Exception
        'MessageBox.Show(ex.ToString)
        'End Try

    End Sub
    Delegate Sub AddText(ByVal Text As String)
    Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        txtTemp.Invoke(New AddText(AddressOf  txtTemp.AppendText), SerialPort1.ReadLine & Environment.NewLine)
    End Sub
End Class

Sunday, June 23, 2013 11:26 AM

This is how the code looks like now.

... and was the breakpoint hit?


Sunday, June 23, 2013 11:52 AM

Sorry how do I know if the breakpoint was hit or not? I never knew before this debugging tool, so I don't know what it gives out


Sunday, June 23, 2013 11:56 AM

Can you give me a code to try. All I need is to read data from serial port to textboxes; the part of storing the data in db I can handle myself.


Sunday, June 23, 2013 12:25 PM

Sorry how do I know if the breakpoint was hit or not? I never knew before this debugging tool, so I don't know what it gives out

You can't write your code without a basic understanding of your debugging tools.  See here:
http://vbdotnetblog.wordpress.com/overview/debugging/

You will know when the breakpoint has been hit because the application will stop executing and the IDE will highlight the line at which it stopped.  Then you examine the variables.


Sunday, June 23, 2013 12:27 PM

Can you give me a code to try. All I need is to read data from serial port to textboxes; the part of storing the data in db I can handle myself.

There is code at the reference I provided above.
http://vbdotnetblog.wordpress.com/serial-port/

or some of the many other sources that Google will throw up.  Code isn't your problem - the problem is proving that your device really is transmitting the data that you think it's transmitting.


Sunday, June 23, 2013 12:38 PM

It has been highlighting on the line where "serialPort1.open()", and am getting msg access to port COM1 is denied. Does that indicate anything on why I cant read from port? What can I try to do?


Sunday, June 23, 2013 12:54 PM

It has been highlighting on the line where "serialPort1.open()", and am getting msg access to port COM1 is denied. Does that indicate anything on why I cant read from port? What can I try to do?

That means it is not reaching the breakpoint because it is encountering an error before it gets that far. 

If that error is occurring the first time that you press the button after starting the program then that indicates that the serial port 1 object could not open the COM port.  Either the port doesn't exist, it is faulty, or it is on use by another application.  You have not included the code that sets the serial port 1 properties, so it is hard to tell whether or not it has been configured properly.

I would recommend implementing the combobox selection and the port setup code from the example I referenced so that you are sure that you are using a valid COM port.

That problem is not associated with the breakpoint, but it might be an example of a problem that was always there but was being concealed by the Try/Catch, and therefore first appeared at teh same time as you made the other changes.


Sunday, June 23, 2013 1:53 PM

I am now starting to think that may be it is a problem of virtual ports though now I can see the available ports thr

Imports System.IO.Ports

Public Class new_monitor


    Private Sub new_monitor_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        For Each s In System.IO.Ports.SerialPort.GetPortNames()
            lstPorts.Items.Add(s)
        Next s
    End Sub
   
    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        If lstPorts.SelectedIndex = -1 Then
            MsgBox("Please select a port")
            Exit Sub
        Else
            SerialPort1.BaudRate = 9600
            SerialPort1.DataBits = 8
            SerialPort1.Parity = IO.Ports.Parity.None
            SerialPort1.StopBits = IO.Ports.StopBits.One
            SerialPort1.PortName = lstPorts.SelectedItem.ToString
            SerialPort1.Open()
        End If
    End Sub
    '1. Define (create) the delegate type we  want to use. It will be 
    '   a SUB with one argument (a string)
    Delegate Sub SetReceivedText(ByVal ReceivedData As String)
    '2. Declare a variable of the correct type
    Dim d As SetReceivedText
    Private Sub SetText(ByVal myData As String)
        If Me.txtReceived.InvokeRequired Then
            Me.Invoke(d, New Object() {myData})
        Else
            Me.txtReceived.Text &= myData
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load
        '3. Assign an object to the delegate variable
        d = New SetReceivedText(AddressOf SetText)

        '...
    End Sub
    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
        ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
        Handles SerialPort1.DataReceived
        SetText(SerialPort1.ReadExisting())
    End Sub


    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
        SerialPort1.Close()
    End Sub
End Class

ough the code you have referenced to me. I have pasted and edit serial port properties...I can see the available ports but when I click start button, am taken to code and shown the same problem with other codes "access is denied at com1".


Sunday, June 23, 2013 1:59 PM

Are you clicking the button with the .Open more than once without closing the port between clicks?

Is the PIC send a newline (LF)?  What causes the PIC to send the data?

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics


Sunday, June 23, 2013 2:05 PM

Am clicking the button once.

Yes the pic send LF.

sorry what do you mean when you say what cause the pic to send the data?


Sunday, June 23, 2013 2:11 PM

Does the PIC just send the data periodically or do you have to send it a command?

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics


Sunday, June 23, 2013 2:13 PM

I have configured a timer on it, so it automatically sends new data after every 15 secs


Sunday, June 23, 2013 2:24 PM

What port is the PIC attached to? 

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics


Sunday, June 23, 2013 2:47 PM

COM port 2


Sunday, June 23, 2013 2:51 PM

So for testing create a new project and add a RichTextBox to the form, nothing else.  Then add this code:

    Dim WithEvents timer1 As New System.Windows.Forms.Timer
    Dim WithEvents SerialPort1 As New IO.Ports.SerialPort

    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        '
        'port setup and open - modify to fit your needs
        '
        Dim p() As String = IO.Ports.SerialPort.GetPortNames 'contains ports visible to system
        With SerialPort1
            .PortName = "COM2" '<<<<<<<<<<<<<<<<<YOUR PORT<<<<<<<<<<<<<<<<<<<<<<<<
            .Encoding = System.Text.Encoding.GetEncoding(28591)
            .DtrEnable = True
            .RtsEnable = True
        End With
        nl = CByte(Asc(SerialPort1.NewLine))
        Try
            SerialPort1.Open()
            timer1.Interval = 100
            timer1.Start()
        Catch ex As Exception
            RichTextBox1.AppendText(ex.Message & Environment.NewLine)
        End Try
        stpw = Stopwatch.StartNew
    End Sub

    Dim nl As Byte
    Dim setup As Boolean = False
    Dim dataByts As New List(Of Byte)
    Dim dataLock As New Object
    Dim datarcvd As New Threading.AutoResetEvent(False)

    Private Sub SerialPort1_DataReceived(sender As Object, _
                                         e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Debug.WriteLine("DR")
        Dim br As Integer = SerialPort1.BytesToRead '# of bytes to read
        If br > 0 Then
            Dim b(br - 1) As Byte 'create buffer to read the data
            Try
                br = SerialPort1.Read(b, 0, b.Length) 'read the bytes, note non-blocking
                If br < b.Length Then 'adjust length if required
                    Array.Resize(b, br)
                End If
                'add bytes just read to list
                Threading.Monitor.Enter(dataLock)
                dataByts.AddRange(b)
                Threading.Monitor.Exit(dataLock)
                datarcvd.Set() 'signal SOME bytes read
                '
                'check for a condition
                '
                'If dataByts.Count >= 10 Then
                '    'condition met
                'End If
                '
                'fine tune exception handling
                '
            Catch ex As Exception
                RichTextBox1.AppendText(ex.Message & Environment.NewLine)
            End Try
        End If
    End Sub

    Private Sub SerialPort1_ErrorReceived(sender As Object, _
                                          e As IO.Ports.SerialErrorReceivedEventArgs) Handles SerialPort1.ErrorReceived

        Debug.WriteLine("ER")
    End Sub

    Private Sub SerialPort1_PinChanged(sender As Object, _
                                       e As IO.Ports.SerialPinChangedEventArgs) Handles SerialPort1.PinChanged

        Debug.WriteLine("PC")
    End Sub

    Private Sub timer1_Tick(sender As Object, e As EventArgs) Handles timer1.Tick
        If datarcvd.WaitOne(0) Then 'do we have bytes to process
            If dataByts.Count > 0 Then
                Dim s As String = ""
                Threading.Monitor.Enter(dataLock) 'yes
                Dim idxOfNL As Integer = dataByts.IndexOf(nl) 'does the list have a newline
                If idxOfNL >= 0 Then
                    idxOfNL += 1 'include the newline
                    'get the string, including the newline character
                    s = SerialPort1.Encoding.GetChars(dataByts.ToArray, 0, idxOfNL)
                    dataByts.RemoveRange(0, idxOfNL) 'remove the bytes processed
                End If
                Threading.Monitor.Exit(dataLock)
                If s.Length > 0 Then RichTextBox1.AppendText(s)
            End If
        End If
    End Sub

What appears in the RichTextBox?

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics


Sunday, June 23, 2013 4:05 PM

In Rich textbox I get this msg "Access to the port 'COM2' is denied."


Sunday, June 23, 2013 5:13 PM

So I see you have been having this error.  This means that something else has the port open most likely.  Only one application can access the port at a time.  Make certain the the PIC is attached to COM2 and nothing else is using the port.  If you are certain that the port is not in use by another app try rebooting and see if that helps.

Is the port built in or USB?

"Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." JohnWein

Multics


Sunday, June 23, 2013 5:15 PM

You really need to find your Com port first.

Start a new console application and replace the code in Module 1 with:

Option Strict On
Imports System.IO.Ports

Module Module1
  Sub Main()
    Dim SP As SerialPort = Nothing
    For Each PortName As String In SerialPort.GetPortNames
      Console.Write(PortName)
      Try
        SP = New SerialPort(PortName)
        SP.Open()
        If SP.IsOpen Then Console.WriteLine(", valid port.")
      Catch ex As Exception
        Console.WriteLine(ex.ToString)
      End Try
      SP.Dispose()
    Next
    Console.WriteLine("Press ""Enter"" to end program.")
    Console.ReadLine()
  End Sub
End Module

Run the program, copy the console output and paste to a new post.


Sunday, June 23, 2013 11:00 PM

In Rich textbox I get this msg "Access to the port 'COM2' is denied."

If the PIC is now attached to COM 2 then you have changed your configuration from what you first posted.

Have you confirmed the connection?  If the PIC is transmitting every 15s without needing a prompt of some sort then you should be able to use any generic serial port data communication application and see that data being received.  For instance:
http://technet.microsoft.com/en-us/sysinternals/bb896644.aspx

There are many others.   Until you are 100% sure of exactly how that PIC is connected and what it is doing, you are likely wasting effort with the VB app.


Wednesday, November 6, 2013 3:25 AM

I am able to recieve the serial data but want it to be seperated by comma or any other seperator .I am sending the data from arduino to comPort .and Im recieving it through visual basic gui ...It is only being displayed in one textbox as my 3 sensors value is concatenated .So how to seperate the sensor values so tha they can be fetch into indivisual text boxes


Wednesday, November 6, 2013 4:34 AM

So how to seperate the sensor values so tha they can be fetch into indivisual text boxes

You need to find an identifier in the data stream that marks the end of one transmission and the start of the next.  This might be a special start-of-record indicator, or it might be generic separator like a newline, or anything at all.  It entirely depends on the protocol that is defined within the PLC.