工作中經常需要瞭解plcdb塊的數據!由於工作使用OPC類庫進行通訊,開發,配置,使用都比較麻煩, 特在網上找到一個名為PLCcom.dll的類庫,可以實現PLC讀寫操作,下麵演示C#如何使用PLCcom.dll類庫 首先看一下封裝對PLCcom調用的幫助類: using System;using ...
工作中經常需要瞭解plcdb塊的數據!由於工作使用OPC類庫進行通訊,開發,配置,使用都比較麻煩,
特在網上找到一個名為PLCcom.dll的類庫,可以實現PLC讀寫操作,下麵演示C#如何使用PLCcom.dll類庫
首先看一下封裝對PLCcom調用的幫助類:
using System;
using PLCcom;
using System.Data;
//using System.Windows.Forms;
namespace GetPlcInfo
{
/// <summary>
/// Description of PLCReadWriteHelper.
/// </summary>
public class PLCReadWriteHelper
{
#region 變數定義
private static PLCReadWriteHelper instance=null;//當前類實例
private ePLCType cpu = ePLCType.S7_300_400_compatibel;//cpu類型
private string ip = "192.168.150.201";//CpuIP
private short rack = 0;//機架號
private short slot = 3;//插槽號
public TCP_ISO_Device plc = null;//Plc對象
private const string user = "111";//用戶
private const string serial = "51135-21193-754111-1111111";//系列號
public delegate void OnErrorHandler(OnErrorEventArgs e);//發生錯誤委托
public event OnErrorHandler OnError;//發生錯誤事件
public delegate void SuccessHandler(SuccessedEventArgs e);//成功委托
public event SuccessHandler success;//成功事件
#endregion
#region 構造函數
public PLCReadWriteHelper(ePLCType type,string plcip,string plcRack,string plcsolt)
{
this.cpu=ePLCType.S7_300_400_compatibel;
this.ip=plcip;
this.rack=short.Parse( plcRack );
this.slot=short.Parse( plcsolt );
plc=new TCP_ISO_Device(ip,rack,slot,cpu);
authentication.User=user;
authentication.Serial =serial ;
}
#endregion
#region 連接
public void TestConnect()
{
try
{
if (instance!=null)
{
ConnectResult cr=plc.Connect();
//連接失敗
if (!cr.HasConnected)
{
if (OnError!=null)
{
OnError (new OnErrorEventArgs(string.Format("連接到PLC:{0}時,發生錯誤!{1}",this.ip,cr.Message)));
}
}
//成功!
else
{
if(success!=null)
{
success(new SuccessedEventArgs("PLC"+this.ip+"連接成功!"+cr.Message));
}
}
}
}
catch(Exception ex)
{
WriteError("連接失敗:"+ex.Message);
}
}
public void disconnect()
{
plc.DisConnect();
}
#endregion
#region 獲取時間
public DateTime GetCpuTime()
{
if (instance == null)
{
instance = GetInstance(ePLCType.Other,"192.168.0.4", "0", "1");
instance.plc.Connect();
}
ReadRequest[] request = new ReadRequest[1];
request[0] = new ReadRequest();
request[0].Region = eRegion.DataBlock;
request[0].StartByte = 0;
request[0].Len = 37;
request[0].DB = 10;
ReadResult[] res = plc.read(request);
if (!res[0].HasWorked)
{
WriteError("讀取CPU時間失敗:" + res[0].Message);
return DateTime.MinValue;
}
else
{
return res[0].get_DATE_AND_TIME();
}
}
#endregion
#region 獲得當前類的實例
/// <summary>
/// 靜態方法獲得此幫助類的實例
/// </summary>
/// <param name="type">cpu類型</param>
/// <param name="plcip">ip地址</param>
/// <param name="plcRack">機架號</param>
/// <param name="plcsolt">插槽號</param>
/// <returns></returns>
public static PLCReadWriteHelper GetInstance(ePLCType type,string plcip,string plcRack,string plcsolt)//此處偷了個懶寫了最簡單的單例,此處線程不安全!
{
lock (typeof(PLCReadWriteHelper))
{
if (instance == null)
{
instance = new PLCReadWriteHelper(type,plcip,plcRack,plcsolt );
return instance;
}
else
{
return instance;
}
}
}
#endregion
#region 讀PLC信息
public byte[] ReadPLC(int db,int Start,int Length)
{
byte[]readbytes=null;
try{
if (this.plc==null)
{
plc=new TCP_ISO_Device (ip,rack,slot,cpu);
plc.Connect();
}
ReadRequest[]request=new ReadRequest[1] ;
request[0]=new ReadRequest ();
request[0].Region=eRegion.DataBlock;
request[0].DB=db;
request[0].StartByte=Start;
request[0].Len=Length;
ReadResult[]res=plc.read(request);
if (!res[0].HasWorked)
{
this.plc=null;
}
readbytes=new byte[res[0].getBufferLen()];
int index=0;
while (res[0].dataAvailable())
{
readbytes[index++]+=res[0].get_Byte();
}
plc.DisConnect();
if (success !=null)
{
success(new SuccessedEventArgs("讀取CPU信息成功!"));
string result = null;
foreach(var n in readbytes)
{
result+=n.ToString()+"|";
}
if(result!=null)
{
success(new SuccessedEventArgs(result));
}
}
return readbytes;
}
catch(NullReferenceException) { return null; }
catch(Exception ex)
{
WriteError("讀取指定信息錯誤:"+ex.Message);
return null;
}
}
#endregion
#region 寫信息到DB塊
public WriteResult WritePLC(int db,int Start,byte[]wValue)
{
try
{
if (plc==null)
{
plc=new TCP_ISO_Device (ip,rack,slot,cpu);
plc.Connect();
}
WriteRequest[]writes=new WriteRequest[1];
writes[0]=new WriteRequest ();
writes[0].Region=eRegion.DataBlock;
writes[0].DB=db;
writes[0].StartByte=Start;
writes[0].addByte(wValue);
WriteResult[]wrs=plc.write(writes );
if (wrs[0].HasWorked != true)
{
this.plc = null;
}
return wrs[0];
}
catch (Exception ex)
{
WriteError("寫入信息錯誤:"+ex.Message);
return new WriteResult ();
}
}
#endregion
#region 拋出異常
void WriteError(string errmsg)
{
if (OnError!=null)
{
OnError(new OnErrorEventArgs (errmsg));
}
}
#endregion
#region byte數組轉換為字
public int[]ConvertToints(byte[]bt)
{
try
{
int []result = new int[(bt.Length / 2)];
for (int ii = 0; ii < result.Length; ii++)
{
result[ii] = Convert.ToInt16(bt[ii * 2]) * 256 + Convert.ToInt16(bt[ii * 2 + 1]);
}
return result;
}
catch(Exception ex)
{
WriteError("位元組數組轉換成int數組失敗:"+ex.Message);
return null;
}
}
#endregion
#region 自定義事件類
/// <summary>
/// 發生錯誤
/// </summary>
public class OnErrorEventArgs
{
string errMsg=string.Empty;
public OnErrorEventArgs(string errmsg)
{
this.errMsg=errmsg;
}
public string ErrMsg
{get{return this. errMsg;}
}
}
/// <summary>
/// 成功
/// </summary>
public class SuccessedEventArgs
{
string errMsg=string.Empty;
public SuccessedEventArgs(string errmsg)
{
this.errMsg=errmsg;
}
public string ErrMsg
{
get{return this. errMsg;}
}
}
#endregion
#region 讀取IO
public DateTime GetTime()
{
ReadResult rs= plc.GetPLCTime();
DateTime dt= rs.get_DATE_AND_TIME();
return dt;
}
public void readIO()
{
ReadRequest[] re = new ReadRequest[1];
re[0].Region = eRegion.Input;
re[0].Bit = 1;
re[0].StartByte = 253;
re[0].Len = 1;
ReadResult []rr= plc.read(re);
if ( rr[0].isBit)
{
// MessageBox.Show(rr[0].Buffer.ToString());
}
}
#endregion
public LEDInfoResult GetLEDINFO()
{
return plc.GetLEDInfo();
}
}
}
下麵看看如何進行調用:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Gaofajin.LogWrite;
namespace GetPlcInfo
{
class Program
{
static Timer t;
static TimerCallback tc;
static int time = 50;
static PLCReadWriteHelper helper;
static string last;
// public static object TxtLog { get; private set; }
static void Main(string[] args)
{
if(args.Length<=0)
{
Console.WriteLine("必須輸入IP地址:");
return;
}
if(args.Length==2)
{
int.TryParse(args[1],out time);
}
helper=new PLCReadWriteHelper(PLCcom.ePLCType.S7_300_400_compatibel,args[0],"0","2");//此示例演示的PLC為300系列故此處寫死槽號2,機架號0
helper.OnError+=new PLCReadWriteHelper.OnErrorHandler(error);
helper.success+=new PLCReadWriteHelper.SuccessHandler(success);
tc=new TimerCallback(getContent);
t=new Timer(tc,helper,0,time);
Console.WriteLine("後臺程式捕獲進程運行中!請勿關閉程式!");
Console.ReadLine();
}
private static void success(PLCReadWriteHelper.SuccessedEventArgs e)
{
Console.WriteLine(e.ErrMsg);
}
private static void error(PLCReadWriteHelper.OnErrorEventArgs e)
{
Console.WriteLine(e.ErrMsg);
}
private static void getContent(object obj)
{
try
{
t.Change(-1,-1);
helper.TestConnect();
byte[]bts= helper.ReadPLC(53,20,51);
string str = null;
foreach(byte b in bts)
{
str+=byteTostringChar(b).ToString()+"|";
}
if(last!=str)
{
TxtLog.WriteLineToTimeFile(str);
}
last=str;
}
catch(Exception ex)
{
// Console.WriteLine("發生錯誤:"+ex.Message);
}
finally
{
t.Change(0,time);
}
}
public static char byteTostringChar(byte b)
{
return ((Char)b);
}
}
}