我有一个网关连接到一台运行C#程序的计算机上。我在计算机和网关之间有一个Modbus从主关系.下面是网关配置(EKI-1221-BE型号):
我的设置与这张图片相同,但我有6个设备连接,而不是2个,以后将有12个设备:
我可以向这6个设备中的任何一个发送Modbus命令,没有任何问题,但是当我试图在短时间内发送多个命令时,问题就会发生。在下面的代码中,只有设备1、2和6接收命令。
PumpsComm.SendMessage(1, 3099, 2000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(2, 3099, 3000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(3, 3099, 4000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(4, 3099, 6000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(5, 3099, 8000);
PumpsComm.ClientSocket.Receive(TempBuffer);
PumpsComm.SendMessage(6, 3099, 10000);
PumpsComm.ClientSocket.Receive(TempBuffer);
函数SendMessage如下所示,其中ClientSocket是连接到网关/ Modbus从节点的TCP套接字。
public void SendMessage(int pumpID, int register, int command)
{
byte[] message = new byte[12];
message[0] = 0;
message[1] = 0; //Message number
message[2] = 0;
message[3] = 0;
message[4] = 0;
message[5] = 6; //Message length
message[6] = (byte)ToHexInDec(pumpID, 'L'); //Pump ID
message[7] = 6;
message[8] = (byte)ToHexInDec(register, 'H'); //Register high
message[9] = (byte)ToHexInDec(register, 'L'); //Register low
message[10] = (byte)ToHexInDec(command, 'H'); //Command high
message[11] = (byte)ToHexInDec(command, 'L'); //Command low
try
{
ClientSocket.Send(message);
}
catch
{
return;
}
}
如果在每次发送之间让线程休眠30 as,那么每个命令都可以工作,但在我的情况下,这不是一个选项,因为我需要能够在很短的时间内更新每个设备。
我看了一下我和Wireshark在网关收发的数据包,我想我找到了
这就是Wireshark的输出(以200结尾的Ip是计算机,以107结尾的Ip是网关):
看起来,设备3、4、5和6的通信,其中放入相同的TCP数据包,出于某种原因,唯一从该数据包读取的Modbus通信是最后一个。
我尝试为Modbus通信的MBAP头中的每个通信添加MBAP事务号,但是它没有改变任何东西。然后,我尝试添加一个阻塞接收,使程序在发送下一个通信之前等待Modbus响应,但我没有收到任何消息(即使我们可以看到,当通信成功时,网关正在发送一个Modbus响应)
我不知道我还能做些什么,我想看看是否有人在TCP modbus通信方面有更多的经验。如有需要,我可以提供更多细节。对不起,如果这不够清楚,英语不是我的第一语言。
谢谢!
发布于 2022-07-22 21:16:05
根据规格
可以在同一个TCP连接上同时激活多个MODBUS事务。 注意:如果这样做了,那么必须使用MODBUS事务标识符来唯一地标识匹配的请求和响应。
但是,您正在发送将事务标识符设置为0000
的消息。
message[0] = 0;
message[1] = 0; //Message number
(我猜网关正在检测复制并为此分配一个新的标识符)。
一种更好的方法是发送所有的请求(每个请求都有不同的标识符;只要它是唯一的,这并不重要),然后等待响应进来(使用每个响应中的事务标识符将响应与请求匹配;响应可能与请求的顺序不同)。
请注意,您不应该假设每个响应都将出现在一个单独的TCP数据包中(或者它将位于单个数据包中);协议考虑到了这一点:
当MODBUS通过TCP时,在MBAP报头中携带额外的长度信息,以允许收件人识别消息边界,即使消息已被分割成多个分组以进行传输。显式和隐式长度规则的存在,以及CRC-32错误检查代码(在以太网上)的使用,导致对请求或响应消息不被检测到损坏的可能性微乎其微。
https://stackoverflow.com/questions/73085846
复制相似问题