s7.net 读写西门子PLC


using S7.Net;
using System.Text.RegularExpressions;
using static xxxx.Enums.EnumType;

namespace Camera3D.Helper.PLC
{
    public class SIEMENS_PLCHelper
    {
        /// <summary>
        /// 
        /// </summary>
        public static SIEMENS_PLCHelper? Instance;
        // private MitsubishiClient? client;
        private Plc plc;
        /// <summary>
        /// 实例
        /// </summary>
        /// <returns></returns>
        public static SIEMENS_PLCHelper GetInstance()
        {
            if (Instance == null)
            {
                Instance = new SIEMENS_PLCHelper();
            }
            return Instance;
        }
        /// <summary>
        /// 连接PLC
        /// </summary>
        /// <returns></returns>
        public bool Connected()
        {
            //  Log.Logger.Debug($"PLC Connected = {client.Connected}");
            return plc.IsConnected;//.Connected;
        }

        /// <summary>
        /// 连接PLC
        /// </summary>
        /// <returns></returns>
        public void ConnectToPlc()
        {
            //SystemParams.PLC.SIEMENS_IP
            string PLCIP = SystemParams.PLC.SIEMENS_IP;// AppSettingsHelper.Configuration["PLC:IP"];
            bool isIPOK = xxxx.Utils.Utils.IsIpAddressValid(PLCIP);
            if (isIPOK)
            {
                plc = new Plc(CpuType.S71500, PLCIP, 0, 1);

                try
                {
                    plc.Open();

                    string jsonLog = JsonConvert.SerializeObject(new
                    {
                        Msg = $"PLC 连接 {PLCIP} {(Connected() ? "成功" : "失败")}",
                        IP = SystemParams.PLC.SIEMENS_IP,
                        Port = SystemParams.PLC.SIEMENS_Port,
                        Connected = plc.IsConnected
                   
                    });
                    if (Connected())
                    {
                        Log.Logger.Debug($"{jsonLog}");
                    }
                    else
                    {
                        Log.Logger.Error($"{jsonLog}");
                    }
                }
                catch (Exception ex)
                {
                    Log.Logger.Error($"{ex.Message}");
                }
            }
            else
            {
                Log.Logger.Error($"PLC IP =[{PLCIP}] 不合法");
            }
        }
  
        public async Task< string> PLCRead(string ValueType, string TagName, byte bitAdr = 0,int StrLength=1)
        {
            var TagNameResult = ParseDbAddress(TagName);

            //if (plc == null || !IsConnected)
            //{
            //    Connect();
            //}

            string Result = "";
            switch (ValueType.ToUpper())
            {
                case "BOOL":
                    Result = ((bool)plc.Read(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, VarType.Bit, 1, bitAdr)).ToString();
                    break;
                //case "BYTE":
                //    Result = ((byte)plc.Read(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, VarType.Byte, 1)).ToString();
                //    break;
                case "INT16":
                    Result = (plc.Read(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, VarType.Int, 1)).ToString();
                    break;
                case "INT32":
                    Result = ((Int32)plc.Read(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, VarType.DInt, 1)).ToString();
                    break;
                case "REAL":
                    Result = ((double)plc.Read(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, VarType.Real, 1)).ToString();
                    break;
                case "DOUBLE":
                    Result = ((double)plc.Read(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, VarType.LReal, 1)).ToString();
                    break;
                case "STRING":
                    //Result = (string)plc.Read(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset + 2, VarType.String, StrLength);

                     先读取前2字节获取元数据
                    byte[] header = plc.ReadBytes(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, 2);
                    int maxLength = header[0];
                    int currentLength = header[1];
                    // 读取完整字符串内容
                    byte[] buffer = plc.ReadBytes(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset + 2, currentLength);
                    Result = Encoding.ASCII.GetString(buffer);

                    break;
            } 

            return Result;
        }

        public async Task<PLCRWResult> PLCWrite(string ValueType, string TagName, string value)
        {
            //if (plc == null || !IsConnected)
            //{
            //    Connect();
            //}
            PLCRWResult Result = xxxx.Enums.EnumType.PLCRWResult.Empty;
            var TagNameResult = ParseDbAddress(TagName);
            await Task.Delay(1);
            // string Result = "";
            try
            {
                switch (ValueType.ToUpper())
                {
                    case "BOOL":
                        plc.Write(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, bool.Parse(value));
                        break;
                    //case "BYTE":
                    //    plc.Write(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, bitAdr);
                    //    break;
                    case "INT16":
                        plc.Write(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, short.Parse(value));
                        break;
                    case "INt32":
                        plc.Write(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, int.Parse(value));
                        break;
                    case "REAL":

                        plc.Write(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, float.Parse(value));
                        break;
                    case "DOUBLE":

                        plc.Write(S7.Net.DataType.DataBlock, TagNameResult.DbNumber, TagNameResult.Offset, double.Parse(value));
                        break;
                }
                Result = xxxx.Enums.EnumType.PLCRWResult.OK;
            }
            catch (Exception ex)
            {
                Log.Logger.Error($" PLC 写入 ValueType = {ValueType} 异常 TagName = {TagName} {ex.Message}");
                Result = xxxx.Enums.EnumType.PLCRWResult.Error;
            }

            return Result;
        } 

        /// <summary>
        /// 解析 DB 地址格式(支持 DBXXXX.Y.Z 或 DBXXXX.Y)
        /// </summary>
        public static (int DbNumber, int Offset) ParseDbAddress(string address)
        {
            // 正则匹配:DB开头 + 数字 + . + 数字 + . + 数字
            var match = Regex.Match(
                address,
                @"^DB(\d+)\.(\d+)(?:\.\d+)?$",
                RegexOptions.IgnoreCase
            );

            if (!match.Success)
                throw new ArgumentException("无效的地址格式: " + address);

            // 提取数值
            if (!int.TryParse(match.Groups[1].Value, out int dbNumber))
                throw new ArgumentException("无效的DB编号: " + match.Groups[1].Value);

            if (!int.TryParse(match.Groups[2].Value, out int offset))
                throw new ArgumentException("无效的偏移量: " + match.Groups[2].Value);

            return (dbNumber, offset);
        } 
    }

}
示例
TagName ="DB400.0.0" 由于电气工程师只给这个格式,所以
result = await SIEMENS_PLCHelper.GetInstance().PLCRead("STRING",TagName,0,Length);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值