.NET的PLC帮助类

TCP和UDP协议:

TCP(传输控制协议)和UDP(用户数据报协议)是TCP/IP协议簇中的两种核心协议。它们在传输层上提供数据传输服务,但具有不同的特性和功能。

TCP协议是一种提供可靠、面向连接的字节流服务的传输协议。在数据传输前,发送方和接收方必须先建立TCP连接,然后才能进行数据传输。它通过超时重发、丢弃重复数据、数据检验等功能,确保数据能从一端传输到另一端。

UDP协议则是一种简单的面向数据报的传输层协议,它提供的是非面向连接、不可靠的数据流传输服务。由于UDP在传输数据报前不需要在客户和服务器之间建立连接,也没有超时重发等机制,因此其传输速度相对较快。但这也意味着它不能提供数据传输的可靠性保障。

总的来说,TCP和UDP各有其优点和使用场景。TCP主要应用于可靠性要求高的应用,如网页浏览、文件传输等;而UDP则更适合于可靠性要求低、对传输速度和经济性有一定需求的应用,如视频流、游戏等。

RS-232和RS-475通信接口标准及Modbus协议:

RS-232是一种常见的串行通信接口标准,由美国电子工业协会(EIA)联合贝尔系统公司、调制解调器厂家及计算机终端生产厂家于1970年共同制定。其全名为"数据终端设备(DTE)和数据通信设备(DCE)之间串行二进制数据交换接口技术标准"。它通常被应用于计算机、调制解调器和各种电子设备之间的通信连接。

RS-475是一种由美国电子工业协会(EIA)制定的半双工通信接口标准,它通常被应用于电子设备之间的数据传输。它采用平衡驱动和差分接收,因此具有较好的抗干扰能力,同时传输距离较远,可以达到数百米甚至千米级别。与RS-232不同的是,RS-475通常采用9针D型连接器,并且其引脚定义也与RS-232有所不同。RS-475主要用于工业、科学和医疗等领域的设备间通信,但由于其半双工的限制,应用场景不如RS-232和RS-485广泛。

Modbus是一种串行通信协议,最初由Modicon公司(现在的施耐德电气 Schneider Electric)于1979年开发,用于可编程逻辑控制器(PLC)之间的通信。此协议已经成为工业领域通信协议的业界标准,并且现在是工业电子设备之间常用的连接方式。西门子的S1200和S1500用的就是Modbus协议

Modbus协议定义了一个控制器能够识别的消息结构,不管它们是经过何种网络进行通信的。它描述了控制器请求访问其他设备的过程,如果回应来自其他设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。当在Modbus网络上通信时,此协议决定了每个控制器需要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制器将生成反馈信息并用Modbus协议发出。总的来说,Modbus是一种应用于电子控制器之间的通用语言,通过它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。

一、使用HslCommunication程序集,官网:胡工科技

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using HslCommunication.Profinet.Omron;
using HslCommunication.Profinet.Keyence;

namespace PLC.Class
{
    public class PLCHelper
    {
        #region 连接西门子PLC--SiemensS7Net
        /// <summary>
        /// 连接西门子PLC--SiemensS7Net
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <returns></returns>
        private bool ConnectSiemens(SiemensS7Net siemens, string ip, int port)
        {
            try
            {
                IPAddress ipaddress;
                bool flag = !IPAddress.TryParse(ip, out ipaddress);
                if (flag)
                {
                    return false;
                }
                else
                {
                    siemens.IpAddress = ip;
                    siemens.Port = port;
                    OperateResult operateResult = siemens.ConnectServer();
                    bool isSuccess = operateResult.IsSuccess;
                    if (isSuccess)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 给西门子PLC点位写信号
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="flag">给点位传入的值</param>
        /// <returns></returns>
        public bool WriteFlagBySiemens(SiemensS7Net siemens, string ip, int port, string point, short flag)
        {
            if (ConnectSiemens(siemens, ip, port))
            {
                OperateResult result = siemens.Write(point, flag);
                siemens.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 读取西门子PLC的状态
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <returns></returns>
        public bool ReadBoolBySiemens(SiemensS7Net siemens, string ip, int port, string point)
        {
            if (ConnectSiemens(siemens, ip, port))
            {
                OperateResult<bool> value = siemens.ReadBool(point);
                siemens.ConnectClose();
                return value.Content;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 读取西门子PLC的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="length">读取长度</param>
        /// <returns></returns>
        public string ReadStringBySiemens(SiemensS7Net siemens, string ip, int port, string point, ushort length)
        {
            if (ConnectSiemens(siemens, ip, port))
            {
                OperateResult<string> result = new OperateResult<string>();
                result = siemens.ReadString(point, length);
                string source = string.Empty;

                if (!string.IsNullOrEmpty(result.Content))
                {
                    source = result.Content;
                }
                else
                {
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(10);
                        result = siemens.ReadString(point, length);
                        if (!string.IsNullOrEmpty(result.Content))
                        {
                            source = result.Content;
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(result.Content))
                    {
                        return "未读取到PLC信息";
                    }
                }
                siemens.ConnectClose();
                return source;
            }
            else
            {
                return "false";
            }
        }

        /// <summary>
        /// 清空西门子PLC点位中的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="point"></param>
        /// <param name="length">写入的长度</param>
        /// <returns></returns>
        public bool ClearPlcPocketBySiemens(SiemensS7Net siemens, string ip, int port, string point, int length, string flag = " ")
        {
            if (ConnectSiemens(siemens, ip, port))
            {
                OperateResult result = siemens.Write(point, flag, length);
                siemens.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 连接欧姆龙PLC--OmronFinsNet
        /// <summary>
        /// 连接欧姆龙PLC--OmronFinsNet
        /// </summary>
        /// <param name="omron"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        private bool ConnectOmron(OmronFinsNet omron, string ip, int port)
        {
            //OmronFinsUdp
            try
            {
                IPAddress ipaddress;
                bool flag = !IPAddress.TryParse(ip, out ipaddress);
                if (flag)
                {
                    return false;
                }
                else
                {
                    omron.IpAddress = ip;
                    omron.Port = port;
                    omron.SA1 = 239;
                    //if (ip240.Contains(ip))
                    //{
                    //    omron.SA1 = 240;
                    //}
                    //else
                    //{
                    //    omron.SA1 = 239;
                    //}
                    //omron.DA1 = 24;
                    OperateResult operateResult = omron.ConnectServer();
                    if (!operateResult.IsSuccess)
                    {
                        for (int i = 0;i < 3;i++)
                        {
                            operateResult = omron.ConnectServer();
                            if (operateResult.IsSuccess)
                            {
                                break;
                                //return true;
                            }
                        }
                        //SA1使用239连接不上,则采取240连接
                        if (!operateResult.IsSuccess)
                        {
                            omron.SA1 = 240;
                            for (int i = 0; i < 3; i++)
                            {
                                operateResult = omron.ConnectServer();
                                if (operateResult.IsSuccess)
                                {
                                    break;
                                    //return true;
                                }
                            }
                        }
                        //if (!isSuccess)
                        //{
                        //    return false;
                        //}
                    }
                    return operateResult.IsSuccess;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 给欧姆龙PLC点位写信号
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="flag">给点位传入的值</param>
        /// <returns></returns>
        public bool WriteShortByOmron(OmronFinsNet omron, string ip, int port, string point, short flag)
        {
            //if (ConnectOmron(omron, ip, port))
            //{
            OperateResult result = omron.Write(point, flag);
            if (!result.IsSuccess)
            {
                for (int i = 0;i < 3;i++)
                {
                    result = omron.Write(point,flag);
                    if (result.IsSuccess)
                    {
                        break;
                        //return true;
                    }
                }
                //if (!result.IsSuccess)
                //{
                //    return false;
                //}
            }
            //omron.ConnectClose();
            return result.IsSuccess;
            //}
            //else
            //{
            //    return false;
            //}
        }

        //写入float值
        public bool WriteFloatByOmron(OmronFinsNet omron, string ip, int port, string point, float flag)
        {
            //if (ConnectOmron(omron, ip, port))
            //{
            OperateResult result = omron.Write(point, flag);
            if (!result.IsSuccess)
            {
                for (int i = 0; i < 3; i++)
                {
                    result = omron.Write(point, flag);
                    if (result.IsSuccess)
                    {
                        break;
                        //return true;
                    }
                }
                //if (!result.IsSuccess)
                //{
                //    return false;
                //}
            }
            //omron.ConnectClose();
            return result.IsSuccess;
            //}
            //else
            //{
            //    return false;
            //}
        }

        public string WritePointByOmron(OmronFinsNet omron, string ip, int port, List<string> pointlst, List<string> dataTypelst, List<string> valuelst,string type,List<string> filedlst)
        {
            //int sucNum = 0;
            string errorFileds = "";
            try
            {
                if (type == "EDIT")
                {
                    //return 0;
                    return "";
                }
                //调用时以下6个点位不写入
                List<string> addNotWritePoint = new List<string>() { "D200", "D202", "D210", "D212", "D0", "D469" };
                if (ConnectOmron(omron, ip, port))
                {
                    for (int i = 0; i < pointlst.Count; i++)
                    {
                        if (addNotWritePoint.Contains(pointlst[i]))
                        {
                            continue;
                        }

                        if (dataTypelst[i] == "FLOAT" && !string.IsNullOrEmpty(valuelst[i]))
                        {
                            float flag = Convert.ToSingle(valuelst[i]);
                            bool result = WriteFloatByOmron(omron, ip, port, pointlst[i], flag);
                            if (result)
                            {
                                //sucNum++;
                            }
                            else
                            {
                                if (errorFileds.Length > 0)
                                {
                                    errorFileds += ",";
                                }
                                errorFileds += filedlst[i];
                                LogHelper.WriteErrLog($"IP:{ip},端口:{port},点位:{pointlst[i]},值:{valuelst[i]}写入失败!");
                            }
                        }
                        else if (dataTypelst[i] == "SHORT" && !string.IsNullOrEmpty(valuelst[i]))
                        {
                            short flag = Convert.ToInt16(valuelst[i]);
                            bool result = WriteShortByOmron(omron, ip, port, pointlst[i], flag);
                            if (result)
                            {
                                //sucNum++;
                            }
                            else
                            {
                                if (errorFileds.Length > 0)
                                {
                                    errorFileds += ",";
                                }
                                errorFileds += filedlst[i];
                                LogHelper.WriteErrLog($"IP:{ip},端口:{port},点位:{pointlst[i]},值:{valuelst[i]}写入失败!");
                            }
                        }
                    }
                    //return sucNum;
                }
                //else
                //{
                //    return sucNum;
                //}
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex.ToString());
            }
            finally
            {
                omron.ConnectClose();
            }
            //return sucNum;
            return errorFileds;
        }

        /// <summary>
        /// 读取欧姆龙PLC的状态
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <returns></returns>
        public bool ReadBoolByOmron1(OmronFinsNet omron, string ip, int port, string point)
        {
            if (ConnectOmron(omron, ip, port))
            {
                OperateResult<bool> value = omron.ReadBool(point);
                omron.ConnectClose();
                return value.Content;
            }
            else
            {
                return false;
            }
        }

        //读取float型数据
        public float ReadFloatByOmron(OmronFinsNet omron, string ip, int port, string point)
        {
            //if (ConnectOmron(omron, ip, port))
            //{
            OperateResult<float> value = omron.ReadFloat(point);
            if (!value.IsSuccess)
            {
                for (int i = 0;i < 3;i++)
                {
                    value = omron.ReadFloat(point);
                    if (value.IsSuccess)
                    {
                        break;
                        //return value.Content;
                    }
                }
                //if (!value.IsSuccess)
                //{
                //    return 0;
                //}
            }
            //omron.ConnectClose();
            if (value.IsSuccess)
            {
                return value.Content;
            }
            else
            {
                return 0;
            }
            //}
            //else
            //{
            //    return 0;
            //}
        }

        //读取short型数据
        public short ReadShortByOmron(OmronFinsNet omron, string ip, int port, string point)
        {
            //if (ConnectOmron(omron, ip, port))
            //{
            OperateResult<short> value = omron.ReadInt16(point);
            if (!value.IsSuccess)
            {
                for (int i = 0; i < 3; i++)
                {
                    value = omron.ReadInt16(point);
                    if (value.IsSuccess)
                    {
                        break;
                        //return value.Content;
                    }
                }
                //if (!value.IsSuccess)
                //{
                //    return 0;
                //}
            }
            //omron.ConnectClose();
            if (value.IsSuccess)
            {
                return value.Content;
            }
            else
            {
                return 0;
            }
            //}
            //else
            //{
            //    return 0;
            //}
        }

        //读取Bool类型数据
        public bool ReadBoolByOmron(OmronFinsNet omron, string ip, int port, string point)
        {
            OperateResult<bool> value = omron.ReadBool(point);
            if (!value.IsSuccess)
            {
                for (int i = 0; i < 3; i++)
                {
                    value = omron.ReadBool(point);
                    if (value.IsSuccess)
                    {
                        break;
                    }
                }
            }
            if (value.IsSuccess)
            {
                return value.Content;
            }
            else
            {
                return false;
            }
        }

        public string ReadPointByOmron(OmronFinsNet omron, string ip, int port, List<string> filedlst, List<string> pointlst, List<string> datatypelst)
        {
            string result = "0";
            JObject jObj = new JObject();

            try
            {
                if (ConnectOmron(omron, ip, port))
                {
                    for (int i = 0; i < pointlst.Count; i++)
                    {
                        if (datatypelst[i] == "FLOAT")
                        {
                            result = ReadFloatByOmron(omron, ip, port, pointlst[i]).ToString();
                        }
                        else if (datatypelst[i] == "SHORT")
                        {
                            result = ReadShortByOmron(omron, ip, port, pointlst[i]).ToString();
                        }
                        else if (datatypelst[i] == "BOOL" && pointlst[i] == "H10")
                        {
                            //涂布单双面3个点位细分---00:单面,01:双面,01;02:连续
                            bool res = false;
                            List<string> H10s = new List<string>() { "H10.00", "H10.01", "H10.02" };
                            foreach (string h10 in H10s)
                            {
                                res = ReadBoolByOmron(omron, ip, port, h10);
                                if (res)
                                {
                                    result = h10.Substring(h10.Length - 1,1);
                                    break;
                                }
                            }
                        }

                        jObj.Add(new JProperty(filedlst[i], result));
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex.ToString());
            }
            finally
            {
                omron.ConnectClose();
            }
            
            return jObj.ToString();
        }

        /// <summary>
        /// 读取欧姆龙PLC的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="length">读取长度</param>
        /// <returns></returns>
        public string ReadStringByOmron(OmronFinsNet omron, string ip, int port, string point, ushort length)
        {
            if (ConnectOmron(omron, ip, port))
            {
                OperateResult<string> result = new OperateResult<string>();
                result = omron.ReadString(point, length);
                string source = string.Empty;

                if (!string.IsNullOrEmpty(result.Content))
                {
                    source = result.Content;
                }
                else
                {
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(10);
                        result = omron.ReadString(point, length);
                        if (!string.IsNullOrEmpty(result.Content))
                        {
                            source = result.Content;
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(result.Content))
                    {
                        return "未读取到PLC信息";
                    }
                }
                omron.ConnectClose();
                return source;
            }
            else
            {
                return "false";
            }
        }

        /// <summary>
        /// 清空欧姆龙PLC点位中的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="point"></param>
        /// <param name="length">写入的长度</param>
        /// <returns></returns>
        public bool ClearPlcPocketByOmron(OmronFinsNet omron, string ip, int port, string point, int length, string flag = " ")
        {
            if (ConnectOmron(omron, ip, port))
            {
                OperateResult result = omron.Write(point, flag, length);
                omron.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region  连接基恩士PLC--KeyenceMcNet
        /// <summary>
        /// 连接基恩士PLC--KeyenceMcNet
        /// </summary>
        /// <param name="omron"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        private bool ConnectKeyence(KeyenceMcNet keyence, string ip, int port)
        {
            try
            {
                IPAddress ipaddress;
                bool flag = !IPAddress.TryParse(ip, out ipaddress);
                if (flag)
                {
                    return false;
                }
                else
                {
                    keyence.IpAddress = ip;
                    keyence.Port = port;
                    OperateResult operateResult = keyence.ConnectServer();
                    bool isSuccess = operateResult.IsSuccess;
                    if (isSuccess)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 给基恩士PLC点位写信号
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="flag">给点位传入的值</param>
        /// <returns></returns>
        public bool WriteFlagByKeyence(KeyenceMcNet keyence, string ip, int port, string point, short flag)
        {
            if (ConnectKeyence(keyence, ip, port))
            {
                OperateResult result = keyence.Write(point, flag);
                keyence.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 读取基恩士PLC的状态
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <returns></returns>
        public bool ReadBoolByKeyence(KeyenceMcNet keyence, string ip, int port, string point)
        {
            if (ConnectKeyence(keyence, ip, port))
            {
                OperateResult<bool> value = keyence.ReadBool(point);
                keyence.ConnectClose();
                return value.Content;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 读取基恩士PLC的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="length">读取长度</param>
        /// <returns></returns>
        public string ReadStringByKeyence(KeyenceMcNet keyence, string ip, int port, string point, ushort length)
        {
            if (ConnectKeyence(keyence, ip, port))
            {
                OperateResult<string> result = new OperateResult<string>();
                result = keyence.ReadString(point, length);
                string source = string.Empty;

                if (!string.IsNullOrEmpty(result.Content))
                {
                    source = result.Content;
                }
                else
                {
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(10);
                        result = keyence.ReadString(point, length);
                        if (!string.IsNullOrEmpty(result.Content))
                        {
                            source = result.Content;
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(result.Content))
                    {
                        return "未读取到PLC信息";
                    }
                }
                keyence.ConnectClose();
                return source;
            }
            else
            {
                return "false";
            }
        }

        /// <summary>
        /// 清空基恩士PLC点位中的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="point"></param>
        /// <param name="length">写入的长度</param>
        /// <returns></returns>
        public bool ClearPlcPocketByKeyence(KeyenceMcNet keyence, string ip, int port, string point, int length, string flag = " ")
        {
            if (ConnectKeyence(keyence, ip, port))
            {
                OperateResult result = keyence.Write(point, flag, length);
                keyence.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }
        #endregion
    }
}
相关推荐
九鼎科技-Leo2 小时前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
九鼎科技-Leo4 小时前
什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
windows·后端·c#·asp.net·mvc·.net
.net开发4 小时前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
九鼎科技-Leo8 小时前
在 C# 中,ICollection 和 IList 接口有什么区别?
windows·c#·.net
时光追逐者9 小时前
C#/.NET/.NET Core学习路线集合,学习不迷路!
开发语言·学习·c#·asp.net·.net·.netcore·微软技术
Crazy Struggle12 小时前
.NET 全功能流媒体管理控制接口平台
.net·开源项目·流媒体
.net开发12 小时前
WPF使用prism框架发布订阅实现消息提示
c#·.net·wpf
慧都小妮子16 小时前
FastReport将停止 .NET Framework 上的 WebReport 更新
.net·报表控件·fastreport
九鼎科技-Leo21 小时前
在 C# 中,如何实现观察者模式?
观察者模式·c#·.net