C# 使用S7netplus读取西门子PLC的DB块-S7协议

发布于:2024-10-15 ⋅ 阅读:(56) ⋅ 点赞:(0)

在工业的设备监控领域,S7协议使用比较普遍下面简单教大家使用

1、添加包

2、添加帮助类(读写数据就研究该类即可,具体的理论就不多说了)

//plc中类型与c#类型 bool => Bit
//Byte => byte
//word => ushort
//DWord => uint
//Int => short
//DInt => int
//Real => float
//LReal => double
//String => string
//DateTimeLong=>datetime
//s7wstring=>string
//ReadTimeout,WriteTimeout,分别为读取和写入等待时间
/// <summary>
/// plc帮助类
/// </summary>
public class PlcHelper
{
    /// <summary>
    /// 是否连接
    /// </summary>
    /// <returns></returns>
    public bool IsConnected(Plc Plc)
    {
        if (Plc.IsConnected) { return true; }
        else return false;
    }
    /// <summary>
    /// 连接plc   
    /// </summary>
    /// <param name="cpuType">cpu型号</param>
    /// <param name="ip">plc的ip地址</param>
    /// <param name="rack">机架号</param>
    /// <param name="slot">插槽号</param>
    /// <returns>是否成功</returns>
    /// 默认值填充  在1200中机架号,插槽号通常为0和1。可根据实际情况赋值
    public Plc OpenPlc(Plc Plc, CpuType cpuType = CpuType.S71200, string ip = "127.0.0.1", short rack = 0, short slot = 1)
    {
        Plc = new Plc(cpuType, ip, rack, slot);
        Plc.Open();
        if (Plc.IsConnected) return Plc;
        else return null;
    }
    /// <summary>
    /// 关闭plc连接
    /// </summary>
    /// <param name="plc">引用的plc实例</param>
    public void ClosePlc(Plc plc)
    {
        plc.Close();
    }

    /// <summary>
    /// 读取bool类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public bool ReadBool(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Bit, 1);
        return (bool)result;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="Plc"></param>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="count">位偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public bool ReadBoolByte(Plc Plc, int dbBlock, int startByteAdr, byte count, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Bit, 1, count);
        return (bool)result;
    }
    /// <summary>
    /// 写入bool类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteBool(Plc Plc, int dbBlock, int startByteAdr, bool Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取int类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public short ReadInt(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Int, 1);
        return (short)result;
    }
    /// <summary>
    /// 写入int类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteInt(Plc Plc, int dbBlock, int startByteAdr, short Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取Dint类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public int ReadDInt(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Int, 1);
        return (int)result;
    }
    /// <summary>
    /// 写入Dint类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteDInt(Plc Plc, int dbBlock, int startByteAdr, int Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取char类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public char ReadChar(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.String, 1);
        return (char)result;
    }
    /// <summary>
    /// 写入char类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteChar(Plc Plc, int dbBlock, int startByteAdr, char Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取byte类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public byte ReadByte(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Byte, 1);
        return (byte)result;
    }
    /// <summary>
    /// 写入byte类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteByte(Plc Plc, int dbBlock, int startByteAdr, byte Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取word类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public ushort ReadWord(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Word, 1);
        return (ushort)result;
    }
    /// <summary>
    /// 写入word类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteWord(Plc Plc, int dbBlock, int startByteAdr, ushort Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取Dword类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public uint ReadDWord(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Int, 1);
        return (uint)result;
    }
    /// <summary>
    /// 写入Dword类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteDWord(Plc Plc, int dbBlock, int startByteAdr, uint Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取real类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public float ReadReal(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Real, 1);
        return (float)result;
    }
    /// <summary>
    /// 写入real类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteReal(Plc Plc, int dbBlock, int startByteAdr, float Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取Lreal类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public double ReadLReal(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.Int, 1);
        return (double)result;
    }
    /// <summary>
    /// 写入Lreal类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteLReal(Plc Plc, int dbBlock, int startByteAdr, double Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取dateandtime类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public DateTime ReadDateAndTime(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(dataType, dbBlock, startByteAdr, VarType.DateTime, 1);
        return (DateTime)result;
    }
    /// <summary>
    /// 写入dateandtime类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteDateAndTime(Plc Plc, int dbBlock, int startByteAdr, DateTime Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }
    /// <summary>
    /// 读取任意值类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="type">数组类型</param>
    /// <param name="count">读取值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public dynamic Read(Plc Plc, int dbBlock, int startByteAdr, VarType type, int count, DataType dataType = DataType.DataBlock)
    {
        switch (type)
        {
            case VarType.String:
                byte[] stringDemo = Plc.ReadBytes(DataType.DataBlock, dbBlock, startByteAdr + 2, (byte)Plc.Read(DataType.DataBlock, dbBlock, startByteAdr + 1, VarType.Byte, 1));//+2表示读取偏移值(跳过)的字符
                return Encoding.Default.GetString(stringDemo);
            case VarType.Bit:
                return (bool)Plc.Read(dataType, dbBlock, startByteAdr, VarType.Bit, count);
            case VarType.Int:
                return (short)Plc.Read(dataType, dbBlock, startByteAdr, VarType.Int, count);
            case VarType.DInt:
                return (int)Plc.Read(dataType, dbBlock, startByteAdr, VarType.DInt, count);
            case VarType.S7WString:
                return Plc.Read(dataType, dbBlock, startByteAdr, VarType.S7WString, count = 254).ToString();//254为wstring默认存储字符数
            case VarType.Byte:
                return (byte)Plc.Read(dataType, dbBlock, startByteAdr, VarType.Byte, count);
            case VarType.Word:
                return (ushort)Plc.Read(dataType, dbBlock, startByteAdr, VarType.Word, count);
            case VarType.DWord:
                return (uint)Plc.Read(dataType, dbBlock, startByteAdr, VarType.DWord, count);
            case VarType.Real:
                return (float)Plc.Read(dataType, dbBlock, startByteAdr, VarType.Real, count);
            case VarType.LReal:
                return (double)Plc.Read(dataType, dbBlock, startByteAdr, VarType.LReal, count);
            case VarType.DateTimeLong:
                return (DateTime)Plc.Read(dataType, dbBlock, startByteAdr, VarType.DateTimeLong, count);
            default:
                throw new Exception("数据类型不存在");
        }
    }

    /// <summary>
    /// 写入任意值类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="type">原数据类型</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void Write(Plc Plc, int dbBlock, int startByteAdr, VarType type, object Value, DataType dataType = DataType.DataBlock)
    {
        switch (type)
        {
            case VarType.String:
                Plc.Write(DataType.DataBlock, dbBlock, startByteAdr + 1, (byte)Value.ToString().Length);//长度需要改成byte类型
                Plc.Write(DataType.DataBlock, dbBlock, startByteAdr + 2, Value);
                break;
            case VarType.Bit:
                Plc.Write(dataType, dbBlock, startByteAdr, bool.Parse(Value.ToString()));
                break;
            case VarType.Int:
                Plc.Write(dataType, dbBlock, startByteAdr, short.Parse(Value.ToString()));
                break;
            case VarType.DInt:
                Plc.Write(dataType, dbBlock, startByteAdr, int.Parse(Value.ToString()));
                break;
            case VarType.Byte:
                Plc.Write(dataType, dbBlock, startByteAdr, byte.Parse(Value.ToString()));
                break;
            case VarType.Word:
                Plc.Write(dataType, dbBlock, startByteAdr, ushort.Parse(Value.ToString()));
                break;
            case VarType.DWord:
                Plc.Write(dataType, dbBlock, startByteAdr, uint.Parse(Value.ToString()));
                break;
            case VarType.Real:
                Plc.Write(dataType, dbBlock, startByteAdr, float.Parse(Value.ToString()));
                break;
            case VarType.LReal:
                Plc.Write(dataType, dbBlock, startByteAdr, double.Parse(Value.ToString()));
                break;
            case VarType.DateTimeLong:
                Plc.Write(dataType, dbBlock, startByteAdr, DateTime.Parse(Value.ToString()));
                break;
            default:
                throw new Exception("数据类型不存在");
        }
    }

    /// <summary>
    /// 读取array[]类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="type">数组类型</param>
    /// <param name="count">读取长度</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public dynamic ReadArray(Plc Plc, int dbBlock, int startByteAdr, VarType type, int count, DataType dataType = DataType.DataBlock)
    {
        switch (type)
        {
            case VarType.Bit:
                return (bool[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.Bit, count);
            case VarType.Int:
                return (short[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.Int, count);
            case VarType.DInt:
                return (int[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.DInt, count);
            case VarType.Byte:
                return (byte[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.Byte, count);
            case VarType.Word:
                return (ushort[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.Word, count);
            case VarType.DWord:
                return (uint[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.DWord, count);
            case VarType.Real:
                return (float[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.Real, count);
            case VarType.LReal:
                return (double[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.LReal, count);
            case VarType.DateTimeLong:
                return (DateTime[])Plc.Read(dataType, dbBlock, startByteAdr, VarType.DateTimeLong, count);
            default:
                throw new Exception("数据类型不存在");
        }
    }

    /// <summary>
    /// 写入array[]类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteArray(Plc Plc, int dbBlock, int startByteAdr, object Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(dataType, dbBlock, startByteAdr, Value);
    }

    /// <summary>
    /// 读取string类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public string ReadString(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var count = Plc.Read(DataType.DataBlock, dbBlock, startByteAdr + 1, VarType.Byte, 1);//+1表示读取偏移值的长度
        byte[] stringDemo = Plc.ReadBytes(DataType.DataBlock, dbBlock, startByteAdr + 2, (byte)count);//+2表示读取偏移值(跳过)的字符
        return Encoding.Default.GetString(stringDemo);
    }
    /// <summary>
    /// 写入string类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="Value">写入值</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public void WriteString(Plc Plc, int dbBlock, int startByteAdr, string Value, DataType dataType = DataType.DataBlock)
    {
        Plc.Write(DataType.DataBlock, dbBlock, startByteAdr + 1, (byte)Value.Length);//长度需要改成byte类型
        Plc.Write(DataType.DataBlock, dbBlock, startByteAdr + 2, Value);
    }
    /// <summary>
    /// 读取wstring类型
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="startByteAdr">数据偏移量</param>
    /// <param name="dataType">数据块类型</param>
    /// <returns></returns>
    public string ReadWString(Plc Plc, int dbBlock, int startByteAdr, DataType dataType = DataType.DataBlock)
    {
        var result = Plc.Read(DataType.DataBlock, dbBlock, startByteAdr, VarType.S7WString, 254);
        return result.ToString();
    }

    /// <summary>  以下两种方式不推荐,会重复开启tcp连接占用资源
    /// 标签方式读取
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <returns></returns>
    public dynamic ReadTags(Plc Plc, string dbBlock)
    {
        //例:Plc.Read("DB2.DBX0.0"); 其中db2表示数据库名称,0.0表示偏移量  dbx表示数据块
        return Plc.Read(dbBlock);
    }

    /// <summary>
    /// 标签方式写入
    /// </summary>
    /// <param name="dbBlock">所选择的数据库块</param>
    /// <param name="vaule">写入值</param>
    /// <returns></returns>
    public void WriteTags(Plc Plc, string dbBlock, object vaule)
    {
        //例:Plc.Read("DB2.DBX0.0",true); 其中db2表示数据库名称,0.0表示偏移量,true表示将其转换为true
        Plc.Write(dbBlock, vaule);
    }
    /// <summary>
    /// 获取西门子PLC字符串数组--WString
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public byte[] GetPLCWStringByteArray(Plc Plc, string str)
    {
        byte[] value = Encoding.BigEndianUnicode.GetBytes(str);
        byte[] head = BitConverter.GetBytes((short)254);
        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;
    }
}

 3、使用方法:

 public class UseItDemo
 {
     /// <summary>
     /// 西门子PLC的连接信息集合
     /// </summary>
     public static Dictionary<string, SiemensModel> SiemensPLCs = new Dictionary<string, SiemensModel>();
     /// <summary>
     /// 1、PLC连接初始化,把所有连接丢进连接池
     /// </summary>
     public void PLC_Init(List<DBInfo> infos)
     {
         try
         {
             for (int i = 0; i < infos.Count; i++)
             {
                 SiemensModel siemens = new SiemensModel();
                 if (infos[i].PLCType == "S1200")
                     siemens.SiemensClient = OpenPlc(CpuType.S71200, infos[i].PLCIP, (short)infos[i].PLCRack, (short)infos[i].PLCSlot);
                 else if (infos[i].PLCType == "S1500")
                     siemens.SiemensClient = OpenPlc(CpuType.S71500, infos[i].PLCIP, (short)infos[i].PLCRack, (short)infos[i].PLCSlot);
                 else if (infos[i].PLCType == "S200Smart")
                     siemens.SiemensClient = OpenPlc(CpuType.S7200Smart, infos[i].PLCIP, (short)infos[i].PLCRack, (short)infos[i].PLCSlot);
                 else if (infos[i].PLCType == "S300")
                     siemens.SiemensClient = OpenPlc(CpuType.S7300, infos[i].PLCIP, (short)infos[i].PLCRack, (short)infos[i].PLCSlot);
                 else if (infos[i].PLCType == "S400")
                     siemens.SiemensClient = OpenPlc(CpuType.S7400, infos[i].PLCIP, (short)infos[i].PLCRack, (short)infos[i].PLCSlot);
                 if (siemens.SiemensClient != null)
                 {
                     SiemensPLCs.Add(infos[i].PLCConnection, siemens);
                 }
                 else
                 {
                     // Log
                 }

             }

             // Log
         }
         catch (Exception ex)
         {

             // Log
         }
     }

     /// <summary>
     /// 打开连接
     /// </summary>
     /// <param name="cpuType"></param>
     /// <param name="ip"></param>
     /// <param name="rack"></param>
     /// <param name="slot"></param>
     /// <returns></returns>
     public Plc OpenPlc(CpuType cpuType = CpuType.S71200, string ip = "127.0.0.1", short rack = 0, short slot = 1)
     {
         Plc Plc = new Plc(cpuType, ip, rack, slot);
         Plc.Open();
         if (Plc.IsConnected) return Plc;
         else return null;
     }

     /// <summary>
     /// 2、读取数据、写入数据类似
     /// </summary>
     /// <param name="datatype">PLC的数据类型</param>
     /// <param name="Address">DB地址,例如:DB2030.DBX94.0</param>
     public void ReadPlcData(string datatype, string Address)
     {
         Task.Run(() =>
         {
             try
             {
                 foreach (var item in SiemensPLCs.Values)
                 {
                     if (!item.SiemensClient.IsConnected)
                     {
                         item.SiemensClient.Open();
                     }
                     //采集变量信息
                     int db = 1;//数据块
                     int start = 0;//字节偏移量
                     byte by = 0;//位偏移量"DB1.DBX2.7"中的7代表位偏移量为7
                     //将DB地址拆分-DB2030.DBX94.0(X是数据类型,具体的百度) 拆开后:2023-DB地址 94-字节偏移量 0--字节的偏移量
                     var arry = Address.Split(new char[] { '.', '%', 'D', 'B', 'X', 'W' }, StringSplitOptions.RemoveEmptyEntries);
                     db = int.Parse(arry[0]);
                     start = int.Parse(arry[1]);
                     if (arry.Length == 3)//代表小数点后还有
                     {
                         by = byte.Parse(arry[2]);
                     }
                     //根据数据类型的不同选择不同的读取方法
                     switch (datatype.ToUpper())//存入redis
                     {
                         case "WORD":
                             var result = item.SiemensClient.Read(DataType.DataBlock, db, start, VarType.Word, 1);
                             if (result != null)
                             {
                                 //取到数据做相应操作,此处我是存到缓存供客户端使用
                                 //redis.StringSet("Key", result.ToString());
                             }
                             break;
                         case "BYTE":
                             var result1 = item.SiemensClient.Read(DataType.DataBlock, db, start, VarType.Byte, 1);
                             if (result1 != null)
                             {
                                 //redis.StringSet("Key", result1.ToString());
                             }
                             break;
                         case "BOOL":
                             var result2 = item.SiemensClient.Read(DataType.DataBlock, db, start, VarType.Bit, 1, by);
                             if (result2 != null)
                             {
                                 // redis.StringSet("Key", result2.ToString());
                             }
                             break;
                         default:
                             break;
                     }
                 }
             }
             catch (Exception ex)
             {
                 //Log
             }
         });
     }
 }
 /// <summary>
 /// DB块的相关信息。
 /// </summary>
 public class DBInfo
 {
     /// <summary>
     /// PLC连接名
     /// </summary>
     public string PLCConnection { get; set; }
     /// <summary>
     /// PLCIp
     /// </summary>
     public string PLCIP { get; set; }
     /// <summary>
     /// 机架号
     /// </summary>
     public int PLCRack { get; set; }
     /// <summary>
     /// 插槽号
     /// </summary>
     public int PLCSlot { get; set; }
     /// <summary>
     /// PLC类型
     /// </summary>
     public string PLCType { get; set; }
 }

 //plc中类型与c#类型 bool => Bit
 //Byte => byte
 //word => ushort
 //DWord => uint
 //Int => short
 //DInt => int
 //Real => float
 //LReal => double
 //String => string
 //DateTimeLong=>datetime
 //s7wstring=>string
 /// <summary>
 /// 西门子连接信息
 /// </summary>
 public class SiemensModel
 {
     /// <summary>
     /// 西门子客户端
     /// </summary>
     public Plc SiemensClient { get; set; }
     /// <summary>
     /// 是否连接
     /// </summary>
     public bool IsConnected { get; set; }
     /// <summary>
     /// 是否运行
     /// </summary>
     public bool IsWorking { get; set; }

     /// <summary>
     /// 采集任务
     /// </summary>
     public Func<List<Tuple<PLC_DB, byte[]>>> ReadValueTask { get; set; }
     /// <summary>
     /// 解析任务
     /// </summary>
     public Action<List<Tuple<PLC_DB, byte[]>>> AnalysisTask { get; set; }

 }

到这就结束了。记录一下。


网站公告

今日签到

点亮在社区的每一天
去签到