Serial Port ReadLine vs ReadExisting or how to read the data from serial port properly

62,117

Solution 1

I have never had luck with ReadLine working. Just do a Read into a local buffer whenever data is available and then use a separate thread to scan the data and find line breaks yourself.

Solution 2

Depends on what the end-of-line (EOL) character(s) is for your input data. If your data is line oriented then ReadLine is a valid function to use, but you may want to look at the NewLine property and be sure that it is set appropriately for your input data.

For example, if your scale outputs linefeed for EOL then set port.NewLine = "\n";

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.newline.aspx

Solution 3

if (serialPort1->IsOpen){
    if (serialPort1->BytesToRead>0){
        this->textBox1->Text += serialPort1->ReadExisting();
    }
}

Solution 4

I am adding an answer to respond to Elias Santos. There are some gotchas in using the ReadExisting method:

https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.readexisting(v=vs.110).aspx

Note that this method can leave trailing lead bytes in the internal buffer, which makes the BytesToRead value greater than zero.

I faced some issues with ReadExisting before and this is because of the unwanted bytes. Using Readline fixed those issues.

Share:
62,117
aliadly
Author by

aliadly

I am a ASP.net/PHP web developer. Recently I have been involved with a Compact Framework project which explains my multiple CF related questions.

Updated on December 07, 2020

Comments

  • aliadly
    aliadly over 3 years

    I am reading data from serial port. The data comes off the scale. I am now using Readline() and getting data dropped even after I removed DiscardInBuffer().

    What is the proper way to read the data from the serial port? There are so few examples online that I feel it's like some holy grail that no one has figured out.

    C#, WinCE 5.0, HP thin client, Compact framework 2.0

     private void WeighSample()
        {
            this._processingDone = false;
            this._workerThread = new Thread(CaptureWeight);
            this._workerThread.IsBackground = true;
            this._workerThread.Start();
        } //end of WeighSample()
    
    
        private void CaptureWeight()
        {
             globalCounter++;
             string value = "";
    
    
              while (!this._processingDone)
              {
                  try
                  {
    
                     value = this._sp.ReadLine();
    
                      if (value != "")
                      {
                          if (value == "ES")
                          {
                              _sp.DiscardInBuffer();
                              value = "";
                          }
                          else
                          {
                              this.Invoke(this.OnDataAcquiredEvent, new object[] { value });
                          }
                      }
                  }
                  catch (TimeoutException)
                  {
                      //catch it but do nothing
                  }
                  catch
                  {
                      //reset the port here?
                      MessageBox.Show("some other than timeout exception thrown while reading serial port");
                  }
              }
    
    
        } //end of CaptureWeight()
    

    One thing to note about my application is that I start the thread (weighSample) when the cursor jumps onto the textbox. The reason to this is that the weight can also be typed in manually (part of the requirements). So I don't know in advance whether a user is going to press PRINT on the balance or type the weight. In either case after the data is acquired, I exit the worker thread. Also, note that I am not using serial port event DataReceived, since I have been told it's not reliable.

    This is my first experience with serial ports.