概述
前言
好久没发博文了,发了这么多的通讯协议源码,在此贴一下,PLC寄存器数据的读写程序,各种PLC都是换汤不换药的,至于如何标准起来,各位筒子们自行发挥,在此以西门子的PLC为例,贴上使用的源程序,读写各自以心跳为例,带上各种格式转换的方法程序。
声明变量
项目程序当中,正常是一个PLC CPU一个线程,所以举例以一个线程为例,这样不会占用太多的PLC CPU的通讯性能,防止PLC CPU的扫码周期边长,更有甚者,会导致看门狗直接挂掉
/// <summary>
/// PLC通讯线程
/// </summary>
Thread PlcLinkTd;
/// <summary>
/// 西门子连接对象
/// </summary>
SimencePlcLinkHelper simenceLink;
/// <summary>
/// PLC配置模型
/// </summary>
public static PlcEquipMentModel PlcModel;
下面贴一下PLC配置模型类的代码:
/// <summary>
/// PLC配置模型类
/// </summary>
public class PlcEquipMentModel
{
/// <summary>
/// PLC对应名称
/// </summary>
public string PlcName { get; set; }
/// <summary>
/// IP地址
/// </summary>
public string PlcIpAddr { get; set; }
/// <summary>
/// PLC端口
/// </summary>
public int PlcPort { get; set; }
/// <summary>
/// PLC型号300或者1200
/// </summary>
public int PLCSiemenceType { get; set; }
/// <summary>
/// PLC槽号
/// </summary>
public int SoltNo { get; set; }
/// <summary>
/// 连接标志位
/// </summary>
public bool LinkRes { get; set; }
/// <summary>
/// 连接状态
/// </summary>
public int link_Status { get; set; }
}
变脸声明完了需要进行一个初始化的一个操作,将变量赋值
/// <summary>
/// 初始化PLC的配置数据,可以做成配置文件进行加载
/// </summary>
private void InitialPlcConfig()
{
PlcModel = new PlcEquipMentModel()
{
PlcName = "XXXXPLC",
PlcIpAddr = "192.168.1.100",//PLC的IP地址
PlcPort = 102,//西门子开放的OPC默认端口
PLCSiemenceType = 1200,//1200系列PLC和1500可以公用一套通讯协议
SoltNo = 0,//槽号正常是0 如果有带网口模块有可能是1
LinkRes = false
};
}
变量赋值完之后,我们程序运行起来就可以将线程启动,下面是线程启动的代码
/// <summary>
/// PLC通讯线程启动方法,可以在程序初始化完成之后启动
/// </summary>
private void TheadLoadStart()
{
PlcLinkTd = new Thread(PlcLinkFunc);
PlcLinkTd.Start();
}
再下面就是我们的一个PLC寄存器数据的一个读写线程
#region PLC线程处理
/// <summary>
/// PLC线程处理
/// </summary>
/// <param name="sender"></param>
private void PlcLinkFunc(object sender)
{
Ping p = new Ping();
simenceLink = new SimencePlcLinkHelper(PlcModel.PlcIpAddr, PlcModel.PlcPort, PlcModel.PLCSiemenceType, PlcModel.SoltNo);
int check_plc_link = 0;
int check_plc_link_1 = 0;
int re_link = 0;
int recordOnce = 0;
while (_continue)
{
try
{
if (!PlcModel.LinkRes)
{
#region 连接PLC
try
{
if (p.Send(PlcModel.PlcIpAddr, 200).Status == IPStatus.Success)
{
recordOnce = 0;
simenceLink.CloseLinkPLC();
Thread.Sleep(10);
simenceLink = new SimencePlcLinkHelper(PlcModel.PlcIpAddr, PlcModel.PlcPort, PlcModel.PLCSiemenceType, PlcModel.SoltNo);
bool res = simenceLink.OpenLinkPLC();
if (res)
{
PlcModel.LinkRes = true;
if (check_plc_link == 0)
{
check_plc_link = 1;
string logStr = string.Format("PLC 连接成功");
SaveLogStrRunTime(logStr);
}
}
else
{
if (check_plc_link_1 == 0)
{
check_plc_link_1 = 1;
PlcModel.link_Status = -1;
string logStr = string.Format("PLC 连接失败");
SaveLogStrRunTime(logStr);
}
}
}
else
{
if (recordOnce == 0)
{
recordOnce = 1;
string logStr = string.Format("PLC 连接 失败 原因Ping异常");
SaveLogStrRunTime(logStr);
}
PlcModel.link_Status = -2;
PlcModel.LinkRes = false;
}
}
catch (Exception ex)
{
PlcModel.link_Status = -1;
PlcModel.LinkRes = false;
}
#endregion
}
else
{
int RET = 0;
#region 读值
int readOnceLen = 200;
#region 读取PLC部分寄存器值
int[] PLC_UZ_W = new int[10];//用于存放读取上来的字节数据
RET = simenceLink.ReadPlcDBValue(10, 100, 0, out PLC_UZ_W);//10表示读取的字节长度个数 100表示读取的DB块索引 DB100 0表示寄存器读取的起始偏移量 总的为读取DB100.DBB0读取10个字节数据
if (RET != 0)
{
goto MYEND;
}
#endregion
#endregion
//认定为读值成功
PlcModel.link_Status = 1;
re_link = 0;
#region 此处做你需要的逻辑处理 读取的数据都存放在 PLC_UZ_W里面
#endregion
MYEND:
if (RET != 0)
{
re_link++;
if (re_link > 3)
{
re_link = 0;
PlcDataAllLineModel = new PlcDataLineValue[DeviceConfigAll.Length];
PlcModel.LinkRes = false;
PlcModel.link_Status = -1;
simenceLink.CloseLinkPLC();
}
}
}
}
catch (Exception ex)
{
SaveLogStrErr(ex.ToString());
}
Thread.Sleep(600);
}
}
#endregion
以上就是西门子PLC CPU的一个寄存器数据读取的线程
下面说一下字节数组转换成不同的类型方法
1、字节数组转成PLC内部的DINT方法
/// <summary>
/// 字节数组转成PLC内部的DINT方法
/// </summary>
private int byteArr4ToDint(byte[] byteData)
{
byte[] bt_0 = new byte[4];
for (int j = 0; j < bt_0.Length; j++)
{
bt_0[j] = (byte)intValueArr[3 - j];
}
int intTemp = BitConverter.ToInt32(bt_0, 0).ToString();
return intTemp;
}
2、字节数组转成PLC内部的INT方法
/// <summary>
/// 字节数组转成PLC内部的INT方法
/// </summary>
private int byteArr4ToDint(byte[] byteData)
{
byte[] bt_0 = new byte[2];
for (int j = 0; j < bt_0.Length; j++)
{
bt_0[j] = (byte)intValueArr[1 - j];
}
int intTemp = BitConverter.ToInt16(bt_0, 0).ToString();
return intTemp;
}
3、字节数据转成二进制的方法
#region 十进制转二进制
/// <summary>
/// 十进制转二进制 低位在前 1就是10000000
/// </summary>
/// <param name="intIn"></param>
/// <returns></returns>
public string OctoberToBinaryStr(int intIn)
{
string strIn = Convert.ToString(intIn, 2).PadLeft(8, '0');
string strTemp = "";
for (int i = 0; i < strIn.Length; i++)
{
strTemp += strIn[strIn.Length - i - 1];
}
return strTemp;
}
#endregion
最后
以上就是美满帆布鞋为你收集整理的C#各种PLC调用例子教程的全部内容,希望文章能够帮你解决C#各种PLC调用例子教程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复