没有在C#中读取完整的串口数据

时间:2011-01-11 18:58:20

标签: c# serial-port

我正在使用.Net framework 4并在C#中创建一个串口GUI应用程序。在某些情况下,SerialPort对象(端口)不会接收所有数据(我将其与混合信号示波器进行比较)

例如,如果连接的设备发送:

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09

我可以收到:

0x00 0x01 0x02 0x03 0x04 0x08 0x09

我尝试了具有相同问题的不同代码:

  • 使用收到的数据事件来填充缓冲区:

        private void dataReceived(object sender, SerialDataReceivedEventArgs e) {
            while (port.BytesToRead > 0){
                byte[] newBytes = new byte[port.BytesToRead];
                int LengthRead = port.Read(newBytes, 0, newBytes.Length);
                Array.Resize(ref newBytes, LengthRead);
                System.Buffer.BlockCopy(newBytes, 0, buffer, positionInBuffer, newBytes.Length);
                positionInBuffer += newBytes.Length;
            }
        }
    
  • 循环使用预期的字节数,在这种情况下导致TimeoutException:

            while (port.BytesToRead < expectedSize)
        {
            System.Threading.Thread.Sleep(10);
            waitingLoop++;
            if (waitingLoop > TimeOut)             // wait for a 1s timeout
                throw new TimeoutException();
        }
    
        newBytes = new byte[expectedSize];
        LengthRead = port.Read(newBytes, 0, newBytes.Length);
        if (LengthRead != newBytes.Length)
            throw new TimeoutException(); // or any exception, doesn't matter...
    

我试图更改ReadBufferSize大小,超时信息......但没有任何作用。 有什么想法吗?

3 个答案:

答案 0 :(得分:4)

此代码中存在细微错误。第一个片段的Array.Resize()什么都不做,可能需要重新调整 buffer 的大小?当收到更多字节而 expectedSize 时,第二个片段会在TimeoutException上发生爆炸。这当然是可能的,而不是超时问题。

但我认为真正的问题是你在这段代码之外对数组做了些什么。通常,调用SerialPort.Read()只能获得几个字节。串口很慢。您需要某种协议才能知道何时收到“完整”响应。一个非常常见的(非二进制)只是通过换行来终止响应。然后你只需在DataReceived事件处理程序中使用ReadLine()。在你的情况下,适当的方法是不明显的。

还实现ErrorReceived事件。它会告诉你发生了什么不好的事情,比如SerialError.Overrun或RXOver,这些错误也会使字节消失。

答案 1 :(得分:2)

尝试在串行端口上配置软件(XON / XOF)或硬件(例如RTS / CTS)握手,以匹配正在传输的设备的配置。

答案 2 :(得分:0)

感谢您的回答。

实际上我在串行数据中有某种协议。它类似于:

<ID><SIZE><DATA....><CHECKSUM>

我通常正确地获取ID,SIZE然后我会监听预期的'size'数据字节(大小小于1000,串口运行在115200,所以应该是很短的时间)。 但是当我等待它们时,例如使用第二个代码(等待循环)时,它们永远不会出现在我的C#代码上,即使它们真的通过思考串行线(用范围检查)。仍在运行第二个代码,我得到了第一个TimeOutException(在等待循环上),这意味着我没有收到1s内的所有数据(也试图增加到5s)。因此,在转到SerialPort.Read()函数之前,错误是捕获。

无论如何,我会检查ErrorReceived事件以检查是否有东西......

关于Array.Resize()我写了这个,以防返回的SerialPort.Read()数据的字节数少于预期的字节数。缓冲区的大小预先设置为我的SerialPort缓冲区的最大大小(4096)。 关于我在代码中的第二个错误你是对的。我应该更好地使用更合适的例外:)