5

我在 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),并且数据通过我发送,异常。我真的需要这个领域的专家的帮助,拜托。

这是一个更明显的例外:

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

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

4

1 回答 1

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 的扩展类)。

于 2014-07-15T08:23:16.987 回答