Modbus TCP 通讯 C#

Posted

技术标签:

【中文标题】Modbus TCP 通讯 C#【英文标题】:Modbus TCP Communication C# 【发布时间】:2020-06-10 01:40:15 【问题描述】:

我正在寻求一点帮助。 我有一个通过 Modbus TCP 与控制器通信的程序。 唯一的问题是我无法将 Nop 从 125 扩展到 400,因为我收到 Illegal Data Address 错误消息。 你能帮我解决这个问题吗?

            try
        
            byte slaveid = 1;
            byte function = 4;
            ushort id = function;

            ushort startAddress = 0;
            uint NoP = 125;

            byte[] frame = ReadInputRegistersMsg(id, slaveid, startAddress, function, NoP);
            this.Write(frame); //data send to controller
            Thread.Sleep(100);
            byte[] buffReceiver = this.Read(); //data recieving from controller
            int SizeByte = buffReceiver[8]; // Data what I got from the controller
            UInt16[] temp = null;

            if (function != buffReceiver[7])
            
                byte[] byteMsg = new byte[9];
                Array.Copy(buffReceiver, 0, byteMsg, 0, byteMsg.Length);
                byte[] data = new byte[SizeByte];
                textBox2.Text = Display(byteMsg);

                byte[] errorbytes = new byte[3];
                Array.Copy(buffReceiver, 6, errorbytes, 0, errorbytes.Length);
                this.CheckValidate(errorbytes); // check the answer -> error message
            
            else
            
                byte[] byteMsg = new byte[9 + SizeByte];
                Array.Copy(buffReceiver, 0, byteMsg, 0, byteMsg.Length);
                byte[] data = new byte[SizeByte];
                textBox2.Text = Display(byteMsg); // Show received messages in windows form app
                Array.Copy(buffReceiver, 9, data, 0, data.Length);
                temp = Word.ConvertByteArrayToWordArray(data); // Convert Byte[]-> Word[]
            
            // Result
            if (temp == null) return;
            string result = string.Empty;
            //foreach (var item in temp) // show all the data
            for(int i=0;i<100;i++) // show the first 100 data
            
                //result += string.Format("0 ", item);
                result += temp[i];
            
            textBox3.Text = result; // insert the result into the textbox (windows form app)

        
        catch
        

        

ReadInputRegister 消息如下:

private byte[] ReadInputRegistersMsg(ushort id, byte slaveAddress, ushort startAddress, byte function, uint NoP)
        
            byte[] frame = new byte[12];
            frame[0] = (byte)(id >> 8); // Transaction Identifier High
            frame[1] = (byte)id; // Transaction Identifier Low
            frame[2] = 0; // Protocol Identifier High
            frame[3] = 0; // Protocol Identifier Low
            frame[4] = 0; // Message Length High
            frame[5] = 6; // Message Length Low(6 bytes to follow)
            frame[6] = slaveAddress; // Slave address(Unit Identifier)
            frame[7] = function; // Function             
            frame[8] = (byte)(startAddress >> 8); // Starting Address High
            frame[9] = (byte)startAddress; // Starting Address Low           
            frame[10] = (byte)(NoP >> 8); // Quantity of Registers High
            frame[11] = (byte)NoP; // Quantity of Registers Low
            return frame;
        

【问题讨论】:

唯一使用 NoP 的地方是作为我们看不到的方法的参数 (ReadInputRegistersMsg)。那是发生异常的地方吗?还是...? 我刷新了问题! @MarcGravell 是什么给了你一个“非法数据地址”的错误信息——你将帧发送到的设备? 最后在wikipedia上找到了一个描述:Function code 4(读取输入寄存器)和function code 3(读取保持寄存器)请求:要读取的第一个寄存器地址(16位)要读取的寄存器数读取(16 位) 正常响应:跟随的寄存器值的字节数(8 位) 寄存器值(每个寄存器 16 位) 因为寄存器值的字节数是 8 位宽并且最大 modbus 消息大小是 256字节,一次只能读取 Modbus RTU 的 125 个寄存器和 Modbus TCP 的 123 个寄存器。[13] 所以基本上:125 是协议强加的硬限制?只是检查一下这里没有您要查找的其他内容...? 【参考方案1】:

The hard limit for modbus is 125 NoP

【讨论】:

以上是关于Modbus TCP 通讯 C#的主要内容,如果未能解决你的问题,请参考以下文章

请教KepServer与Modbus TCP通讯问题

Unity Modbus Tcp 通讯协议

modbus tcp和modbusrtu的区别

Modbus TCP 通讯 C#

基于ModBus-TCP/IT 台达PLC 通讯协议解析

Modbus TCP 示例报文