【C#使用S7.NET库读取和写入西门子PLC变量】

C#使用S7.NET库读取和写入西门子PLC变量

前言

本来想用Wincc的接口给读和写Wincc,但是速度实在太感人了,所以不如直接读和写PLC的变量,这种方式速度瞬间快了不知道多少倍(经测试4000个变量几乎瞬间完成,应该1s左右,人感知不出来)。

网上找了好多资料,都写得比较分散。特别是关于字符串的读取和写入,写了好久才读写正常,把两种方式的代码分享出来。

使用S7.NET库读取

csharp 复制代码
        //使用S7.NET库___读取PLC变量
        public static string[] ReadPLC(int DbAddress,int StartByteAdr,int ByteCount,int Type)
        {
            int i, j, k;
            int types = 2;
            int count;
            byte[] bytes=new byte[1000];
            //返回值当前设置最大1000,可自由设置
            string[] result=new string[1000];

            #region plc系列号+机架号+插槽号
            Plc MyPLC = new Plc(CpuType.S71500, "10.168.4.2", 0, 1);
            MyPLC.Open();
            #endregion

            //读取的是int
            if (Type == 1)
            {
                types = 2;
            }
            //读取的是real
            else if (Type == 2)
            {
                types = 4;
            }
            //读取的是String
            else if (Type == 3)
            {
                types = 256;
            }
            //读取的是bool
            else if(Type == 0)
            {
                types = 1;
            }

            try
            {
                j = 0;
                if (types == 1)
                {
                    //读取BOOL
                    for (i = 0; i < Convert.ToInt16(ByteCount / 8 + 1); i++)
                    {
                        for (k = 0; k <= 7; k++)
                        {
                            result[j + k] = MyPLC.Read("DB" + DbAddress.ToString() + "." + "DBX" + (StartByteAdr + i).ToString() + "." + k.ToString()).ToString();
                            if (result[j + k] == "True")
                            {
                                result[j + k] = "1";
                            }
                            else
                            {
                                result[j + k] = "0";
                            }
                        }
                        j = j + 8;
                    }
                }
                else if (types == 2 || types == 4)
                {
                    //读取字节
                    bytes = MyPLC.ReadBytes(DataType.DataBlock, DbAddress, StartByteAdr, ByteCount * types);
                    for (i = 0; i <= (ByteCount * types - types); i = i + types)
                    {
                        if (types == 2)
                        {
                            result[j] = S7.Net.Types.Int.FromByteArray(bytes.Skip(i).Take(types).ToArray()).ToString();
                        }
                        if (types == 4)
                        {
                            result[j] = S7.Net.Types.Real.FromByteArray(bytes.Skip(i).Take(types).ToArray()).ToString();
                        }
                        j++;
                    }
                }
                else if (types == 256)
                {
                    //读取字符串
                    //读取字符串的长度
                    for (i=0; i< ByteCount; i++)
                    {
                        count = (byte)MyPLC.Read(DataType.DataBlock, DbAddress, StartByteAdr+i*22 + 1, VarType.Byte, 1);
                        bytes = MyPLC.ReadBytes(DataType.DataBlock, DbAddress, StartByteAdr+i*22 + 2, count);
                        result[j] = Encoding.Default.GetString(bytes);
                        j++;
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("错误:读取PLC变量错误!");
            }

            MyPLC.Close();
            return result;
        }

使用S7.NET库写入

csharp 复制代码
        //使用S7.NET库___写入PLC变量
        public static void WritePLC(int DbAddress, int StartByteAdr, int ByteCount, int Type, string[] strings)
        {
            int i,j;
            short ints;
            float floats;
            int types = 2;
            //最多1000个字节写入,可自由设置
            byte[] bytes = new byte[1000];

            #region plc系列号+机架号+插槽号
            Plc MyPLC = new Plc(CpuType.S71500, "10.168.4.2", 0, 1);
            MyPLC.Open();
            #endregion

            //写入的是int
            if (Type == 1)
            {
                types = 2;
            }
            //写入的是real
            else if (Type == 2)
            {
                types = 4;
            }
            //写入的字符串
            else if (Type == 3)
            {
                types = 256;
            }
            //读取的是bool
            else if (Type == 0)
            {
                types = 1;
            }

            try
            {
                if (types == 2)
                {
                    for (i = 0; i <= ByteCount-1; i++)
                    {
                        ints = Convert.ToInt16(strings[i]);
                        MyPLC.Write(DataType.DataBlock, DbAddress, StartByteAdr + i * types, ints);            
                    }
                }
                else if (types == 4)
                {
                    for (i = 0; i <= ByteCount-1; i++)
                    {
                        floats = Convert.ToSingle(strings[i]);
                        MyPLC.Write(DataType.DataBlock, DbAddress, StartByteAdr + i * types, floats);
                    }
                }
                else if (types == 256)
                {
                    for (i = 0; i <= ByteCount - 1; i++)
                    {
                        if (strings[i]!=null)
                        {
                            //字符串转换成编码再转成字节
                            bytes = Encoding.Default.GetBytes(strings[i]);
                            //写入字节长度,用字节的数据类型
                            MyPLC.Write(DataType.DataBlock, DbAddress, StartByteAdr + i * 22 + 1, (byte)bytes.Length);
                            //依次写入
                            MyPLC.Write(DataType.DataBlock, DbAddress, StartByteAdr + i * 22 + 2, bytes);
                        }
                        else
                        {
                            //字符串转换成编码再转成字节
                            bytes = Encoding.Default.GetBytes("");
                            //写入字节长度,用字节的数据类型
                            MyPLC.Write(DataType.DataBlock, DbAddress, StartByteAdr + i * 22 + 1, (byte)bytes.Length);
                            //依次写入
                            MyPLC.Write(DataType.DataBlock, DbAddress, StartByteAdr + i * 22 + 2, bytes);
                        }
                    }
                }
                else if (types == 1)
                {
                    for (i=0; i <= ByteCount - 1; i=i+8)
                    {
                        for (j=0;j<=7 && i+j<= ByteCount - 1; j++)
                        {
                            if (strings[i + j]=="1")
                            {
                                MyPLC.WriteBit(DataType.DataBlock, DbAddress, StartByteAdr+i/8, j,true);
                            }
                            else
                            {
                                MyPLC.WriteBit(DataType.DataBlock, DbAddress, StartByteAdr+i/8, j, false);
                            }                            
                        }                       
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("写入PLC数据错误");
            }
            
            MyPLC.Close();
        }
相关推荐
乌暮1 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
YDS8291 小时前
Small Spring IOC篇:容器事件及其监听器
java·spring
金銀銅鐵1 小时前
带您看懂字节码指令(三):一行加法里有什么
java·jvm
文丑颜不良啊1 小时前
LeetCode2921~2940题目解析
java·leetcode
暴走约伯2 小时前
【VFX工具链源码拆解 09】终极工业化闭环:基于 ID 规则驱动的全自动场景建档、骨骼挂载与男转女场景迁移
unity·c#·游戏引擎·材质
北漂人Java2 小时前
基于 Spring AI Alibaba WorkFlow 构建 Java 生产级 AI Agent
java·人工智能·spring
用户112936112193 小时前
编译全绿,上线就崩:MyBatis 五层方法名大小写埋下的坑
java
文丑颜不良啊3 小时前
LeetCode2901~2920题目解析
java·leetcode
码云社区3 小时前
能碳管理系统开发要关注什么?能源数据、统计口径与AI分析的衔接
java·人工智能·ai·能源·能源管理系统·能碳管理系统·能碳管理系统源码
Flynn Liang4 小时前
Agentic 工作流:子代理、Supervisor 与人工介入
java·langchain·多智能体·supervisor·agentic·langchain4j