none
SerialPort Overrun Errors

    Question

  • I am writing a Windows Forms application (Visual C++ 2005) to record data from a device via RS485. The connection runs at a baud rate of 2000000 with 8 data bits, 1 stop bit, and parity set to none. No handshaking is used. Each data message is 720 bytes long, and messages are transmitted at 200Hz. The ReadBufferSize is 4096, the ReadTimeout is -1, and the ReceivedBytesThreshold is 1.

    My problem is that I get frequent overrun errors. This has the effect of dropping the end of some of the messages (around 5% of them).  What causes overrun errors? BytesToRead never comes close to ReadBufferSize, so I don't see where it has received too many bytes.

    System::Void Recorder_Form::Serial_Port_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
    {
     
    unsigned int count = 0;
     
    try
     
    {
        count =
    this->TM_Serial_Port->Read(this->In_Buffer,0,this->TM_Serial_Port->BytesToRead);
      }
     
    catch(...) {}
      try
     
    {
       
    this->Out_Writer->Write(this->In_Buffer,0,count);
     
    }
     
    catch(...) {}
    }

    In_Buffer is an array<unsigned char>^ the same size as ReadBufferSize. Out_Writer writes the data to a file on the computer. I have tried removing the file IO operation, but that has not changed the frequency of the overrun errors. There is also an another thread running that periodically updates the GUI display. Changing the update rate has also had no affect on the overrun errors. What can I do to eliminate this error and read all the data?

    Thanks for the help.

    PS - An old MFC application we have (this is what I'm trying to replace) is capable of reading the data at this rate without dropping a single byte, so I know it is possible to read all the data.

    Friday, February 27, 2009 7:54 PM

Answers

  • There are two kind of overrun errors.  The intuitive one is overrunning the receive buffer in the serial port driver.  The less obvious one is overrunning the buffer in the serial port chip.  .NET distinguishes them with SerialError.RXOver and SerialError.Overrun.  If you get RXOver, you are doing something wrong.  You're not emptying the receive buffer quick enough.  Overrun is a hardware problem, the serial port driver is not emptying the chip buffer fast enough.  You can fix the first one, you can't fix the second one.  Unless you use better hardware (larger chip buffer) or a smarter driver.

    Judging from your post, it is #2.  Put that MFC app on a pedestal if it can fix that.



    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Friday, March 06, 2009 6:44 AM
    Saturday, February 28, 2009 1:09 AM