我在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 消息,以便控制连接到模块COM1的RS-232设备能够转换Modbus消息。换句话说,我打算与Modbus网关通信,将ASCII数据发送到COM1,然后COM1将数据转换为RS-232,然后与RS-232设备通信。翻译意味着在网关内部发生,所以我需要知道的是我在地球上如何发送这些消息,其长度各不相同。我不知道这是怎么可能的,从哪里开始。
答案 0 :(得分: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
}
关于问题的第一部分,NModbus非常适合基础知识,但它缺少一层抽象,可以任意扩展。当我发现需要进行大量修改才能使GetServerId功能正常工作时,我自己的体验结束了,即使这是Modbus RTU规范的一部分。我的解决方案是从头开始重新实现它(由于它依赖于第三部分库的日志记录等,并且缺少扩展,因此我花费的时间比首先编译和运行NModbus源所花费的时间少。 IEnumerable类)。