C#通过S7.NET库实现与西门子PLC数据交互
拉了换一个简单的界面
PLC端设置
我新建了一个DB数据块【DB1】,右键【DB1】,点击【属性】项,【优化的块访问】默认是勾选,要想显示数据块中地址偏移量,需要把【优化的块访问】勾选取消
PLC与C#数据类型对应
Bit => bool
Byte => byte
word => ushort
DWord => uint
Int => short
DInt => int
Real => float
LReal => double
String => string
VS2019添加S7.NET库引用
1、右键项目名,选择图中【管理NuGet程序包】2、在搜索框输入【S7netplus】,我安装的是第一个。
3、安装完成引用里面会自动添加【S7.NET】引用,如上图所示。
连接PLC
public void Open();
this.myPlc.Open();
if (this.myPlc.PlcObject.IsConnected)
{
this.btnOpen.Enabled = false;
this.btnClose.Enabled = true;
this.tsslblIsConnected.BackColor = Color.Green;
this.tsslblIsConnected.Text = "PLC已连接";
this.tsslblIP.Text = this.myPlc.PlcObject.IP.ToString();
this.btnRead.Enabled = true;
this.btnWrite.Enabled = true;
switch (this.myPlc.PlcObject.CPU)
{
case CpuType.S7300:
this.tsslblCpuType.Text = "S7-300";
break;
case CpuType.S7400:
this.tsslblCpuType.Text = "S7-400";
break;
case CpuType.S71200:
this.tsslblCpuType.Text = "S7-1200";
break;
case CpuType.S71500:
this.tsslblCpuType.Text = "S7-1500";
break;
}
}
对于S7-1200和S7-1500,默认为机架= 0,槽位= 0;对于S7-300和S7-400是默认的机架= 0,槽位= 2;端口号默认为102。
断开PLC
public void Close();
this.myPlc.Close();
if (!this.myPlc.PlcObject.IsConnected)
{
this.btnOpen.Enabled = true;
this.btnClose.Enabled = false;
this.tsslblIsConnected.BackColor = Color.Red;
this.tsslblIsConnected.Text = "PLC未连接";
this.tsslblIP.Text = "***********";
this.tsslblCpuType.Text = "******";
this.btnRead.Enabled = false;
this.btnWrite.Enabled = false;
}
读取单个数据
public object? Read(string variable);
if (this.tabControlRead.SelectedTab == this.tabControlRead.TabPages[0]) //读取单个数据
{
try
{
this.txtReadResult.Text = DateTime.Now.ToString() + ":" + this.myPlc.Read(this.txtReadSingleAdr.Text.Trim().ToUpper()).ToString();
}
catch (Exception ex)
{
MessageBox.Show("读取单个数据出现错误!" + ex.Message, "提示信息");
}
}
我这里把输入的地址的转换为大写字母;如果不转换,输入小写字母会出现报错。
读取数组数据
public object? Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount, byte bitAdr = 0);
switch (this.cboReadVarType.Text.Trim())
{
case "Bit":
foreach (var item in (System.Collections.BitArray)this.myPlc.Read(dataType, db, startByteAdr, VarType.Bit, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "Byte":
foreach (var item in (byte[])this.myPlc.Read(dataType, db, startByteAdr, VarType.Byte, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "Word":
foreach (var item in (ushort[])this.myPlc.Read(dataType, db, startByteAdr, VarType.Word, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "DWord":
foreach (var item in (uint[])this.myPlc.Read(dataType, db, startByteAdr, VarType.DWord, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "Int":
foreach (var item in (short[])this.myPlc.Read(dataType, db, startByteAdr, VarType.Int, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "DInt":
foreach (var item in (int[])this.myPlc.Read(dataType, db, startByteAdr, VarType.DInt, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "Real":
foreach (var item in (float[])this.myPlc.Read(dataType, db, startByteAdr, VarType.Real, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "LReal":
foreach (var item in (double[])this.myPlc.Read(dataType, db, startByteAdr, VarType.LReal, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "String":
foreach (var item in (string)this.myPlc.Read(dataType, db, startByteAdr, VarType.String, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "S7String":
foreach (var item in (string[])this.myPlc.Read(dataType, db, startByteAdr, VarType.S7String, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "S7WString":
foreach (var item in (string[])this.myPlc.Read(dataType, db, startByteAdr, VarType.S7WString, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "DateTime":
foreach (var item in (DateTime[])this.myPlc.Read(dataType, db, startByteAdr, VarType.DateTime, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
case "DateTimeLong":
foreach (var item in (DateTime[])this.myPlc.Read(dataType, db, startByteAdr, VarType.DateTimeLong, varCount, bitAdr))
{
this.rtxtReadResult.Text += item.ToString() + " ";
}
break;
}
读取BIT数组时我这里使用【System.Collections.BitArray】强制转换
读取字节数组
public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count);文章来源:https://www.toymoban.com/news/detail-635689.html
var bytes = this.myPlc.PlcObject.ReadBytes(DataType.DataBlock, 1, 0, 120);
string str = string.Empty;
str = "DB1.DBX0.0:\t" + Convert.ToBoolean(bytes[0].SelectBit(0)).ToString() + "\n";
str += "DB1.DBX0.1:\t" + Convert.ToBoolean(bytes[0].SelectBit(1)).ToString() + "\n";
str += "DB1.DBX0.2:\t" + Convert.ToBoolean(bytes[0].SelectBit(2)).ToString() + "\n";
str += "DB1.DBB1.0:\t" + Convert.ToString(S7.Net.Types.Byte.FromByteArray(bytes.Skip(1).Take(1).ToArray()), 16) + "\n";
str += "DB1.DBB2.0:\t" + Convert.ToString(S7.Net.Types.Byte.FromByteArray(bytes.Skip(2).Take(1).ToArray()), 16) + "\n";
str += "DB1.DBB3.0:\t" + Convert.ToString(S7.Net.Types.Byte.FromByteArray(bytes.Skip(3).Take(1).ToArray()), 16) + "\n";
str += "DB1.DBW4.0:\t" + Convert.ToInt16(S7.Net.Types.Int.FromByteArray(bytes.Skip(4).Take(2).ToArray())) + "\n";
str += "DB1.DBW6.0:\t" + Convert.ToInt16(S7.Net.Types.Int.FromByteArray(bytes.Skip(6).Take(2).ToArray())) + "\n";
str += "DB1.DBW8.0:\t" + Convert.ToInt16(S7.Net.Types.Int.FromByteArray(bytes.Skip(8).Take(2).ToArray())) + "\n";
str += "DB1.DBW10.0\t:" + Convert.ToUInt16(S7.Net.Types.Word.FromByteArray(bytes.Skip(10).Take(2).ToArray())) + "\n";
str += "DB1.DBW12.0\t:" + Convert.ToUInt16(S7.Net.Types.Word.FromByteArray(bytes.Skip(12).Take(2).ToArray())) + "\n";
str += "DB1.DBW14.0\t:" + Convert.ToUInt16(S7.Net.Types.Word.FromByteArray(bytes.Skip(14).Take(2).ToArray())) + "\n";
str += "DB1.DBW16.0:\t" + Convert.ToString(S7.Net.Types.Word.FromByteArray(bytes.Skip(16).Take(2).ToArray()), 16) + "\n";
str += "DB1.DBW18.0:\t" + Convert.ToString(S7.Net.Types.Word.FromByteArray(bytes.Skip(18).Take(2).ToArray()), 16) + "\n";
str += "DB1.DBW20.0:\t" + Convert.ToString(S7.Net.Types.Word.FromByteArray(bytes.Skip(20).Take(2).ToArray()), 16) + "\n";
str += "DB1.DBD22.0:\t" + Convert.ToString(S7.Net.Types.DWord.FromByteArray(bytes.Skip(22).Take(4).ToArray()), 16) + "\n";
str += "DB1.DBD26.0:\t" + Convert.ToString(S7.Net.Types.DWord.FromByteArray(bytes.Skip(26).Take(4).ToArray()), 16) + "\n";
str += "DB1.DBD30.0:\t" + Convert.ToString(S7.Net.Types.DWord.FromByteArray(bytes.Skip(30).Take(4).ToArray()), 16) + "\n";
str += "DB1.DBD34.0:\t" + Convert.ToInt32(S7.Net.Types.DInt.FromByteArray(bytes.Skip(34).Take(4).ToArray())) + "\n";
str += "DB1.DBD38.0:\t" + Convert.ToInt32(S7.Net.Types.DInt.FromByteArray(bytes.Skip(38).Take(4).ToArray())) + "\n";
str += "DB1.DBD42.0:\t" + Convert.ToInt32(S7.Net.Types.DInt.FromByteArray(bytes.Skip(42).Take(4).ToArray())) + "\n";
str += "DB1.DBD46.0:\t" + Convert.ToUInt32(S7.Net.Types.DWord.FromByteArray(bytes.Skip(46).Take(4).ToArray())) + "\n";
str += "DB1.DBD50.0:\t" + Convert.ToUInt32(S7.Net.Types.DWord.FromByteArray(bytes.Skip(50).Take(4).ToArray())) + "\n";
str += "DB1.DBD54.0:\t" + Convert.ToUInt32(S7.Net.Types.DWord.FromByteArray(bytes.Skip(54).Take(4).ToArray())) + "\n";
str += "DB1.DBD58.0:\t" + Convert.ToSingle(S7.Net.Types.Real.FromByteArray(bytes.Skip(58).Take(4).ToArray())) + "\n";
str += "DB1.DBD62.0:\t" + Convert.ToSingle(S7.Net.Types.Real.FromByteArray(bytes.Skip(62).Take(4).ToArray())) + "\n";
str += "DB1.DBD66.0:\t" + Convert.ToSingle(S7.Net.Types.Real.FromByteArray(bytes.Skip(66).Take(4).ToArray())) + "\n";
str += "DB1.DBD70.0:\t" + Convert.ToDouble(S7.Net.Types.LReal.FromByteArray(bytes.Skip(70).Take(8).ToArray())) + "\n";
str += "DB1.DBD78.0:\t" + Convert.ToDouble(S7.Net.Types.LReal.FromByteArray(bytes.Skip(78).Take(8).ToArray())) + "\n";
str += "DB1.DBD86.0:\t" + Convert.ToDouble(S7.Net.Types.LReal.FromByteArray(bytes.Skip(86).Take(8).ToArray())) + "\n";
str += "LocalTime:\t" + Convert.ToDateTime(S7.Net.Types.DateTimeLong.FromByteArray(bytes.Skip(96).Take(12).ToArray())) + "\n";
str += "SYSTime: \t\t" + Convert.ToDateTime(S7.Net.Types.DateTimeLong.FromByteArray(bytes.Skip(108).Take(12).ToArray())) + "\n";
str += "----------***********************-----------------\n";
我这里是读取DB1数据块的前120个字节的数据,我这里使用了Skip()和Take()函数,要使用这两个函数需要添加
using System.Linq;文章来源地址https://www.toymoban.com/news/detail-635689.html
修改单个数据
if (this.tabControlWrite.SelectedTab == this.tabControlWrite.TabPages[0]) //写入单个数据
{
try
{
switch (this.cboWriteVarType.Text.Trim())
{
case "Bit":
this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToBoolean(this.rtxtWriteData.Text.Trim()));
break;
case "Byte":
this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToByte(this.rtxtWriteData.Text.Trim()));
break;
case "Word":
case "Int":
this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToInt16(this.rtxtWriteData.Text.Trim()));
break;
case "DWord":
case "DInt":
this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToInt32(this.rtxtWriteData.Text.Trim()));
break;
case "Real":
this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToSingle(this.rtxtWriteData.Text.Trim()));
break;
case "LReal":
this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToDouble(this.rtxtWriteData.Text.Trim()));
break;
case "String":
case "S7String":
case "S7WString":
this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), this.rtxtWriteData.Text.Trim());
break;
case "Timer":
break;
case "Counter":
break;
case "DateTime":
case "DateTimeLong":
this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToDateTime(this.rtxtWriteData.Text.Trim()));
break;
}
}
catch (Exception ex)
{
MessageBox.Show("写入单个数据出现错误!" + ex.Message, "提示信息");
}
到了这里,关于C#上位机与西门子PLC数据交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!