基于.net 基于ModBus协议的PLC设备数据采集(单片机,研华6017设备)

1.场景

  项目上需要对一些工厂设备状态进行实时状态分析,生成折线图并报警等。

  设备外面一般都接入了处理模块(单片机,6017等)(相当于网关设备),对信号进行转化,由网线接出,可进行采集。

2.程序

基础访问使用类库HslCommunication.dll。  github可以下到,无需在csdn花币下载(https://github.com/dathlin/ModBusTcpTools

(1)所需参数

  设备ip,设备端口(一般默认为502),设备各寄存器地址,长度,以及对应描述信息(该信息可能不必须),如下图所示

  

实际使用中,地址从0开始,长度为下一个地址减上一个地址的值。

所以上图信息为   一通道:起始地址为0,length为2,说明    40001

                            二通道:起始地址为2,length为2,说明    40003   。。。。。。。。。。。。。。。

(2)程序处理以及类库的使用

   使用的诸多方法如下:

public string Ip
        {
            set; get;
        }

        public int Port
        {
            set; get;
        }

        //private string LogPath
        //{
        //    get
        //    {
        //        return @"C:\log.log";
        //    }
        //}
        public ModBusRead()
        {
            //LogNet = new HslCommunication.LogNet.LogNetSingle(LogPath);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Ip">通讯网关IP</param>
        /// <param name="Port">通讯网关端口,默认端口502</param>

        public ModBusRead(string Ip,int Port)
        {
            this.Ip = Ip;
            this.Port = Port;
            //LogNet = new HslCommunication.LogNet.LogNetSingle(LogPath);
        }

        private ModBusTcpClient modBusTcpClient;

        /// <summary>
        /// 连接通讯网关
        /// </summary>
        /// <returns></returns>
        public  bool Connect()
        {
            modBusTcpClient = new ModBusTcpClient(Ip, Port);
            //modBusTcpClient.LogNet = LogNet;
            if (!modBusTcpClient.ConnectServer().IsSuccess)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 根据变量类型读取变量
        /// </summary>
        /// <param name="Item">变量类</param>
        /// <returns></returns>
        public  string Read(VarItem Item)
        {
            return Read(Item.RegisterStart.ToString(), Item.DataLenth.ToString());
        }

        /// <summary>
        /// 根据变量起始地址和长度读取变量
        /// </summary>
        /// <param name="RegisterStart">变量起始地址</param>
        /// <param name="len">长度</param>
        /// <returns></returns>
        public string Read(string RegisterStart,string len)
        {
            HslCommunication.OperateResult<ushort, ushort> result = GetAddressAndDataLenth(RegisterStart, len);
            if (result.IsSuccess)
            {
                return MessageResultRecieved(modBusTcpClient.ReadRegister(result.Content1, result.Content2));
            }
            return "";
        }

        /// <summary>
        /// 读取字符串
        /// </summary>
        /// <param name="Item">变量类</param>
        /// <returns>返回字符串</returns>
        public string ReadString(VarItem Item)
        {
            return ReadString(Item.RegisterStart.ToString(), Item.DataLenth.ToString());
        }

        /// <summary>
        /// 读取字符串
        /// </summary>
        /// <param name="RegisterStart">变量起始地址</param>
        /// <param name="len">长度</param>
        /// <returns>返回字符串</returns>
        public string ReadString(string RegisterStart, string len)
        {
            HslCommunication.OperateResult<ushort, ushort> result = GetAddressAndDataLenth(RegisterStart, len);
            if (result.IsSuccess)
            {
                return ResultRecievedString(modBusTcpClient.ReadStringRegister(result.Content1, result.Content2));
            }
            return "";
        }

        /// <summary>
        /// 读取整数型变量
        /// </summary>
        /// <param name="Item">变量类</param>
        /// <returns>返回整数</returns>
        public int ReadInt(VarItem Item)
        {
            return ReadInt(Item.RegisterStart.ToString(), Item.DataLenth.ToString());
        }

        /// <summary>
        /// 读取整型变量
        /// </summary>
        /// <param name="RegisterStart">变量起始地址</param>
        /// <param name="len">长度</param>
        /// <returns></returns>
        public int ReadInt(string RegisterStart, string len)
        {
            HslCommunication.OperateResult<ushort, ushort> result = GetAddressAndDataLenth(RegisterStart, len);
            if (result.IsSuccess)
            {
                return ResultRecievedInt(modBusTcpClient.ReadIntRegister(result.Content1));
            }
            return -1;
        }
        
        

        /// <summary>
        /// 接收返回的字符值
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        private string ResultRecievedString(HslCommunication.OperateResult<string> result)
        {
            if (result.IsSuccess)
            {
                return result.Content;
            }
            return "";
        }

        /// <summary>
        /// 接收返回的整数数据
        /// </summary>
        /// <param name="result">返回值</param>
        /// <returns></returns>
        private int ResultRecievedInt(HslCommunication.OperateResult<int> result)
        {
            if (result.IsSuccess)
            {
                return result.Content;
            }
            return -1;
        }

        /// <summary>
        /// 读取float型变量
        /// </summary>
        /// <param name="RegisterStart">变量起始地址</param>
        /// <param name="len">长度</param>
        /// <returns>返回float型字符串</returns>
        public string ReadFloat(string RegisterStart, string len)
        {
            HslCommunication.OperateResult<ushort, ushort> result = GetAddressAndDataLenth(RegisterStart.ToString(),len);
            if (result.IsSuccess)
            {
                return ResultRecievedFloat(modBusTcpClient.ReadRegister(result.Content1, 2));
            }
            return "";
        }

        /// <summary>
        /// 读取float型变量
        /// </summary>
        /// <param name="Item">变量类</param>
        /// <returns>返回浮点型数值字符串</returns>
        public string ReadFloat(VarItem Item)
        {
            return ReadFloat(Item.RegisterStart.ToString(), Item.DataLenth.ToString());
        }

        /// <summary>
        /// default  采用CDAB格式表示float
        /// </summary>
        /// <param name="result"></param>
        /// <returns>返回float型字符串</returns>
        private string ResultRecievedFloat(HslCommunication.OperateResult<byte[]> result)
        {
            if (result.IsSuccess)
            {
                string HexString =HslCommunication.BasicFramework.SoftBasic.ByteToHexString(result.Content, ' ');
                List<string> acts = HexString.Split(' ').ToList();
                if (acts.Count == 4)
                {
                    HexString = acts[2] + acts[3] + acts[0] + acts[1];
                }
                uint num = uint.Parse(HexString, System.Globalization.NumberStyles.AllowHexSpecifier);

                byte[] floatVals = BitConverter.GetBytes(num);
                float f = BitConverter.ToSingle(floatVals, 0);
                return f.ToString();
            }
            return ""; 
        }

        /// <summary>
        /// 读取变量返回16进制字符串
        /// </summary>
        /// <param name="Item">变量类</param>
        /// <returns>返回浮点型数值字符串</returns>
        public string ReadHexString(VarItem Item)
        {
            HslCommunication.OperateResult<ushort, ushort> result = GetAddressAndDataLenth(Item.RegisterStart.ToString(), Item.DataLenth.ToString());
            if (result.IsSuccess)
            {
                return MessageResultRecieved(modBusTcpClient.ReadRegister(result.Content1, (ushort)Item.DataLenth));
            }
            return "";
        }


        private string  MessageResultRecieved(HslCommunication.OperateResult<byte[]> result)
        {
            string HexString = "";
            if (result.IsSuccess)
            {
                HexString = HslCommunication.BasicFramework.SoftBasic.ByteToHexString(result.Content, ' ');
            }
            return HexString;
        }


        private HslCommunication.OperateResult<ushort, ushort> GetAddressAndDataLenth(string Start,string len)
        {
            HslCommunication.OperateResult<ushort, ushort> result = new HslCommunication.OperateResult<ushort, ushort>();
            try
            {
                result.Content1 = ushort.Parse(Start);
                result.Content2 = ushort.Parse(len);
                result.IsSuccess = true;
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return result;
        }

        //public Hashtable  ReadMuiltpleFloat(List<VarItem> items)
        //{
        //    Hashtable hash = new Hashtable();
        //    foreach(var item in items)
        //    {
        //        if (!hash.ContainsKey(item.RegisterStart)){
        //            hash.Add(item.RegisterStart,this.ReadFloat(item));
        //        }else
        //        {
        //            hash[item.RegisterStart] = this.ReadFloat(item);
        //        }
        //    }
        //    return hash;    
        //}
        public string[] ReadMuiltpleFloat(string[] RegisterStarts, string[] DataLenths)
        {
            string[] strs = new string[RegisterStarts.Length];
            for (int i = 0; i < RegisterStarts.Length; i++)
            {
                strs[i] = ReadFloat(RegisterStarts[i],DataLenths[i]);
            }
            return strs;
        }
        /// <summary>
        /// default  采用CDAB格式表示float
        /// </summary>
        /// <param name="result"></param>
        /// <returns>返回float型字符串</returns>
        private string ResultRecievedFloatForTaigu(HslCommunication.OperateResult<byte[]> result)
        {
            if (result.IsSuccess)
            {
                string HexString = HslCommunication.BasicFramework.SoftBasic.ByteToHexString(result.Content, ' ');
                //SysEventLog.SysEventLog.WriteLogToFile("16进制:" + HexString, AppDomain.CurrentDomain.BaseDirectory + @"\logs\Hslog" + DateTime.Now.ToString("yyyy-MM-dd") + ".log");
                List<string> acts = HexString.Split(' ').ToList();
                if (acts.Count == 4)
                {
                    HexString = acts[0] + acts[1];
                }
                uint num = uint.Parse(HexString, System.Globalization.NumberStyles.AllowHexSpecifier);

                //byte[] floatVals = BitConverter.GetBytes(num);
                //float f = BitConverter.ToSingle(floatVals, 0);
                return num.ToString();
            }
            return "";
        }
        public string ReadFloatForTaigu(string RegisterStart, string len)
        {
            HslCommunication.OperateResult<ushort, ushort> result = GetAddressAndDataLenth(RegisterStart, len);
            if (result.IsSuccess)
            {
                return ResultRecievedFloatForTaigu(modBusTcpClient.ReadRegister(result.Content1, 2));
            }
            return "";
        }
        /// <summary>
        /// 太古可乐读取float型变量
        /// </summary>
        /// <param name="Item">变量类</param>
        /// <returns>返回浮点型数值字符串</returns>
        public string ReadFloatForTaigu(VarItem Item)
        {
            return ReadFloatForTaigu(Item.RegisterStart.ToString(), Item.DataLenth.ToString());
        }
        /// <summary>
        /// 太古可乐读取 -4/3.2
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        //public Hashtable ReadMuiltpleFloatForTaigu(List<VarItem> items)
        //{
        //    Hashtable hash = new Hashtable();
        //    foreach (var item in items)
        //    {
        //        if (!hash.ContainsKey(item.RegisterStart))
        //        {
        //            hash.Add(item.RegisterStart, this.ReadFloatForTaigu(item));
        //        }
        //        else
        //        {
        //            hash[item.RegisterStart] = this.ReadFloatForTaigu(item);
        //        }
        //    }
        //    return hash;
        //}
        public string[] ReadMuiltpleFloatForTaigu(string[] RegisterStarts, string[] DataLenths)
        {
            string[] strs=new string[RegisterStarts.Length];
            for (int i = 0; i < RegisterStarts.Length; i++)
            {
                strs[i]= ReadFloatForTaigu(RegisterStarts[i],DataLenths[i]);
            }
            return strs;
        }
        public Hashtable ReadMuiltpleInt(List<VarItem> items)
        {
            Hashtable hash = new Hashtable();
            foreach (var item in items)
            {
                if (!hash.ContainsKey(item.RegisterStart))
                {
                    hash.Add(item.RegisterStart, this.ReadInt(item));
                }
                else
                {
                    hash[item.RegisterStart] = this.ReadInt(item);
                }
            }
            return hash;
        }

        public Hashtable ReadMuiltpleString(List<VarItem> items)
        {
            Hashtable hash = new Hashtable();
            foreach (var item in items)
            {
                if (!hash.ContainsKey(item.RegisterStart))
                {
                    hash.Add(item.RegisterStart, this.ReadString(item));
                }
                else
                {
                    hash[item.RegisterStart] = this.ReadString(item);
                }
            }
            return hash;
        }

处理时得到是共4位16进制的数据,需要对这4位数据进行转化才能得到真实的数据。上图列取了两种规则,不一一而表了。

得到数据后,再结合所使用的量纲以及上下限推算出真实的带量纲的值。

最后再拿该值与实际设备的量纲上下限进行线性对应,即可得到真实的设备的实际值。

猜你喜欢

转载自blog.csdn.net/miluli1/article/details/85322103