2

我正在为 modbus 和串行连接构建一个类库,我需要返回一个字节数组,但是当使用 System.IO.Ports 中的 DataReceived 事件时,我无法返回任何内容,因为它的类型是无效的。另外,我注意到 DataReceived 没有触发。以下是我的代码:

        public void ConnectSerialModBus_Loopback(string COM, int baud, int meter_address, int function, int Code_HighByte, int Code_LowByte, int data_high_byte, int data_low_byte)
    {
        SerialPort port = new SerialPort(COM, baud);
        try
        {

            if (!(port.IsOpen))
            {
                byte[] sendPacket = BuildPacket(meter_address, function, Code_HighByte, Code_LowByte, data_high_byte, data_low_byte);
                double dataBytes = 2.0;

                port.Open();
                port.RtsEnable = false;//rts = high
                port.Handshake = Handshake.None;
                //SEND PACKET TO DEVICE
                port.Write(sendPacket, 0, sendPacket.Length);

                #region RECEIVE DATA FROM SERIAL
                //MAKE DELAY TO SEND
                Thread.Sleep(10);

                port.RtsEnable = true;
                //MAKE DELAY TO RECEIVE
                port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                //Thread.Sleep(CalculateDelay(dataBytes)+90);

                port.Close();
                port.Dispose();
                #endregion

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (port != null)
            {
                if (port.IsOpen)
                {
                    port.Close();
                }
                port.Dispose();
            }
        }
    }

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort port = (SerialPort)sender;
        byte[] readingbyte = new byte[port.BytesToRead];
        if (port.BytesToRead > 0)
        {
            port.Read(readingbyte, 0, readingbyte.Length);   
        }
    }

以某种方式,我想返回从DataReceived 未触发的port_DataReceived或从DataReceived 接收的字节。ConnectSerialModBus_Loopback请帮助这是非常紧急的

4

2 回答 2

22

DataReceived 未触发

DataReceived 没有触发,因为您port.Close()在附加处理程序之后并且在 SerialPort 的接收线程有机会运行之前立即调用。

返回一个字节数组 - 简单的答案

在您提供的简单代码示例中,您可以创建一个私有Byte[]成员并readingbyte从您的port_DataReceived事件处理程序中将对象分配给它。

返回一个字节数组 - OO提示答案

但是,在一个更强大的应用程序中,您应该考虑创建一个封装 Modbus ADU 协议部分的事务类,处理客户端请求的传输和服务器响应的(第 2 层)处理。

除了 ADU 层之外,您还可以将 PDU 层分离为一个抽象的 ModbusFunction 基类,该基类为 ADU 类提供一个接口,以获取请求字节并返回响应字节。然后,您希望客户端使用的每个 modbus 功能都将在派生自 PDU 基类的自己的类中实现。

这样,当您需要与服务器交互时,您可以创建一个 PDU 函数类的实例,并使用适当的参数来形成正确的 PDU 数据包,并将其传递给处理请求/重试/响应逻辑的事务对象和将返回的数据传递回 PDU 对象以进行适当的解析。

向 PDU 基类添加事件将允许代码的其他部分附加到 PDU 类的事件并在函数成功完成时接收通知。

使用具有多个可寻址属性的服务器,通过 Modbus 函数实现,您将为每个属性创建一个适当的 Modbus 函数类的实例(例如,为连续寄存器创建其集合)并附加到事件,更新您的模型和/或每当对象引发其更新事件时的 UI。如果您想手动查询服务器,则挂钩 UI 命令以将 Properties Modbus Function 对象传递给 Transaction 对象,或者如果您希望定期轮询属性,则实现按计划执行此操作的计时器线程。

于 2014-07-14T18:18:42.290 回答
0

不要休眠 datareceived 事件。

当事件触发时,将字节放入队列中。您将需要 UI 可以用来将字节块重新组合在一起的方法。

有关这方面的更多详细信息,请参阅SerialPort101

于 2010-10-17T14:58:50.860 回答