西门子代理商_西门子变频器总代理-翰粤百科

咨詢熱線

18621916738

當(dāng)前位置:首頁(yè)  >  技術(shù)文章  >  運(yùn)用VC#編程通過(guò)OPC方式實(shí)現(xiàn)PC機(jī)與西門(mén)子PLC通訊

運(yùn)用VC#編程通過(guò)OPC方式實(shí)現(xiàn)PC機(jī)與西門(mén)子PLC通訊

更新時(shí)間:2016-01-06      點(diǎn)擊次數(shù):1746

運(yùn)用VC#編程通過(guò)OPC方式實(shí)現(xiàn)PC機(jī)與西門(mén)子PLC通訊

1、 配置OPC服務(wù)器
  對(duì)于服務(wù)器的配置與同步通訊的配置一樣,這里不需再講解,若有不清楚的,可以參閱之前發(fā)布的<運(yùn)用VC#編程通過(guò)OPC方式實(shí)現(xiàn)PC機(jī)與西門(mén)子PLC通訊>

2、 OPC編程
  變量組、項(xiàng)的命名規(guī)則與同步通訊的一樣,這里不再描敘,下面主要就開(kāi)發(fā)一個(gè)異步通訊類(lèi) AsynServer來(lái)講解如何編程。

<1>、引用
  在VC#開(kāi)發(fā)環(huán)境中添加對(duì)OpcRcw.Da庫(kù)以及OpcRcw.Comn庫(kù)的引用,該庫(kù)屬于.NET庫(kù),不屬于COM庫(kù),西門(mén)子雖然編寫(xiě)了類(lèi)庫(kù),以提供對(duì).NET平臺(tái)的支持,但這些類(lèi)庫(kù)仍然難于編程,里面包含了大量的在托管和非托管區(qū)傳輸數(shù)據(jù),因此我們需要在它的基礎(chǔ)上再開(kāi)發(fā)一個(gè)類(lèi)庫(kù),以簡(jiǎn)化以后的編程,首先在類(lèi)的開(kāi)頭使用命名空間:
using OpcRcw.Comn;
using OpcRcw.Da;
using System.Runtime.InteropServices;
using System.Collections;

<2>、編程
  異步編程的原理就是在OPC服務(wù)器那邊檢測(cè)當(dāng)前活動(dòng)的變量組,一但檢測(cè)到某一個(gè)變量,譬如變量Q0.0從1變成0,就會(huì)執(zhí)行一個(gè)回調(diào)函數(shù),以實(shí)現(xiàn)針對(duì)變量發(fā)生變化時(shí)需要實(shí)現(xiàn)的動(dòng)作,在這里可以采用委托來(lái)實(shí)現(xiàn)該功能。

  1、 在命名空間的內(nèi)部、類(lèi) AsynServer聲明之前添加委托的申明:
// 定義用于返回發(fā)生變化的項(xiàng)的值和其對(duì)應(yīng)的客戶句柄
public delegate void DataChange(object[] values,int[] itemsID);

  2、 該類(lèi)繼承于西門(mén)子提供的庫(kù)接口IOPCDataCallback
public class AsynServer:IOPCDataCallback
在類(lèi)的開(kāi)頭部分聲明變量:
struct groupStru
{
public int groupID;
public object groupObj;
}
internal const int LOCALE_ID = 0x407; //本地語(yǔ)言
private Guid iidRequiredInterface;
private string serverType="";
private int hClientGroup = 0; //客戶組號(hào)
private int nSvrGroupID; // server group handle for the added group 
private Hashtable hashGroup; //用于把組收集到一起
private int hClientItem=0; //Item號(hào)

   3、編寫(xiě)構(gòu)造函數(shù),接收委托參數(shù)已確定當(dāng)數(shù)據(jù)發(fā)生變化時(shí)需要執(zhí)行的方法入口點(diǎn):
//創(chuàng)建服務(wù)器
//svrType 服務(wù)器類(lèi)型的枚舉
//dataChange 提供用于在數(shù)據(jù)發(fā)生變化時(shí)需要執(zhí)行的函數(shù)入口
public AsynServer(ServerType svrType,DataChange dataChange)
{
switch(svrType)
{
case ServerType.OPC_SimaticHMI_PTPR
serverType="OPC.SimaticHMI.PTPro";break;
case ServerType.OPC_SimaticNET:
serverType="OPC.SimaticNET";break;
case ServerType.OPC_SimaticNET_DP:
serverType="OPC.SimaticNET.DP";break;
case ServerType.OPC_SimaticNET_PD:
serverType="OPC.SimaticNET.PD";break;
case ServerType.OPCServer_WinCC:
serverType="OPCServer.WinCC";break;

}
hashGroup=new Hashtable(11);
dtChange=dataChange;
}
  
  4、創(chuàng)建服務(wù)器
// 創(chuàng)建一個(gè)OPC Server接口
//error 返回錯(cuò)誤信息
//若為true,創(chuàng)建成功,否則創(chuàng)建失敗
public bool Open(out string error)
{
error="";bool success=true;
Type svrComponenttyp ;
//獲取 OPC Server COM 接口
iidRequiredInterface = typeof(IOPCItemMgt).GUID;
svrComponenttyp = System.Type.GetTypeFromProgID(serverType);
try
{
//創(chuàng)建接口
pIOPCServer =(IOPCServer)System.Activator.CreateInstance(svrComponenttyp);
error="";
}
catch (System.Exception err) //捕捉失敗信息
{
error="錯(cuò)誤信息:"+err.Message;success=false;
}
return success;
}

  5、 編寫(xiě)添加Group的函數(shù)
///


/// 添加組
/// 
/// 組名
/// /創(chuàng)建時(shí),組是否被激活
/// //組的刷新頻率,以ms為單位
/// 返回錯(cuò)誤信息
/// 若為true,添加成功,否則添加失敗
public bool AddGroup(string groupName,int bActive,int updateRate,out string error)

error="";bool success=true;
int dwLCID = 0x407; //本地語(yǔ)言為英語(yǔ) 
int pRevUpdateRate;
float deadband = 0;
// 處理非托管COM內(nèi)存
GCHandle hDeadband;
IntPtr pTimeBias = IntPtr.Zero;
hDeadband = GCHandle.Alloc(deadband,GCHandleType.Pinned);
try
{
pIOPCServer.AddGroup(groupName, //組名
bActive, //創(chuàng)建時(shí),組是否被激活
updateRate, //組的刷新頻率,以ms為單位
hClientGroup, //客戶號(hào)
pTimeBias, //這里不使用
(IntPtr)hDeadband,
dwLCID, //本地語(yǔ)言
out nSvrGroupID, //移去組時(shí),用到的組ID號(hào)
out pRevUpdateRate, //返回組中的變量改變時(shí)的zui短通知時(shí)間間隔
ref iidRequiredInterface,
out pobjGroup1); //指向要求的接口
hClientGroup=hClientGroup+1; 
groupStru grp=new groupStru();
grp.groupID=nSvrGroupID;grp.groupObj=pobjGroup1;
this.hashGroup.Add(groupName,grp);//儲(chǔ)存組信息
// 對(duì)異步操作設(shè)置回調(diào),初始化接口
pIConnectionPointContainer = (IConnectionPointContainer)pobjGroup1;
Guid iid = typeof(IOPCDataCallback).GUID;
pIConnectionPointContainer.FindConnectionPoint(ref iid,out pIConnectionPoint);
pIConnectionPoint.Advise(this,out dwCookie);
}
catch (System.Exception err) //捕捉失敗信息
{
error="錯(cuò)誤信息:"+err.Message;success=false;
}
finally
{
if (hDeadband.IsAllocated) hDeadband.Free();
}
return success;
}

  6、 編寫(xiě)激活、或者取消激活組的函數(shù)

  在同步編程中對(duì)于組的激活或者取消激活沒(méi)有實(shí)質(zhì)的意義,但在異步通訊編程中卻異常重要,這是因?yàn)镺PC服務(wù)器只對(duì)當(dāng)前處于活動(dòng)狀態(tài)的組中的變量進(jìn)行監(jiān)控,同時(shí)這也是很有必要的,因?yàn)槲覀兛梢园巡煌缑嬷械淖兞烤幊滩煌慕M,即同一界面中的變量規(guī)成一個(gè)組,而在某一時(shí)刻提供給用戶的只有一個(gè)界面,讓該界面中用到的組處于活動(dòng)狀態(tài),這樣執(zhí)行委托調(diào)用時(shí)只會(huì)執(zhí)行于該界面中有關(guān)的變量檢測(cè),而如果讓所有的組處于活動(dòng)狀態(tài),則當(dāng)前沒(méi)有顯示給用戶的界面用到的變量若發(fā)生變化也會(huì)觸發(fā)對(duì)委托函數(shù)的調(diào)用,這根本是沒(méi)有必要的,同時(shí)會(huì)大大降低程序的性能,請(qǐng)嚴(yán)格控制組的激活。
///
/// 激活或者取消激活組
/// 
/// 組名
/// true為激活,false為取消激活
/// 若有錯(cuò)誤,返回錯(cuò)誤信息
/// 若為true,添加成功,否則添加失敗
public bool AciveGroup(string groupName,bool toActive,out string error)
{
error="";bool success=true;
//通過(guò)名稱獲取組
object grp=((groupStru)hashGroup[groupName]).groupObj;
IOPCGroupStateMgt groupStateMgt=(IOPCGroupStateMgt)grp;
//初始化傳遞參數(shù)
IntPtr pRequestedUpdateRate = IntPtr.Zero; //由客戶的Item更新間隔時(shí)間
int nRevUpdateRate = 0; //由服務(wù)器返回的能夠更新的zui短時(shí)間間隔
IntPtr hClientGroup = IntPtr.Zero; //客戶組
IntPtr pTimeBias = IntPtr.Zero;
IntPtr pDeadband = IntPtr.Zero;
IntPtr pLCID = IntPtr.Zero; 

// 激活或者取消激活組
int nActive = 0; 
GCHandle hActive = GCHandle.Alloc(nActive,GCHandleType.Pinned);
if(toActive)
hActive.Target = 1;
else
hActive.Target = 0;
try 
{
groupStateMgt.SetState(pRequestedUpdateRate,out nRevUpdateRate,hActive.AddrOfPinnedObject(),pTimeBias,pDeadband,pLCID,hClientGroup); 
}
catch(System.Exception err)
{
error="錯(cuò)誤信息:"+err.Message;success=false;
}
finally
{
hActive.Free(); 
}
return success;
}

7、 向的組中添加變量的函數(shù)
///
/// 向的組添加一系列項(xiàng)
/// 
/// 組名
/// 完整的item名數(shù)組
/// 由服務(wù)器返回讀寫(xiě)數(shù)據(jù)時(shí)需要使用的item號(hào)
/// 無(wú)錯(cuò)誤,返回true,否則返回false
public bool AddItems(string groupName,string[] iteame,int[] itemsID)
{
bool success=true;
OPCITEMDEF[] ItemDefArray=new OPCITEMDEF[iteame.Length];
for(int i=0;i {
hClientItem=hClientItem+1; //客戶項(xiàng)自動(dòng)加1
ItemDefArray[i].szAccessPath = ""; // 可選的通道路徑,對(duì)于Simatiic Net不需要。
ItemDefArray[i].szItemID = iteame[i]; // ItemID, see above
ItemDefArray[i].bActive = 1; // item is active
ItemDefArray[i].hClient = hClientItem; // client handle ,在OnDataChange中會(huì)用到
ItemDefArray[i].dwBlobSize = 0; // blob size
ItemDefArray[i].pBlob = IntPtr.Zero; // pointer to blob 
ItemDefArray[i].vtRequestedDataType = 4; //DWord數(shù)據(jù)類(lèi)型
}
//初始化輸出參數(shù)
IntPtr pResults = IntPtr.Zero;
IntPtr pErrors = IntPtr.Zero;
try 
{
// 添加項(xiàng)到組
object grp=((groupStru)hashGroup[groupName]).groupObj;
((IOPCItemMgt)grp).AddItems(iteame.Length,ItemDefArray,out pResults,out pErrors);

int[] errors = new int[iteame.Length]; 
IntPtr pos = pResults;
Marshal.Copy(pErrors, errors, 0,iteame.Length);
for(int i=0;i {
if (errors[i] == 0)
{
OPCITEMRESULT result = (OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OPCITEMRESULT));
itemsID[i] = result.hServer; 
pos = new IntPtr(pos.ToInt32() + Marshal.SizeOf(typeof(OPCITEMRESULT)));
}
else
{
String pstrError;
pIOPCServer.GetErrorString(errors[0],0x407,out pstrError); 
success=false;
break;
}
}
SetItenClient(groupName,itemsID,itemsID); //要求始終只有一個(gè)組被激活,才不會(huì)引起沖突。
}
catch (System.Exception err) // catch for error in adding items.
{
success=false;
//error="錯(cuò)誤信息:"+error+err.Message;
}
finally
{
// 釋放非托管內(nèi)存
if(pResults != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(pResults);
pResults = IntPtr.Zero;
}
if(pErrors != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(pErrors);
pErrors = IntPtr.Zero; 
}
}
return success;
}

聯(lián)系我們

上海翰粵自動(dòng)化系統(tǒng)有限公司 公司地址:上海市松江區(qū)思賢路2399弄137號(hào)   技術(shù)支持:化工儀器網(wǎng)
  • 聯(lián)系人:黃政武
  • QQ:76868608
  • 公司傳真:021-57657276
  • 郵箱:76868608@qq.com

掃一掃 更多精彩

微信二維碼

網(wǎng)站二維碼

主站蜘蛛池模板: 走心机厂家,数控走心机-台州博城智能科技有限公司 | 标准件-非标紧固件-不锈钢螺栓-非标不锈钢螺丝-非标螺母厂家-三角牙锁紧自攻-南京宝宇标准件有限公司 | 活性炭-果壳木质煤质柱状粉状蜂窝活性炭厂家价格多少钱 | 淘趣英语网 - 在线英语学习,零基础英语学习网站 | 全自动包装秤_全自动上袋机_全自动套袋机_高位码垛机_全自动包装码垛系统生产线-三维汉界机器(山东)股份有限公司 | ?水马注水围挡_塑料注水围挡_防撞桶-常州瑞轩水马注水围挡有限公司 | 缠膜机|缠绕包装机|无纺布包装机-济南达伦特机械设备有限公司 | 【中联邦】增稠剂_增稠粉_水性增稠剂_涂料增稠剂_工业增稠剂生产厂家 | 比亚迪叉车-比亚迪电动叉车堆垛车托盘车仓储叉车价格多少钱报价 磁力去毛刺机_去毛刺磁力抛光机_磁力光饰机_磁力滚抛机_精密金属零件去毛刺机厂家-冠古科技 | 伶俐嫂培训学校_月嫂培训班在哪里报名学费是多少_月嫂免费政府培训中心推荐 | 水性绝缘漆_凡立水_绝缘漆树脂_环保绝缘漆-深圳维特利环保材料有限公司 | 郑州大巴车出租|中巴车租赁|旅游大巴租车|包车|郑州旅游大巴车租赁有限公司 | ISO9001认证咨询_iso9001企业认证代理机构_14001|18001|16949|50430认证-艾世欧认证网 | 烟台螺纹,烟台H型钢,烟台钢材,烟台角钢-烟台市正丰金属材料有限公司 | 金属软管_不锈钢金属软管_巩义市润达管道设备制造有限公司 | 印刷人才网 印刷、包装、造纸,中国80%的印刷企业人才招聘选印刷人才网! | 洗石机-移动滚筒式,振动,螺旋,洗矿机-青州冠诚重工机械有限公司 | 工业设计,人工智能,体验式3D展示的智能技术交流服务平台-纳金网 J.S.Bach 圣巴赫_高端背景音乐系统_官网 | 口信网(kousing.com) - 行业资讯_行业展会_行业培训_行业资料 | 筒瓦厂家-仿古瓦-寺庙-古建琉璃瓦-宜兴市古典园林建筑陶瓷厂有限公司 | 外贸资讯网 - 洞悉全球贸易,把握市场先机 | HDPE储罐_厂家-山东九州阿丽贝防腐设备| 深圳货架厂家_金丽声精品货架_广东金丽声展示设备有限公司官网 | CTAB,表面活性剂1631溴型(十六烷基三甲基溴化铵)-上海升纬化工原料有限公司 | 除湿机|工业除湿机|抽湿器|大型地下室车间仓库吊顶防爆除湿机|抽湿烘干房|新风除湿机|调温/降温除湿机|恒温恒湿机|加湿机-杭州川田电器有限公司 | 华夏医界网_民营医疗产业信息平台_民营医院营销管理培训 | 骨灰存放架|骨灰盒寄存架|骨灰架厂家|智慧殡葬|公墓陵园管理系统|网上祭奠|告别厅智能化-厦门慈愿科技 | 动库网动库商城-体育用品专卖店:羽毛球,乒乓球拍,网球,户外装备,运动鞋,运动包,运动服饰专卖店-正品运动品网上商城动库商城网 - 动库商城 | 破碎机_上海破碎机_破碎机设备_破碎机厂家-上海山卓重工机械有限公司 | 无锡门窗-系统门窗-阳光房-封阳台-断桥铝门窗厂[窗致美] | 黄石妇科医院_黄石东方女子医院_黄石东方妇产医院怎么样 | 球盟会·(中国)官方网站 | hc22_hc22价格_hc22哈氏合金—东锜特殊钢 | 环氧乙烷灭菌器_压力蒸汽灭菌器_低温等离子过氧化氢灭菌器 _低温蒸汽甲醛灭菌器_清洗工作站_医用干燥柜_灭菌耗材-环氧乙烷灭菌器_脉动真空压力蒸汽灭菌器_低温等离子灭菌设备_河南省三强医疗器械有限责任公司 | 行吊_电动单梁起重机_双梁起重机_合肥起重机_厂家_合肥市神雕起重机械有限公司 | 选矿设备-新型重选设备-金属矿尾矿重选-青州冠诚重工机械有限公司 | 高精度-恒温冷水机-螺杆式冰水机-蒸发冷冷水机-北京蓝海神骏科技有限公司 | 桌上式超净工作台-水平送风超净工作台-上海康路仪器设备有限公司 | KBX-220倾斜开关|KBW-220P/L跑偏开关|拉绳开关|DHJY-I隔爆打滑开关|溜槽堵塞开关|欠速开关|声光报警器-山东卓信有限公司 | 打造全球沸石生态圈 - 国投盛世 锂电混合机-新能源混合机-正极材料混料机-高镍,三元材料混料机-负极,包覆混合机-贝尔专业混合混料搅拌机械系统设备厂家 | CTAB,表面活性剂1631溴型(十六烷基三甲基溴化铵)-上海升纬化工原料有限公司 |