Introduction to PLC development with .NET

What is PLC?

Programmable Logic Controller (PLC) is a digital electronic device with a microprocessor. It is a digital logic controller used for automated control. It can load control instructions into the memory at any time for storage and operation. The programmable controller is modularly composed of internal CPU, instruction and data memory, input and output units, power modules, digital simulation and other units. PLC can receive (input) and send (output) many types of electrical or electronic signals and use them to control or supervise almost all kinds of mechanical and electrical systems.
Insert image description here

Using .NET for PLC development

Use the VS project, add the S7.net dynamic library to the project, and
read the required DB block number + address in the program. The writing methods are as follows:

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,类型为布尔

Code example:

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

    }

}

Guess you like

Origin blog.csdn.net/ChengR666/article/details/128409011