注:.net中通过TCP/IP方式通过S7.net.dll动态库,连接到西门子PLC,西门子程序中许勾选优化块,程序读取需要 db块号+偏移量
一。使用VS项目,在项目中添加S7.net动态库
代码中引用S7.net动态库
using S7.Net;
实例化PLC服务名
///
/// 实例化PLC
///
Plc S71500;
连接PLC按钮时间编写:
以上代码可测试是否能连接至PLC
二.西门子中点位信息,在程序中地址表示说明
在DB块中有如下变量
/// <summary>
/// 实例化PLC
/// </summary>
Plc S71500;
/// <summary>
/// 连接PLC
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
string ip=tb_plcip.Text.Trim(); //PLC地址IP 例192.168.0.1
short rack= short.Parse( tb_rack.Text.Trim()); //PLC机架位置 默认0
short solt = short.Parse(tb_solt.Text.Trim()); //PLC插槽位置,以实际为准
//CpuType根据实际PLC连接,我这边已1500PLC为例
S71500 = new Plc(CpuType.S71500, ip, rack, solt);
//调用S7.NET中的方法连接PLC
S71500.Open();
//连接成功后使能操作按钮
if (S71500.IsConnected)
{
//判断是否连接成功
MessageBox.Show("连接PLC成功");
}
}
在程序中读取需DB块号+地址,分别写法如下
DB1.DBW0 //地址为0,类型为整数
DB1.STRING2.18 //地址为2,字符长度18 类型为字符串
DB1.B22 //地址为22,类型为字节型
DB1.DBD24 //地址为24,类型为实数
DB1.DBW28 //地址为28,类型为整数
DB1.DBW28 //地址为28,类型为整数
DB1.DBX29.0 //地址为29.0,类型为布尔
三,通过代码读写Tag点信息,以下代码可进行以上Tag点信息的读取及写入,代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using S7.Net;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 实例化PLC
/// </summary>
Plc S71500;
/// <summary>
/// 连接PLC
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
string ip=tb_plcip.Text.Trim(); //PLC地址IP 例192.168.0.1
short rack= short.Parse( tb_rack.Text.Trim()); //PLC机架位置 默认0
short solt = short.Parse(tb_solt.Text.Trim()); //PLC插槽位置,以实际为准
//CpuType根据实际PLC连接,我这边已1500PLC为例
S71500 = new Plc(CpuType.S71500, ip, rack, solt);
//调用S7.NET中的方法连接PLC
S71500.Open();
//连接成功后使能操作按钮
if (S71500.IsConnected)
{
//判断是否连接成功
MessageBox.Show("连接PLC成功");
}
}
//****
//读取 ReadPLC("DB1.DBW0");
//写入 WritePLC("DB1.DBW0","1");
//其中BOOL写入: WritePLC(DB1.DBX29.0, "False");或WritePLC(DB1.DBX29.0, "True");
#region 读写TAG点方法
/// <summary>
/// 去指定字符串中间字符
/// </summary>
/// <param name="sourse">字符串</param>
/// <param name="startstr">首字符</param>
/// <param name="endstr">尾字符</param>
/// <returns></returns>
public static string MidStrEx(string sourse, string startstr, string endstr)
{
string result = string.Empty;
int startindex, endindex;
try
{
startindex = sourse.IndexOf(startstr);
if (startindex == -1)
{
return result;
}
string tmpstr = sourse.Substring(startindex + startstr.Length);
endindex = tmpstr.IndexOf(endstr);
if (endindex == -1)
{
return result;
}
result = tmpstr.Remove(endindex);
}
catch (Exception)
{
}
return result;
}
/// <summary>
/// 写入PLC数值
/// </summary>
/// <param name="DataTag"></param>
public void WritePLC(string DataTag, string Data)
{
try
{
#region 逻辑处理
string Type = "STRING";
if (DataTag.Contains("STRING"))
{
Type = "STRING";
}
else if (DataTag.Contains("DBW"))
{
Type = "Word";
}
else if (DataTag.Contains(".B"))
{
Type = "Byte";
}
else if (DataTag.Contains("DBD"))
{
Type = "Real";
}
else if (DataTag.Contains("DBX"))
{
Type = "Bool";
}
int strAdr = 0;
//取到db块号
int dbInt = dbInt = int.Parse(MidStrEx(DataTag, "DB", ".")); ;
//字符串类型
if (Type == "STRING")
{
//取到地址
strAdr = int.Parse(MidStrEx(DataTag, "STRING", "."));
//写入PLC数据
S71500.Write(DataType.DataBlock, dbInt, strAdr, GetPLCStringByteArray(Data));
}
else if (Type == "Word")
{
//写入整数型
strAdr = int.Parse(Regex.Match(DataTag, @"\d+$").ToString());
S71500.Write(DataType.DataBlock, dbInt, strAdr, Convert.ToInt16(Data));
}
else if (Type == "Byte")
{
//写入字节型
strAdr = int.Parse(Regex.Match(DataTag, @"\d+$").ToString());
S71500.Write(DataType.DataBlock, dbInt, strAdr, Convert.ToByte(Data));
}
else if (Type == "Real")
{
//写入实数
strAdr = int.Parse(Regex.Match(DataTag, @"\d+$").ToString());
S71500.Write(DataType.DataBlock, dbInt, strAdr, Convert.ToDouble(Data));
}
else if (Type == "Bool")
{
//写入Bool值
S71500.Write(DataTag.ToUpper(), Convert.ToBoolean(Data));
}
#endregion
}
catch (Exception ex)
{
//写入异常
}
}
int errorCount = 0;
/// <summary>
/// 读取PLC数据
/// </summary>
/// <param name="DataTag">Tag点名称</param>
public string ReadPLC(string DataTag)
{
string returnData = "";
try
{
if (DataTag.Contains("STRING"))
{
//取到DB块号
int dbInt = dbInt = int.Parse(MidStrEx(DataTag, "DB", "."));
//取到偏移量地址
int strAdr = int.Parse(MidStrEx(DataTag, "STRING", "."));
//获取字符串长度
var reservedLength = (byte)S71500.Read(DataType.DataBlock, dbInt, strAdr, VarType.Byte, 1);
//读取时在地址前加两位偏移
string StrReplac = (string)S71500.Read(DataType.DataBlock, dbInt, strAdr + 2, VarType.String, reservedLength);
//去除字符串后面空白符号
returnData = StrReplac.Replace("\0", "");
}
else if (DataTag.Contains("DBW"))
{
//读取整数型数据
ushort UpValue = (ushort)S71500.Read(DataTag);
returnData = Convert.ToString(UpValue);
}
else if (DataTag.Contains(".B"))
{
//取到DB块号
int dbInt = dbInt = int.Parse(MidStrEx(DataTag, "DB", "."));
//取到偏移量地址
int strAdr = int.Parse(Regex.Match(DataTag, @"\d+$").ToString());
//获取字符串长度
var reservedLength = (byte)S71500.Read(DataType.DataBlock, dbInt, strAdr, VarType.Byte, 1);
//将读取数据转为字符串
returnData = Convert.ToString(reservedLength);
}
else if (DataTag.Contains("DBD"))
{
//读取小数型数据
double UpValue = ((uint)S71500.Read(DataTag)).ConvertToFloat();
if (Convert.ToString(UpValue).Trim() != "")
{
//截取保留小数位长度
returnData = Math.Round(UpValue, 3).ToString();
}
}
else if (DataTag.Contains("DBX"))
{
//读取Bool值数据
var db1Bool1 = S71500.Read(DataTag);
returnData = db1Bool1.ToString();
}
}
catch (Exception ex)
{
//读取异常
}
return returnData;
}
/// <summary>
/// 获取西门子PLC字符串数组--String
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private byte[] GetPLCStringByteArray(string str)
{
byte[] value = Encoding.Default.GetBytes(str);
byte[] head = new byte[2];
head[0] = Convert.ToByte(254);
head[1] = Convert.ToByte(str.Length);
value = head.Concat(value).ToArray();
return value;
}
/// <summary>
/// 获取西门子PLC字符串数组--WString
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private byte[] GetPLCWStringByteArray(string str)
{
byte[] value = Encoding.BigEndianUnicode.GetBytes(str);
byte[] head = BitConverter.GetBytes((short)508);
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;
}
#endregion
}
}