首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Modbus通过tcp通信并不能将数据发送到所有设备

Modbus通过tcp通信并不能将数据发送到所有设备
EN

Stack Overflow用户
提问于 2022-07-22 20:40:40
回答 1查看 361关注 0票数 0

我有一个网关连接到一台运行C#程序的计算机上。我在计算机和网关之间有一个Modbus从主关系.下面是网关配置(EKI-1221-BE型号):

我的设置与这张图片相同,但我有6个设备连接,而不是2个,以后将有12个设备:

我可以向这6个设备中的任何一个发送Modbus命令,没有任何问题,但是当我试图在短时间内发送多个命令时,问题就会发生。在下面的代码中,只有设备1、2和6接收命令。

代码语言:javascript
运行
复制
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套接字。

代码语言:javascript
运行
复制
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通信方面有更多的经验。如有需要,我可以提供更多细节。对不起,如果这不够清楚,英语不是我的第一语言。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-22 21:16:05

根据规格

可以在同一个TCP连接上同时激活多个MODBUS事务。 注意:如果这样做了,那么必须使用MODBUS事务标识符来唯一地标识匹配的请求和响应。

但是,您正在发送将事务标识符设置为0000的消息。

代码语言:javascript
运行
复制
message[0] = 0;
message[1] = 0;     //Message number

(我猜网关正在检测复制并为此分配一个新的标识符)。

一种更好的方法是发送所有的请求(每个请求都有不同的标识符;只要它是唯一的,这并不重要),然后等待响应进来(使用每个响应中的事务标识符将响应与请求匹配;响应可能与请求的顺序不同)。

请注意,您不应该假设每个响应都将出现在一个单独的TCP数据包中(或者它将位于单个数据包中);协议考虑到了这一点:

当MODBUS通过TCP时,在MBAP报头中携带额外的长度信息,以允许收件人识别消息边界,即使消息已被分割成多个分组以进行传输。显式和隐式长度规则的存在,以及CRC-32错误检查代码(在以太网上)的使用,导致对请求或响应消息不被检测到损坏的可能性微乎其微。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73085846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档