MODBUS RTU 写单个线圈

开关量写入和开关量采集

05(0x05)写单个线圈或单个离散输出

功能说明

用于将单个线圈寄存器(或离散输入)设置为ON或OFF,该功能码支持广播模式,在广播模式下,所有从站设备的同一地址的值将被统一修改,查询报文中的ON或OFF状态由报文数据字段的常熟指定,0xFF00表示ON状态,0x0000表示OFF状态。其他所有值均是非法的,并且对寄存器不起作用,将会返回异常相应。

查询报文
本功能码中,起始地址由2个字节构成,取值范围为0x0000~0xFFFF;变更目标数据由2个字节构成,取值只能为0xFF00或0x0000.

响应报文
对于从设备,在线圈或离散输出寄存器正常变更的情况下,则返回于查询报文一样的响应报文。如果修改失败,则返回一个异常响应。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO.Ports;
using System.Threading;

namespace ReadRegister
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 字节数组转字符串
            byte[] vals = { 0x01, 0xAA ,0x02};
            string strr = BitConverter.ToString(vals);
            Console.WriteLine(strr); //结果01-AA-02
            string st1 = BitConverter.ToString(vals).Replace("-", "");
            Console.WriteLine(st1);//结果01AA02


            SerialPort serialPort = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
            if (!serialPort.IsOpen)
            {
                serialPort.Open();
            }
            
            string str = "FE 05 00 00 00 00 D9 C5";
            string[] arr = str.Split(' ');
            List<byte> command = new List<byte>();
            byte[] b = new byte[arr.Length];

            for (int i = 0; i < arr.Length; i++)
            {
               // arr[i] = "0x" + arr[i];
                b[i] = Convert.ToByte(arr[i], 16);
            }
            
            command.AddRange(b);
       
            /*
            //拼接报文
            ushort startAddr = 0;
            ushort readLen = 1;
            List<byte> command = new List<byte>();

            command.Add(0xFE);//从站地址
            command.Add(0x05);//功能码
            command.Add(BitConverter.GetBytes(startAddr)[1]);//开始地址
            command.Add(BitConverter.GetBytes(startAddr)[0]);

            // command.Add(BitConverter.GetBytes(readLen)[1]);//读取长度
            //command.Add(BitConverter.GetBytes(readLen)[0]);
            command.Add(0xFF);
            command.Add(0x00);
            command.Add(0x98);
            command.Add(0x35);
            //crc
           // byte[] crc = CalculateCRC(command.ToArray(), command.Count);
           // command.AddRange(crc);
            //连接串口
            */
            //发送
            serialPort.Write(command.ToArray(), 0, command.Count);
            
            //接收
            Thread.Sleep(50);
            int lengh = serialPort.BytesToRead;
            byte[] buffer = new byte[lengh];

            serialPort.Read(buffer, 0, lengh);
            //接收到字节数组数据 转字符串打印
            Console.WriteLine(BitConverter.ToString(buffer)); //FE - 05 - 00 - 00 - 00 - 00 - D9 - C5
            //byte[] result = new byte[buffer.Length];

            //Array.Copy(buffer, 3, result, 0, buffer.Length);

            string getstr = byteToHexStr(buffer);

            Console.WriteLine(getstr); //FE0500000000D9C5

            //Console.WriteLine((result[0] * 256 + result[1]).ToString());

            Console.ReadKey();
        }

        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");//ToString("X2") 只是以16进制格式化 不显示0x ,X是十六进制,2是两位格式不足高位补零
                }
            }
            return returnStr;
        }

    }
}


版权声明:本文为u010029229原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u010029229/article/details/128051506