Results 1 to 4 of 4

Thread: Reading from COM port works strange

  1. #1

    Thread Starter
    New Member
    Join Date
    Aug 2019
    Posts
    3

    Exclamation Reading from COM port works strange

    Hello to all,

    Sorry to bother you guys, but I need your help, as I was reading the forum during whole last week and did not found the answer. I am new in Visual Basic, but want to learn, so I installed Visual Studio 2017 and wrote the Arduino sketch. So, the idea is to send Arduino <1> or <2>, etc., over the serial and have a string of HEXes back. With Arduino Serial Monitor and Windows Hyper Terminal it works as a charm, I send and receive the data. But the same idea in VS is not working normally. The code:

    Private Sub button_READ_RAW_DATA_Click(sender As Object, e As EventArgs) Handles button_READ_RAW_DATA.Click
    If (serialPort1.IsOpen) Then
    serialPort1.Write("<1>")
    Dim raw_data_in As String = serialPort1.ReadExisting
    tBox_RAW_DATA.Text += raw_data_in & vbCrLf & vbCrLf
    End If
    End Sub

    There were second button READ_DECODED_DATA and another tBox for it (sending <2>), but I removed it for troubleshooting purposes. It should send the <1> and take the Arduino response, and put it in a tBox, but it works strange. At first run of the app and first press of the button I have only two line feeds (vbCrLf), but no data in teh tBox (Arduino sends the data for sure, I can see the LEDs blinking). If I would press the button second time - if writes the data to appropriate tBox. When I have two buttons it was almost the same - on the first run and first press of any button I had nothing from Arduino, just line feeds. If I press the same button again - it gives the data, but if the second press would be a different button than previous - it still gives the first button data. This led me to the thought, that the button reads the new data, but writes the old data from previous click. So the second press of the same button gives the old data to tBox and reads the new data and stores it for some reason. That also explains, why I don't have anything on the first run of the app - it does not have anything from before, but reads the new data to some memory, instead of just putting it to the tBox. Why this is happening and how to correct it ? I want to understand, so please, dont be shy with explanations :).

    Another thing from the same app, so I wouldn't have to create new thread. I am taking the COM port settings from tBoxes with code:

    serialPort1.PortName = cBox_COM_PORT.SelectedItem
    serialPort1.BaudRate = cBox_BAUD_RATE.SelectedItem
    serialPort1.DataBits = cBox_DATA_BITS.SelectedItem
    serialPort1.StopBits = IO.Ports.StopBits.One
    serialPort1.Parity = IO.Ports.Parity.None

    First three are taken from the tBoxes normally, but the Stopbits and Parity I cant make it work with tBoxes, so made it like this for testing. The tBoxes has a Collection fields with One and Two for Stop Bits and None, Odd, Even for Parity. How to make it somehow parse the selected settings in tBoxes to the appropriate COM port settings ?

    Thank you all for support, have a great and sunny day with good mood all the week !

  2. #2
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Reading from COM port works strange

    You click the button,
    It sends the data over the serial bus.
    It reads existing... (guess what, serial is slow and there is no existing data yet, so nothing is read).

    Later, you click the button again.
    It sends the data over the serial bus.
    It reads existing... (now there is data existing, i.e. the response from the earlier transmit, so you read that).

    And so it goes.

    Normally, you should transmit the data in the button press and leave.
    The serial will take awhile to get over to the other device and the other device respond, so you should select the DataReceived Event from the list of events associated with the serialport object and generate an event handler sub for that event. You will get an event when the serial port has data to be read.
    It is possible that not all the data has been received, but that is up to you to determine based on what you expect to receive.
    So put your GetExisting call in that event handler.
    A caveat, the event is on a secondary thread so you can't access controls from that event handler.
    You may want to invoke a sub to process the received data.
    Code:
      Private Sub DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    
        Dim ReceivedData As String
        ReceivedData = SerialPort1.ReadExisting()
        ' TextBox1.Text = ReceivedData
        Me.Invoke(Sub() Me.TextBox1.Text = ReceivedData)
      End Sub
    As for parsing the Tboxes, I guess you could do that manually, i.e.
    Code:
    Select Case TboxStopBits.Text
      Case "0" : serialPort1.StopBits = IO.Ports.StopBits.None
      Case "1" : serialPort1.StopBits = IO.Ports.StopBits.One
      Case "1.5" : serialPort1.StopBits = IO.Ports.StopBits.OnePointFive
      Case "2" : serialPort1.StopBits = IO.Ports.StopBits.Two
    End Select
    
    'Something similar for Parity
    Or, use Listboxes and present them with the options to choose from, and still use the selected index to select the Case and set the value.
    I haven't searched to see if there is some other way to add the values themselves to a list or enumeration and process the selection in a more direct way, but I really don't have the time. Doing more here than I should be as is right now.
    Last edited by passel; Aug 20th, 2019 at 10:25 AM.

  3. #3

    Thread Starter
    New Member
    Join Date
    Aug 2019
    Posts
    3

    Re: Reading from COM port works strange

    passel !!! You saved me, thank you for that !!! I had the idea that COM port is slow, but somehow I thought that Visual Studio will handle that automatically. I just added artef sending the <1>:

    System.Threading.Thread.Sleep(250)

    And it worked. I know that pausing the app is not optimal, but its OK for my purposes. The lowest value to receive data was 100 ms so I made it double and added 50 ms for being sure it will work on all PCs at given Baud. That might need some tweaking, but that is later, when I will know more about programming in VB.

    And advice to do the manual parsing also worked, only that I used it with combo boxes, not text boxes, as I wrote before. Heres the code if someone would need it:

    Select Case cBox_STOP_BITS.Text
    Case "One" : serialPort1.StopBits = IO.Ports.StopBits.One
    Case "Two" : serialPort1.StopBits = IO.Ports.StopBits.Two
    End Select

    Select Case cBox_PARITY_BITS.Text
    Case "None" : serialPort1.Parity = IO.Ports.Parity.None
    Case "Odd" : serialPort1.Parity = IO.Ports.Parity.Odd
    Case "Even" : serialPort1.Parity = IO.Ports.Parity.Even
    End Select

    Thank you once again for the ideas and your time !

  4. #4

    Thread Starter
    New Member
    Join Date
    Aug 2019
    Posts
    3

    Exclamation Re: Reading from COM port works strange

    passel !!! You saved me, thank you for that !!! I had the idea that COM port is slow, but somehow I thought that Visual Studio will handle that automatically. I just added artef sending the <1>:

    System.Threading.Thread.Sleep(250)

    And it worked. I know that pausing the app is not optimal, but its OK for my purposes. The lowest value to receive data was 100 ms so I made it double and added 50 ms for being sure it will work on all PCs at given Baud. That might need some tweaking, but that is later, when I will know more about programming in VB.

    And advice to do the manual parsing also worked, only that I used it with combo boxes, not text boxes, as I wrote before. Heres the code if someone would need it:

    Select Case cBox_STOP_BITS.Text
    Case "One" : serialPort1.StopBits = IO.Ports.StopBits.One
    Case "Two" : serialPort1.StopBits = IO.Ports.StopBits.Two
    End Select

    Select Case cBox_PARITY_BITS.Text
    Case "None" : serialPort1.Parity = IO.Ports.Parity.None
    Case "Odd" : serialPort1.Parity = IO.Ports.Parity.Odd
    Case "Even" : serialPort1.Parity = IO.Ports.Parity.Even
    End Select

    Thank you once again for the ideas and your time !

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width