Introducción al desarrollo de PLC con .NET

¿Qué es PLC?

El Controlador Lógico Programable (PLC) es un dispositivo electrónico digital con un microprocesador. Es un controlador lógico digital utilizado para el control automatizado. Puede cargar instrucciones de control en la memoria en cualquier momento para su almacenamiento y operación. El controlador programable está compuesto modularmente por CPU interna, memoria de instrucciones y datos, unidades de entrada y salida, módulos de potencia, simulación digital y otras unidades. El PLC puede recibir (entrada) y enviar (salida) muchos tipos de señales eléctricas o electrónicas y utilizarlas para controlar o supervisar casi todo tipo de sistemas mecánicos y eléctricos.
Insertar descripción de la imagen aquí

Uso de .NET para el desarrollo de PLC

Utilice el proyecto VS, agregue la biblioteca dinámica S7.net al proyecto y
lea el número de bloque DB + dirección requeridos en el programa. Los métodos de escritura son los siguientes:

DB1.DBW0 //地址为0,类型为整数

DB1.STRING2.18 //地址为2,字符长度18 类型为字符串

DB1.B22 //地址为22,类型为字节型

DB1.DBD24 //地址为24,类型为实数

DB1.DBW28 //地址为28,类型为整数

DB1.DBW28 //地址为28,类型为整数

DB1.DBX29.0 //地址为29.0,类型为布尔

Ejemplo de código:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Text.RegularExpressions;

using System.Windows.Forms;

using S7.Net;

namespace WindowsFormsApp1

{
    
    

    public partial class Form1 : Form

    {
    
    

        public Form1()

        {
    
    

            InitializeComponent();

        }
 

        Plc S71500;

        /// <summary>

        /// 连接PLC

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void button1_Click(object sender, EventArgs e)

        {
    
    

            string ip = tb_plcip.Text.Trim(); //PLC地址IP 例192.168.0.1

            short rack = short.Parse(tb_rack.Text.Trim()); //PLC机架位置 默认0

            short solt = short.Parse(tb_solt.Text.Trim()); //PLC插槽位置,以实际为准

            //CpuType根据实际PLC连接,我这边已1500PLC为例

            S71500 = new Plc(CpuType.S71500, ip, rack, solt);

            //调用S7.NET中的方法连接PLC

            S71500.Open();

            //连接成功后使能操作按钮

            if (S71500.IsConnected)

            {
    
    

                //判断是否连接成功

                MessageBox.Show("连接PLC成功");

            }

        }

        //****

        //读取 ReadPLC("DB1.DBW0");

        //写入 WritePLC("DB1.DBW0","1");

        //其中BOOL写入: WritePLC(DB1.DBX29.0, "False");或WritePLC(DB1.DBX29.0, "True");

        #region 读写TAG点方法

         /// <summary>

        /// 写入PLC数值

        /// </summary>

        /// <param name="DataTag"></param>

        public void WritePLC(string DataTag, string Data)

        {
    
    

            try

            {
    
    

                #region 逻辑处理

                string Type = "STRING";

                if (DataTag.Contains("STRING"))

                {
    
    

                    Type = "STRING";

                }

                else if (DataTag.Contains("DBW"))

                {
    
    

                    Type = "Word";

                }

                else if (DataTag.Contains(".B"))

                {
    
    

                    Type = "Byte";

                }

                else if (DataTag.Contains("DBD"))

                {
    
    

                    Type = "Real";

                }

                else if (DataTag.Contains("DBX"))

                {
    
    

                    Type = "Bool";

                }

                int strAdr = 0;

                //取到db块号

                int dbInt = dbInt = int.Parse(MidStrEx(DataTag, "DB", ".")); ;

                //字符串类型

                if (Type == "STRING")

                {
    
    

                    //取到地址

                    strAdr = int.Parse(MidStrEx(DataTag, "STRING", "."));

                    //写入PLC数据

                    S71500.Write(DataType.DataBlock, dbInt, strAdr, GetPLCStringByteArray(Data));

                }

                else if (Type == "Word")

                {
    
    

                    //写入整数型

                    strAdr = int.Parse(Regex.Match(DataTag, @"\d+$").ToString());

                    S71500.Write(DataType.DataBlock, dbInt, strAdr, Convert.ToInt16(Data));

                }

                else if (Type == "Byte")

                {
    
    

                    //写入字节型

                    strAdr = int.Parse(Regex.Match(DataTag, @"\d+$").ToString());

                    S71500.Write(DataType.DataBlock, dbInt, strAdr, Convert.ToByte(Data));

                }

                else if (Type == "Real")

                {
    
    

                    //写入实数

                    strAdr = int.Parse(Regex.Match(DataTag, @"\d+$").ToString());

                    S71500.Write(DataType.DataBlock, dbInt, strAdr, Convert.ToDouble(Data));

                }

                else if (Type == "Bool")

                {
    
    

                    //写入Bool值

                    S71500.Write(DataTag.ToUpper(), Convert.ToBoolean(Data));

                }

                #endregion

            }

            catch (Exception ex)

            {
    
    

                //写入异常

            }

        }

        int errorCount = 0;

        /// <summary>

        /// 读取PLC数据

        /// </summary>

        /// <param name="DataTag">Tag点名称</param>

        public string ReadPLC(string DataTag)

        {
    
    

            string returnData = "";

            try

            {
    
    

                if (DataTag.Contains("STRING"))

                {
    
    

                    //取到DB块号

                    int dbInt = dbInt = int.Parse(MidStrEx(DataTag, "DB", "."));

                    //取到偏移量地址

                    int strAdr = int.Parse(MidStrEx(DataTag, "STRING", "."));

                    //获取字符串长度

                    var reservedLength = (byte)S71500.Read(DataType.DataBlock, dbInt, strAdr, VarType.Byte, 1);

                    //读取时在地址前加两位偏移

                    string StrReplac = (string)S71500.Read(DataType.DataBlock, dbInt, strAdr + 2, VarType.String, reservedLength);

                    //去除字符串后面空白符号

                    returnData = StrReplac.Replace("\0", "");

                }

                else if (DataTag.Contains("DBW"))

                {
    
    

                    //读取整数型数据

                    ushort UpValue = (ushort)S71500.Read(DataTag);

                    returnData = Convert.ToString(UpValue);

                }

                else if (DataTag.Contains(".B"))

                {
    
    

                    //取到DB块号

                    int dbInt = dbInt = int.Parse(MidStrEx(DataTag, "DB", "."));

                    //取到偏移量地址

                    int strAdr = int.Parse(Regex.Match(DataTag, @"\d+$").ToString());

                    //获取字符串长度

                    var reservedLength = (byte)S71500.Read(DataType.DataBlock, dbInt, strAdr, VarType.Byte, 1);

                    //将读取数据转为字符串

                    returnData = Convert.ToString(reservedLength);

                }

                else if (DataTag.Contains("DBD"))

                {
    
    

                    //读取小数型数据

                    double UpValue = ((uint)S71500.Read(DataTag)).ConvertToFloat();

                    if (Convert.ToString(UpValue).Trim() != "")

                    {
    
    

                        //截取保留小数位长度

                        returnData = Math.Round(UpValue, 3).ToString();

                    }

                }

                else if (DataTag.Contains("DBX"))

                {
    
    

                    //读取Bool值数据

                    var db1Bool1 = S71500.Read(DataTag);

                    returnData = db1Bool1.ToString();

                }

            }

            catch (Exception ex)

            {
    
    

                //读取异常

            }

            return returnData;

        }

        /// <summary>

        /// 获取西门子PLC字符串数组--String

        /// </summary>

        /// <param name="str"></param>

        /// <returns></returns>

        private byte[] GetPLCStringByteArray(string str)

        {
    
    

            byte[] value = Encoding.Default.GetBytes(str);

            byte[] head = new byte[2];

            head[0] = Convert.ToByte(254);

            head[1] = Convert.ToByte(str.Length);

            value = head.Concat(value).ToArray();

            return value;

        }

        /// <summary>

        /// 获取西门子PLC字符串数组--WString

        /// </summary>

        /// <param name="str"></param>

        /// <returns></returns>

        private byte[] GetPLCWStringByteArray(string str)

        {
    
    

            byte[] value = Encoding.BigEndianUnicode.GetBytes(str);

            byte[] head = BitConverter.GetBytes((short)508);

            byte[] length = BitConverter.GetBytes((short)str.Length);

            Array.Reverse(head);

            Array.Reverse(length);

            head = head.Concat(length).ToArray();

            value = head.Concat(value).ToArray();

            return value;

        }

        /// <summary>

        /// 去指定字符串中间字符

        /// </summary>

        /// <param name="sourse">字符串</param>

        /// <param name="startstr">首字符</param>

        /// <param name="endstr">尾字符</param>

        /// <returns></returns>

        public static string MidStrEx(string sourse, string startstr, string endstr)

        {
    
    

            string result = string.Empty;

            int startindex, endindex;

            try

            {
    
    

                startindex = sourse.IndexOf(startstr);

                if (startindex == -1)

                {
    
    

                    return result;

                }

                string tmpstr = sourse.Substring(startindex + startstr.Length);

                endindex = tmpstr.IndexOf(endstr);

                if (endindex == -1)

                {
    
    

                    return result;

                }

                result = tmpstr.Remove(endindex);

            }

            catch (Exception)

            {
    
    

            }

            return result;

        }



        #endregion

    }

}

Supongo que te gusta

Origin blog.csdn.net/ChengR666/article/details/128409011
Recomendado
Clasificación