我在一个NModbus项目中使用C#,从许多I/O设备读取和写入Modbus数据。我正在使用Modbus /IP协议(ModbusIpMaster等)在节目里。
我已经成功地与设备进行了通信(通过Modbus网关),并且可以使用默认方法(例如,常见的Modbus函数,如ReadHoldingRegisters、WriteCoils )访问设备中的数据,并可以将数据写回给它们。目前,我所能做的只有默认的NModbus方法,这些方法公开了常用的Modbus代码(1、2、3、4等)。
我有两个困难:
1) I/O设备的设置和额外信息可以在Modbus代码70 (0x46)下访问,有一些子函数,我需要使用这些子函数来读取和/或写入设置。
例如,Func 07 (0x46)、Sub func 6 (0x06)可用于设置模块的通信设置。在本例中,需要发送7字节的信息,其中包含设置(例如波特率等)。
对于这个“自定义”函数代码(70),NModbus没有特定的方法。因此,据我所知,需要使用CustomMessage特性的NModbus。我已经尝试过执行CustomMessage,当使用常见的Modbus函数代码(例如1或2)时,我可以获得与使用NModbus的默认方法相同的结果(即CustomMessage到目前为止正在工作)。
当我尝试函数代码而不是一般代码(例如1,2,3.)我确实有各种各样的例外。此外,我不知道我应该如何发送子函数与消息!
当我在函数代码之后添加子函数时(例如,70后面跟着06),数据通过I get发送,异常。我真的需要这个领域的专家的帮助。
这里有一个更明显的例外:
“抛出'Modbus.SlaveException‘类型的异常。函数代码:198个异常代码:3-查询数据字段中包含的A值不是服务器(或从服务器)的允许值。这表明复杂请求的其余部分的结构出现了错误,例如隐含长度不正确。具体而言,这并不意味着提交到寄存器中存储的数据项的值超出应用程序的期望,因为MODBUS协议不知道任何特定寄存器的任何特定值的重要性。”
2)第二个问题是通过Modbus发送ASCII RS-232消息,以便控制连接到具有转换Modbus消息能力的模块的COM1的RS-232设备。换句话说,我计划与Modbus网关通信,将ASCII数据发送到其COM1,后者将数据转换为RS-232,然后与RS-232设备进行通信。翻译应该发生在网关的内部,所以我所需要知道的就是如何在地球上发送这些消息,它们的长度各不相同。我不知道这是怎么可能的,也不知道从哪里开始。
发布于 2014-07-15 08:23:16
Part 2 - NModbus允许您在TCP或UDP客户端上创建主服务器。
using (TcpClient client = new TcpClient("127.0.0.1", 502))
{
ModbusSerialMaster master = ModbusSerialMaster.CreateAscii(client);
// Use the master here
}
关于问题的第一部分,NModbus在基础方面是很棒的,但是它缺少一个抽象层,可以任意扩展它。当我发现添加和使GetServerId函数工作需要进行重大修改时,我自己的经验就结束了,尽管这是Modbus规范的一部分。我的解决方案是从头开始重新实现它(这比首先让NModbus源代码编译和运行花费的时间更少,因为它依赖第三方库进行日志记录,等等&缺少IEnumerable类的扩展)。
https://stackoverflow.com/questions/14097393
复制相似问题