none
Reading data from serial port and plotting graph RRS feed

  • Question

  • Hi all,

    I am developing a VB.Net program to read data from serial port and plot a graph real time. Serial port is reading data continuously without end. I have implemented reading and plotting with the help answers from previous questions. But happens is that my screen freezes while running the program. Even though reading and plotting occurs continuosly, I cannot click on any other controls like button,combo etc

    Form Load

      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

            Dim addDataThreadStart As New ThreadStart(AddressOf AddDataThreadLoop)
            addDataRunner = New Thread(addDataThreadStart)
            addDataDel = New AddDataDelegate(AddressOf pltGraph)

     End Sub

    Serialport reading code

                                                                     

     Private Sub srpPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles srpPort.DataReceived
            Dim dtLen As Long
            Dim mnclpos As Integer = 0, mnrpos As Integer = 0, mnipos As Integer = 0
            Dim pos As Integer = 0, rpos As Integer = 0
            Dim vrpos As Integer = 0
            Dim variable(3) As Integer
            Dim srpos As Integer = 0
            Dim Ch1vl As Integer, Ch2vl As Integer, Ch3vl As Integer, Ch4vl As Integer
            Dim mnpos As Integer
            Dim nBytes As Integer
            If srpPort.IsOpen Then
    Dim dtRecvd(dtLen) As Byte

    Me.BeginInvoke(DirectCast((Sub()

    dtLen = srpPort.BytesToRead
                                    Do
    If srpPort.IsOpen Then
    Dim Incoming As Byte = srpPort.ReadByte()
                                                    If IsNothing(Incoming) Then Exit Do
                                    If Rd1Free Then
                            dtRd1.SetValue(Incoming, posMn)
    Rd1Data = True
    ElseIf Rd2Free Then
    dtRd2.SetValue(Incoming, posMn)
    Rd2Data = True
    End If

    posMn += 1
    If Rd1Free Then
    If posMn = RdBfrSz Then
    dtRd1.CopyTo(dtMain, CopyposMn)
    Rd1Free = False
    Rd2Free = True
    posMn = 0
    CopyposMn += RdBfrSz
    MnArrLen += RdBfrSz
    End If
    ElseIf Rd2Free Then
    If posMn = RdBfrSz Then
    dtRd2.CopyTo(dtMain, CopyposMn)
    Rd2Free = False
    Rd1Free = True
    posMn = 0
    CopyposMn += RdBfrSz
    MnArrLen += RdBfrSz
    End If
    End If

    ChMain.Invoke(addDataDel)
    End If
    Loop While posMn < dtLen

    End Sub), Action))

          End If

    End Sub

    Public Sub pltGraph() 
            Dim Ch1vl As Integer, Ch2vl As Integer, Ch3vl As Integer, Ch4vl As Integer
            Dim PntXVal As Long
            Dim value As Double
            blnThrdStrtd = True
            If MnArrLen Mod 20 <> 0 Then
                blnThrdStrtd = False
                Exit Sub
            Else

            End If
            While mnArrPos < MnArrLen - 1

    value = BitConverter.ToInt16(dtMain, mnArrPos)

    If value = 1246 Then
                    Dim ipos As Integer
                    For ipos = 0 To 3
                        ChMain.Series(ipos).Points.AddXY((CurXVal), variable(ipos))

                    Next
                    If CurXVal > myArea1.AxisX.Maximum Then
                        If mySeries1.Points.Count > 0 Then
                            PntXVal = mySeries1.Points(0).XValue + PltIntrvl
                            While mySeries1.Points(0).XValue < PntXVal
                                mySeries1.Points.RemoveAt(0)
                            End While
                            myArea1.AxisX.Minimum = mySeries1.Points(0).XValue - PltIntrvl
                            myArea1.AxisX.Maximum = myArea1.AxisX.Maximum + PltIntrvl
                            myArea1.AxisX.Crossing = (myArea1.AxisX.Minimum + myArea1.AxisX.Maximum) / 2
                            Ar1XMin = myArea1.AxisX.Minimum
                            Ar1XMax = myArea1.AxisX.Maximum
                        End If
                    End If
                    If CurXVal <= myArea1.AxisX.Maximum Then
                        CurXVal += PltIntrvl
                    End If
                    ChMain.ResetAutoValues()
                    ChMain.ResumeLayout()
                    vrpos = 0
                Else
                    variable(vrpos) = value / 1000
                    vrpos += 1

                    TotPnts += 1

                End If
                mnArrPos += 2


            End While

            blnThrdStrtd = False


    End Sub

    Hope somebody can helpme

    Wednesday, September 12, 2018 8:02 PM

All replies

  • I used Application.DoEvents. Then it works for sometime and causes StackOverflowException
    Wednesday, September 12, 2018 9:09 PM
  • You'll probably want to refactor your code.

    Use the serial port's DataReceived event handler to record the available bytes in a thread-safe collection.  Run a secondary Task to consume bytes from that thread-safe collection and process them.  The secondary task can periodically instruct the main thread to update the properties of a UI control, based on the processed data.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, September 12, 2018 11:00 PM
    Moderator
  • You'll probably want to refactor your code.

    Use the serial port's DataReceived event handler to record the available bytes in a thread-safe collection.  Run a secondary Task to consume bytes from that thread-safe collection and process them.  The secondary task can periodically instruct the main thread to update the properties of a UI control, based on the processed data.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Hi Reed!

    I think CodeMan is starting with the example I posted here which is based on a Microsoft example in the chart samples. It is an old example I suspect. Can you tell us if the example would work and maybe point to how to enter the serial data into the example?

    As I mentioned it seems to me there is some other problem in OPs original code that makes OP think there needs to be a thread? Look at OPs previous questions if you have time.

    Seems that if the chart is plotted in a timer loop then one can read the serial data in between timer ticks.

    Also seems this might be an async candidate?

    Thursday, September 13, 2018 12:04 PM