写在前面
记录一下第一次写CSDN博客,可能写的不好,希望各位大佬指导指导(免责声明);
测试环境:1.Microsoft VS 2022
2..net 4.8
3.win11
本项目只有S7 1200实际使用过,按需获取;
第一步:下载仿真软件
我这里使用的是snap7-full-1.4.2
链接:https://pan.quark.cn/s/86c19d145595
提取码:fRrV
如图一:启动server端后,可以使用测试代码去链接S7协议的仿真;图二标记位置则可以写入值读取测试;
图一
图二
第二步:使用vs进行连接
连接代码如下:
Plc plc = null;
private void button1_Click(object sender, EventArgs e)
{
try
{ //PLC类型 IP地址 机架号 槽号
CpuType plcType = CpuType.S71200;
switch (this.PLCType.Text)
{
case "S7200":
plcType = CpuType.S7200;
break;
case "S7300":
plcType = CpuType.S7300;
break;
case "S7400":
plcType = CpuType.S7400;
break;
case "S71200":
plcType = CpuType.S71200;
break;
case "S71500":
plcType = CpuType.S71500;
break;
}
Plc MyPlc = new Plc(plcType, this.PlcIP.Text.Trim(), 0, 0);
MyPlc.Open();
if (MyPlc.IsConnected == false)
{
this.LogBox.AppendText("PLC连接失败");
}
else
{
this.LogBox.AppendText("PLC连接成功\r\n");
plc = MyPlc;
}
}
catch
{
this.LogBox.AppendText("PLC连接失败");
}
}
连接成功,server运行会提示:
第三步:数据读取测试
读取代码如下:
private void ReadPlc(object sender, EventArgs e)
{
try
{
switch (this.ReadValueType.Text)
{
case "Bool":
var IsRight = plc.Read(this.ReadAddress.Text.Trim());
this.LogBox.AppendText("\r\n" + "读取到:" + this.ReadAddress.Text.Trim() + "值:" + IsRight);
break;
case "Int":
int Score = (ushort)plc.Read(this.ReadAddress.Text.Trim());
this.LogBox.AppendText("\r\n" + "读取到:" + this.ReadAddress.Text.Trim() + "值:" + Score);
break;
case "Real":
var Money = ((uint)plc.Read(this.ReadAddress.Text.Trim())).ConvertToFloat();
this.LogBox.AppendText("\r\n" + "读取到:" + this.ReadAddress.Text.Trim() + "值:" + Money);
break;
case "String":
//String读取
string[] arr = this.ReadAddress.Text.Substring(2).Split('.');
var reservedLength = (byte)plc.Read(DataType.DataBlock, Convert.ToInt16(arr[0]), Convert.ToInt16(arr[1]), VarType.Byte, 1);//获取字符串长度
var Name = (string)plc.Read(DataType.DataBlock, Convert.ToInt16(arr[0]), Convert.ToInt16(arr[1]), VarType.S7String, reservedLength);//获取对应长度的字符串
this.LogBox.AppendText("\r\n" + "读取到:" + this.ReadAddress.Text.Trim() + "值:" + Name);
break;
case "DInt":
case "DWord":
case "Word":
var dIntVar = (uint)plc.Read(this.ReadAddress.Text);
this.LogBox.AppendText("\r\n" + "读取到:" + this.ReadAddress.Text.Trim() + "值:" + dIntVar);
break;
/*case "DWord":
*//*var dWordVar = (uint)plc.Read("DB1.DBD268.0");
this.LogBox.AppendText("DB1.DBD268.0: " + dWordVar);*//*
break;
case "Word":
var wordVar = (uint)plc.Read("DB1.DBD270.0");
this.LogBox.AppendText("DB1.DBD270.0: " + wordVar);
break;*/
case "Byte":
var dByteVar = (byte)plc.Read(this.ReadAddress.Text);
this.LogBox.AppendText("\r\n" + "读取到:" + this.ReadAddress.Text.Trim() + "值:" + dByteVar);
break;
}
}
catch (Exception ex)
{
this.LogBox.AppendText("读取到失败:" + ex.Message);
}
}
测试值的写入则使用仿真软件写入:如下图;
使用代码读取到的值如图:(需要注意的是这个写进去是16进制,我们读取出来时10进制)
第四步:写入数据测试
C#:代码如下
private void xxWritePlc(object sender, EventArgs e)
{
try
{
//object result = WritePlc.SimWrite(plc, "Bool", this.WriteAddress.Text.ToString().Trim(), Convert.ToBoolean(this.WriteValue.Text));
switch (this.WriteValueType.Text)
{
case "Byte":
plc.Write(this.WriteAddress.Text.Trim(), Convert.ToByte(this.WriteValue.Text));
break;
case "Bool":
//Bool
//plc.Write("DB1.DBX0.0", true);
plc.Write(this.WriteAddress.Text.Trim(), Convert.ToBoolean(this.WriteValue.Text));
break;
case "Int":
Int
//plc.Write("DB1.DBW2.0", Convert.ToInt16(1));
plc.Write(this.WriteAddress.Text.Trim(), Convert.ToInt16(this.WriteValue.Text));
break;
case "Real":
// Real
plc.Write(this.WriteAddress.Text.Trim(), Convert.ToSingle(this.WriteValue.Text));
break;
case "String":
//String写入
//"DB1.8.0: "
string[] arr = this.WriteAddress.Text.Substring(2).Split('.');
var temp = Encoding.ASCII.GetBytes(this.WriteValue.Text); //将val字符串转换为字符数组
var bytes = S7.Net.Types.S7String.ToByteArray(this.WriteValue.Text, temp.Length);
plc.WriteBytes(DataType.DataBlock, Convert.ToInt16(arr[0]), Convert.ToInt16(arr[1]), bytes);
break;
case "DInt":
case "DWord":
case "Word":
// DInt
plc.Write(this.WriteAddress.Text.Trim(), Convert.ToInt32(this.WriteValue.Text));
break;
/* case "DWord":
// DWord
plc.Write("DB1.DBD268.0", 123456);
break;
case "Word":
// Word
plc.Write("DB1.DBD270.0", 12345678);
break;*/
}
this.LogBox.AppendText("\r\n" + this.WriteAddress.Text.Trim() + "写入" + this.WriteValue.Text + "成功");
}
catch (Exception ex)
{
this.LogBox.AppendText("\r\n" + this.WriteAddress.Text.Trim() + "写入" + this.WriteValue.Text + "失败");
this.LogBox.AppendText("原因:" + ex.Message);
}
}
写在后面
目前就用到了这么多,要是后面碰到了BUG(肯定有,但是我懒得测了 -_- ) 再回来...