C#使用S7.NET库读取和写入西门子PLC变量
- 前言
- 使用S7.NET库读取
- 使用S7.NET库写入
前言
本来想用Wincc的接口给读和写Wincc,但是速度实在太感人了,所以不如直接读和写PLC的变量,这种方式速度瞬间快了不知道多少倍(经测试4000个变量几乎瞬间完成,应该1s左右,人感知不出来)。
网上找了好多资料,都写得比较分散。特别是关于字符串的读取和写入,写了好久才读写正常,把两种方式的代码分享出来。
使用S7.NET库读取
//使用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//读取的是intif (Type == 1){types = 2;}//读取的是realelse if (Type == 2){types = 4;}//读取的是Stringelse if (Type == 3){types = 256;}//读取的是boolelse if(Type == 0){types = 1;}try{j = 0;if (types == 1){//读取BOOLfor (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库写入
//使用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//写入的是intif (Type == 1){types = 2;}//写入的是realelse if (Type == 2){types = 4;}//写入的字符串else if (Type == 3){types = 256;}//读取的是boolelse 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();}