Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# and SerialPort Class truncating data

I have a C# application that uses the .NET SerialPort class. The code that I use to pick up data from the serial port is nothing special. The key parts are

//Open the port
            comport.BaudRate = myPort.BaudRate;
            comport.StopBits = StopBits.One;
            comport.DataBits = 8;
            comport.Parity = Parity.None;
            comport.ReadTimeout = 20000;


            comport.PortName = myPort.PortSystemName;
            comport.Handshake = Handshake.None;
            comport.RtsEnable = true;


            comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            string msg = "";
            try
            {
                msg = comport.ReadExisting();

                if (comport.IsOpen)
                    comport.Close();
         }

This code works perfectly fine in Windows XP. However, on Windows 7 it runs into issues where no matter what data is sent, it ONLY picks up the first four characters. So in a string like "123456", the msg will be "1234". The device that is collecting the data is an RFIdeas pcProx and I have verified that the data is just fine. I have also verified that the data looks OK in hyperterminal. So there has to be something odd about the way that I'm picking up the data in code. Help!

like image 586
Unknown Coder Avatar asked Jan 19 '12 16:01

Unknown Coder


1 Answers

That is entirely consistent with the API. It is not, and never has been, guaranteed to read everything:

This method returns the contents of the stream and internal buffer of the SerialPort object as a string. This method does not use a time-out. Note that this method can leave trailing lead bytes in the internal buffer, which makes the BytesToRead value greater than zero.

Additionally, you need to handle the "not yet in the internal buffer" - you don't just read while BytesToRead is positive. This usually involves looping and buffering until an entire message is received.

It is your job to read the right amount of data, either by using markers such as line-ends, or by using a length-prefix header.

If it works perfectly fine on XP, then that is good fortune only (and maybe by some timing and/or efficiency tweaks).

Everything above applies equally to most inputs, not just serial ports; for example, file IO and network IO works along pretty much exactly the same principles.

like image 159
Marc Gravell Avatar answered Oct 07 '22 13:10

Marc Gravell