我需要编写一个程序,通过RS485监听ModBus网络中的通信。 我用RS485连接到网络<> USB加密狗。
我可以使用SerialPort.DataReceived事件读取一些数据,但它会产生奇怪的结果。 数据经常是分开的,它应该是一体的。 (Modbus Master每隔100ms发送一次)。
class Serial
{
private SerialPort port;
Queue<byte[]> buffer;
public Serial()
{
buffer = new Queue<byte[]>();
port = new SerialPort("COM3", 19200, Parity.Even, 8, StopBits.One);
port.DataReceived += port_DataReceived;
}
public void Open()
{
if (port.IsOpen)
{
port.Close();
}
port.Open();
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buff = new byte[port.BytesToRead];
port.Read(buff, 0, port.BytesToRead);
buffer.Enqueue(buff);
}
}
我没有任何开始签到传输。 帧之间的延迟是最小的。 3.5个字符,字符之间的最大延迟为1.5个字符。
答案 0 :(得分:2)
这是完全正常的,串口是非常慢的设备。收到一个字节后立即触发DataReceived事件。您需要调用Read()并注意它返回的值,它能够从输入缓冲区中检索的字节数。哪个可能不止一个,但很少等于“数据包”中的字节数,只有当机器由于某种原因变得很慢时才会发生。
请注意,调试器是使其变慢的一种方法,断点或单步执行事件处理程序代码可为驱动程序提供足够的时间来接收数据包中的所有字节。这样Read()调用就会返回它们。但是,一旦停止调试该代码,它就会停止工作。
您可以使用ReceivedBytesThreshold属性来延迟事件,但这只能在数据包具有固定大小时才能工作。只需使用Read()调用的第二个参数将您获得的字节附加到byte []中。并且在你拥有它们之前不要处理数据包。