C# ModbusTcp(协议)

以下用例为读取线圈,可读取多个连续的线圈(01功能码)

            //起始地址
            var inputAddress = 4;
            //读取长度
            var inputReadLength = 8;

            var station = BitConverter.GetBytes(4)[0]; //从站地址
            var funCode = BitConverter.GetBytes(1)[0];//功能码

            var startAddress = BitConverter.GetBytes(inputAddress)[1];
            var endAddress = BitConverter.GetBytes(inputAddress)[0];
            var startLength = BitConverter.GetBytes(inputReadLength)[1];
            var endLength = BitConverter.GetBytes(inputReadLength)[0];

            TcpClient tcpClient = new TcpClient();
            tcpClient.Connect("", 502);
            byte[] by = new byte[]
            {
                //事物标识符
                0x00,
                0x00,
                //协议标识符 固定值
                0x00,
                0x00,
                //长度
                0x00,
                0x06,
                //从站地址
                station,
                //功能码
                funCode,
                startAddress, //起始地址
                endAddress,
                startLength, //读个数
                endLength
            };

            tcpClient.Client.Send(by);

            byte[] result = new byte[1024];
            var ulength = tcpClient.Client.Receive(result);

            var newResult = result.ToList().Take(ulength).ToArray();
            //输出报文
            var output = string.Join(" ", newResult.Select(x => x.ToString("X2")));


            //00 00 00 00 00 04 04 01 01 00

            //00 00 //事物标识符 服务器复制
            //00 00 //协议标识符 固定值
            //00 04 //长度
            //04    //从站地址
            //01    //功能码
            //01    //个数
            //00    //数值

            byte[] bol = new byte[newResult[8]];
            if (newResult[8] > 1)
            {
                for (int i = 0; i < bol.Length; i++)
                    bol[i] = newResult[8 + i + 1];

                var getbyte = ByteToBoolArray(bol, by[by.Length - 1]);
                getbyte.ToList().ForEach(x =>
                {
                    Console.WriteLine(x);
                });
            }
            else
            {
                bol[0] = newResult[9];
                var getbyte = ByteToBoolArray(bol, by[by.Length - 1]);

                getbyte.ToList().ForEach(x =>
                {
                    Console.WriteLine(x);
                });
            }

        }

        public static bool[] ByteToBoolArray(byte[] InBytes, int length)
        {
            if (InBytes == null) return null;

            if (length > InBytes.Length * 8) length = InBytes.Length * 8;

            bool[] buffer = new bool[length];

            for (int i = 0; i < length; i++)
            {
                int index = i / 8;
                int offect = i % 8;

                byte temp = 0;
                switch (offect)
                {
                    case 0: temp = 0x01; break;
                    case 1: temp = 0x02; break;
                    case 2: temp = 0x04; break;
                    case 3: temp = 0x08; break;
                    case 4: temp = 0x10; break;
                    case 5: temp = 0x20; break;
                    case 6: temp = 0x40; break;
                    case 7: temp = 0x80; break;
                    default: break;
                }

                if ((InBytes[index] & temp) == temp)
                {
                    buffer[i] = true;
                }
            }

            return buffer;
        }

其他读写削微修改一下即可,如写入多个连续的float类型(float需要注意字节排序规则 ABCD...)

00 00 
00 00 
00 0F //报文长度

01 //从站地址

10 //功能码
00 00 //起始地址
00 04 //读取长度
08   //字节长度
42 05 33 33 
42 05 33 33

你可能感兴趣的:(工厂,c#,后端)