.NET PLC helper class

 TCP and UDP protocols:

        TCP (Transmission Control Protocol) and UDP (User Datagram Protocol) are the two core protocols in the TCP/IP protocol suite. They provide data transfer services on the transport layer but have different features and functionality.

        The TCP protocol is a transport protocol that provides reliable, connection-oriented byte stream services. Before data transmission, the sender and receiver must establish a TCP connection before data transmission can occur. It ensures that data can be transmitted from one end to the other through functions such as timeout retransmission, discarding duplicate data, and data verification.

        The UDP protocol is a simple datagram-oriented transport layer protocol. It provides non-connection-oriented and unreliable data stream transmission services. Since UDP does not need to establish a connection between the client and the server before transmitting datagrams, and does not have mechanisms such as timeout retransmission, its transmission speed is relatively fast. But this also means that it cannot provide reliability guarantee of data transmission.

        In general, TCP and UDP each have their own advantages and usage scenarios. TCP is mainly used in applications with high reliability requirements, such as web browsing, file transfer, etc.; while UDP is more suitable for applications with low reliability requirements and certain requirements for transmission speed and economy, such as video streaming, games, etc.

RS-232 and RS-475 communication interface standards and Modbus protocol:

        RS-232 is a common serial communication interface standard that was jointly developed in 1970 by the Electronic Industries Association (EIA), Bell Systems, modem manufacturers, and computer terminal manufacturers. Its full name is "Technical Standard for Serial Binary Data Exchange Interface between Data Terminal Equipment (DTE) and Data Communications Equipment (DCE)". It is commonly used in communication connections between computers, modems, and various electronic devices.

        RS-475 is a half-duplex communication interface standard developed by the Electronic Industries Association (EIA). It is usually used for data transmission between electronic devices. It uses balanced drive and differential reception, so it has better anti-interference capabilities and has a long transmission distance, which can reach hundreds of meters or even kilometers. Unlike RS-232, RS-475 usually uses a 9-pin D-type connector, and its pin definitions are also different from RS-232. RS-475 is mainly used for communication between devices in industrial, scientific, and medical fields. However, due to its half-duplex limitation, its application scenarios are not as extensive as RS-232 and RS-485.

        Modbus is a serial communication protocol originally developed by Modicon Corporation (now Schneider Electric) in 1979 for communication between programmable logic controllers (PLCs). This protocol has become the industry standard for communication protocols in the industrial field and is now a commonly used connection method between industrial electronic equipment. Siemens' S1200 and S1500 use the Modbus protocol

        The Modbus protocol defines a message structure that controllers can understand regardless of the network over which they communicate. It describes the process by which the controller requests access to other devices, how it responds to requests from other devices, and how errors are detected and logged. It establishes a common format for message domain layout and content. When communicating on a Modbus network, this protocol determines that each controller needs to know their device address, recognize messages sent by the address, and decide what actions to take. If a response is required, the controller will generate feedback information and send it using the Modbus protocol. In general, Modbus is a universal language used between electronic controllers. Through it, control equipment produced by different manufacturers can be connected into an industrial network for centralized monitoring.

1. Use HslCommunication assembly, official website: Hu Gong Technology .

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
    }
}

Guess you like

Origin blog.csdn.net/weixin_50478033/article/details/133141855