Modbus自定义消息和子功能(NModbus,TCP,子功能)

use*_*908 5 c# modbus

我在C#项目中使用NModbus,从/向许多I/O设备读取和写入Modbus数据.我在程序中使用Modbus TCP/IP协议(ModbusIpMaster等..).

我已经成功地与设备通信(通过Modbus网关),并且可以使用默认方法(例如,常见的Modbus功能,如ReadHoldingRegisters,WriteCoils)来访问设备中的数据,并可以回写它们.目前,我所能做的只是默认的NModbus方法,它暴露了常用的Modbus代码(1,2,3,4等......).

我有两个困难:

1)可以在Modbus代码70(0x46)下访问I/O设备的设置和额外信息,并且我需要使用子功能来读取和/或写入设置.

例如,Func 07(0x46),Sub func 6(0x06)可用于设置模块的通信设置.在这个例子中,有7个字节的信息要发送,这些信息带有设置(例如波特率等......)

NModbus没有针对此"自定义"功能代码的特定方法(70).因此,根据我的理解,需要使用NModbus的CustomMessage功能.我尝试过执行CustomMessage,当使用常见的Modbus功能代码(例如1或2)时,我可以获得与使用NModbus的默认方法相同的结果(即CustomMessage到目前为止工作).

当我尝试除了一般功能代码之外的功能代码(例如1,2,3 ......)时,我会得到各种异常.此外,我不知道如何发送带有消息的子功能!

当我在功能代码之后添加子功能(例如70后跟06),并且通过I get,exception发送数据.我真的需要这个领域的专家帮助.

这是一个更明显的例外:

"抛出类型'Modbus.SlaveException'的异常.功能代码:198异常代码:3 - 查询数据字段中包含的值不是服务器(或从属)的允许值.这表示结构中的错误复杂请求的剩余部分,例如隐含长度不正确.具体而言,并不意味着提交存储在寄存器中的数据项具有超出应用程序期望值的值,因为MODBUS协议不知道重要性任何特定登记册的任何特定价值."

2)第二个问题是通过Modbus 发送ASCII RS-232消息,以便控制连接到能够转换Modbus消息的模块的COM1的RS-232设备.换句话说,我打算与Modbus网关通信,将ASCII数据发送到COM1,然后COM1将数据转换为RS-232,然后与RS-232设备通信.翻译意味着在网关内部发生,所以我需要知道的是我在地球上如何发送这些消息,其长度各不相同.我不知道这是怎么可能的,从哪里开始.

Evi*_*Pie 0

第2部分- NModbus 允许您通过 TCP 或 UDP 客户端创建 ASCII 主站。

using (TcpClient client = new TcpClient("127.0.0.1", 502))
{
    ModbusSerialMaster master = ModbusSerialMaster.CreateAscii(client);

    // Use the master here
}
Run Code Online (Sandbox Code Playgroud)

关于问题的第一部分,NModbus 非常适合基础知识,但它缺乏允许任意扩展的抽象层。当我发现需要进行大量修改才能添加 GetServerId 函数并使其正常工作时,我自己的经历就结束了,尽管这是 Modbus RTU 规范的一部分。我的解决方案是从头开始重新实现它(这比首先编译和运行 NModbus 源代码花费的时间要少,因为它依赖于用于日志记录等的第三方库,并且缺少 IEnumerable 的扩展类)。