在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例常规C/C++编程 → PLC上使用OPC和计算机通信例子

PLC上使用OPC和计算机通信例子

常规C/C++编程

下载此实例
  • 开发语言:C/C++
  • 实例大小:0.10M
  • 下载次数:74
  • 浏览次数:880
  • 发布时间:2016-10-17
  • 实例类别:常规C/C++编程
  • 发 布 人:hdg3707
  • 文件格式:.rar
  • 所需积分:2
 相关标签: c 通信 计算机 计算

实例介绍

【实例简介】OPC(OLE for Process Control, 用于过程控制的OLE)是一个工业标准,管理这个标准国际组织是OPC基金会,OPC基金会现有会员已超过220家。遍布全球,包括世界上所有主要的自动化控制系统、仪器仪表及过程控制系统的公司。基于微软的OLE(现在的Active X)、COM (部件对象模型)和DCOM (分布式部件对象模型)技术。OPC包括一整套接口、属性和方法的标准集,用于过程控制和制造业自动化系统。
【实例截图】
【核心代码】
BOOL COPCDEMODlg::InitOPCServer()
{
    CLSID clsid;
 HRESULT hr = S_OK;
 CString strServer = _T("S7200.OPCServer");  //OPC.SimaticNET S7200.OPCServer

 /*初始化COM库*/
 if (FAILED(::CoInitialize(NULL)))
 {
  AfxMessageBox(_T("Error during CoInitialize"), MB_OK );
        return FALSE;
 }
 
 /*查找OPC服务*/
 hr = CLSIDFromProgID( strServer.AllocSysString(), &clsid );
 if( FAILED(hr))
 {
        AfxMessageBox(_T("Error during CLSIDFromProgID"), MB_OK);
        return FALSE;
 }
 
 /*创建OPC服务器对象*/
 LPUNKNOWN pUnkn = NULL; 
 hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER , IID_IOPCServer, (void**)&m_IOPCServer); //CLSCTX_LOCAL_SERVER CLSCTX_ALL
 if( FAILED(hr) || m_IOPCServer == NULL)
 {
        AfxMessageBox(_T("Error during CoCreateInstance"), MB_OK);
        return FALSE;
 }

 /*添加组到OPC服务器*/
 FLOAT PercentDeadband = 0.0;
 DWORD RevisedUpdateRate;
 hr = m_IOPCServer->AddGroup(
  L"group",                 //[in]  组名
        TRUE,                    //[in]  活动状态
        500,                     //[in]  向服务器发送请求的刷新率
        1,                       //[in]  客户端的操作句柄
        NULL,                    //[in]  与标准时间的校正值
        &PercentDeadband,        //[in]  要舍弃的数据 
        0,                       //[in]  服务器使用的语言
        &m_GrpSrvHandle,         //[out] 添加组以后服务器返回的组句柄
        &RevisedUpdateRate,      //[out] 服务器的数据刷新率 
        IID_IOPCItemMgt,         //[in]  添加组的接口类型
        (LPUNKNOWN*)&m_IOPCItemMgt);  //[out] 服务器返回的接口对象指针
 if( FAILED(hr) )
 { 
  LPWSTR pErrString;
        AfxMessageBox(_T("Error during AddGroup"), MB_OK);
  hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
  if(SUCCEEDED(hr))
  {
   //输出错误信息
  }
  else
  {
   //pErrString = "添加组失败.";
  }
  m_IOPCServer->Release();
  m_IOPCServer=NULL;
  CoUninitialize();
        return FALSE;
 }
 
/* CString TableStr[COUNT]= {
      "进球",      //VB0
   "进球到位",  //VB1
   "合格",
   "不合格",
   "出球结束",
   "复位",
   "其他故障",
   "运行",      //VB7
   "MB0",
   "MB1"

 };
*/
 CString TableStr[COUNT]= {"NewItem"};

 Item*  pcItem ;
 
 OPCITEMDEF *m_Items = new OPCITEMDEF[COUNT];                   //项的存取路径, 定义和被请求的数据类等
 int i;
 for(i = 0; i < COUNT; i )
 {
  pcItem = new Item;
  pcItem->quality = QUAL_BAD;
  
  
 // pcItem->name = _T("" TableStr[i]);      //设置opc节点 Microwin.NewPLC.group.
  pcItem->name = _T("Microwin.NewPLC.group.NewItem1");
  m_Items[i].szItemID = pcItem->name.AllocSysString();
  m_Items[i].dwBlobSize = 0;
  m_Items[i].pBlob = NULL;
  m_Items[i].bActive = TRUE;
  m_Items[i].hClient = (OPCHANDLE)pcItem;
  m_Items[i].szAccessPath = pcItem->cAccessPath.AllocSysString();;                             //pcItem->cAccessPath.AllocSysString();
  m_Items[i].vtRequestedDataType = VT_EMPTY;                       //VT_EMPTY;
 }

 /*添加项目*/
    OPCITEMRESULT *pOPCResults = NULL;
 HRESULT *pOPCErrors = NULL;
    hr = m_IOPCItemMgt->AddItems(COUNT,
  m_Items,
  &pOPCResults,
  &pOPCErrors);
 if(FAILED(hr))
 {
  LPWSTR pErrString;
        AfxMessageBox(_T("Error during AddGroup"), MB_OK);
  hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
  if(SUCCEEDED(hr))
  {
   
   //输出错误信息
  }
  else
  {
   //pErrString = "添加组失败.";
  }
  m_IOPCServer->Release();
  m_IOPCServer=NULL;
  CoUninitialize();
        return FALSE;
 }
 AfxMessageBox(_T("添加项目成功."));
 
 /*保存item对应的服务句柄*/
 pdwServerHandles = new DWORD[COUNT];
 for(i = 0; i < COUNT; i )
 {
  pdwServerHandles[i] = pOPCResults[i].hServer;
        if(pOPCErrors[i]= S_OK)
  {
   pdwServerHandles[i] = pOPCResults[i].hServer; 
  }
 }

 /*获取同步IO口*/
 hr = m_IOPCItemMgt->QueryInterface(IID_IOPCSyncIO, (void**)&m_IOPCSyncIO);
    if(FAILED(hr))
 {
  LPWSTR pErrString;
        AfxMessageBox(_T("获取IO口失败"), MB_OK);
  hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
  if(SUCCEEDED(hr))
  {
   
   //输出错误信息
  }
  else
  {
   //pErrString = "获取IO口失败.";
  }
  m_IOPCServer->Release();
  m_IOPCServer=NULL;
  CoUninitialize();
        return FALSE;
 }

   // delete[] pdwServerHandles;
// delete[] m_Items;
// delete pcItem;
 return TRUE;  //初始化完成,可以开始查询.
}

/* 读取OPC服务器中的状态信息
*  phServe:  读取项的句柄
*  dwSource: 状态获取来源,缓存、内存
*/
BOOL COPCDEMODlg::ReadOPCServe(OPCITEMSTATE **pValues, OPCHANDLE *phServe, OPCDATASOURCE dwSource)
{
 HRESULT hr = S_OK;
    OPCHANDLE *phserve = phServe;

 LPWSTR pErrString; //记录错误信息字符串
 HRESULT *pErrors= new HRESULT;

 try
 {
  hr = m_IOPCSyncIO->Read(
   dwSource,          // OPC_DS_CACHE, Source (device or cache)
   1,//cdwItems,           // Item count
   (OPCHANDLE*)phServe, // Array of server handles for items
   pValues,             // Array of values
   &pErrors);             // Array of errors
        if(FAILED(hr))
     {    
            AfxMessageBox(_T("Error during ReadOPC"), MB_OK);
      hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
      if(SUCCEEDED(hr))
      {
       //pErrString输出错误信息
      }
      else
      {
       //pErrString = "添加组失败.";
      }
      m_IOPCServer->Release();
      m_IOPCServer=NULL;
      CoUninitialize();
            return FALSE;
     }

  
 }
 catch(...)
 {
 
 }
 
// delete pErrors;
 return  TRUE; 
}

/*写入OPC服务器中的状态信息
 *后续需要再写 OPCITEMSTATE **pValues, OPCHANDLE *phServe, OPCDATASOURCE dwSource
 */
BOOL COPCDEMODlg::WriteOPCServe(OPCHANDLE *phServe,  BYTE Values)
{
 HRESULT hr = S_OK;
 VARIANT *pItemValues = new VARIANT;
 OPCHANDLE *phserve = phServe;
 HRESULT *pErrors= new HRESULT;
 LPWSTR pErrString;

    VariantClear(pItemValues);
 memset(pItemValues, 0, sizeof(VARIANT));
    pItemValues->vt = VT_I2;
 short value = Values;
    pItemValues->bVal = value;

 try
 {
        hr = m_IOPCSyncIO->Write(1,
                               phserve,
                               pItemValues,
                               &pErrors);
  if(FAILED(hr))
     {    
      hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
      if(SUCCEEDED(hr))
      {
       //pErrString输出错误信息
      }
      else
      {
       //pErrString = "添加组失败.";
      }
      m_IOPCServer->Release();
      m_IOPCServer=NULL;
      CoUninitialize();
            return FALSE;
     }
 }
 catch(...)
 {}
// delete pErrors;
 
 return TRUE;
}

/* 检查状态位是否正常
 * pValues: 用于传递从OPC Server获得的状态信息
 * type:    用于区别位和字节状态信息 1:位 0:字节
 * bit:    用于指示位状态信息的操作位 eg:M1的M1.x;
            8:代表字节状态, 0-7代表位状态
*/
BOOL COPCDEMODlg::ChkState(OPCITEMSTATE* pValues, int type, int bit)
{
    BYTE state = 0;
 if(pValues->wQuality == QUAL_BAD)
 {
  //记录log 数据质量差
 // return FALSE;
 }
 else if(VT_EMPTY == V_VT(&pValues->vDataValue))
 {
  //没有获取到有效地数据
 // return FALSE;
 }
 else
 {}

    switch(bit)
 {
        case 0:  state = pValues->vDataValue.boolVal & 1;   break;
        case 1:  state = pValues->vDataValue.boolVal & 2;   break;
  case 2:  state = pValues->vDataValue.boolVal & 4;   break;
  case 3:  state = pValues->vDataValue.boolVal & 8;   break;
  case 4:  state = pValues->vDataValue.boolVal & 16;  break;
  case 5:  state = pValues->vDataValue.boolVal & 32;  break;
  case 6:  state = pValues->vDataValue.boolVal & 64;  break;
  case 7:  state = pValues->vDataValue.boolVal & 128; break; 
        default: state = pValues->vDataValue.bVal;          break; 
    } 
   
    if(type == 1) //BIT
 {
    
     return  (state == 1) ? TRUE : FALSE;
 }
 else if(type = 2) //BYTE
 {
     return (state == 0xFF) ? TRUE : FALSE;

 }
 else
 {
     //请检查输入类型是否正确
     return FALSE;
 }
}
   
void COPCDEMODlg::OnButton1()
{
 // TODO: Add your control notification handler code here
 BOOL ret;

    ret = InitOPCServer();
 if(ret == FALSE)
 {
  return;
 }
 AfxMessageBox("初始化完成!");
 /*
 //OPCDATASOURCE dwSource = bDeviceRead ? OPC_DS_DEVICE : OPC_DS_CACHE;
 OPCITEMSTATE *pValues = new OPCITEMSTATE; //保存读取的状态值
 ret = ReadOPCServe(&pValues, &pdwServerHandles[0], OPC_DS_CACHE); //pValues初始化与操作后地址不一致
 if(ret == FALSE)
 {
  return;
 }

    ret = ChkState(pValues, 0, 0);
 if(ret == FALSE)
 {
  return;
 }
 ReleaseSource();
*/ return;
}

/*
* 释放资源
*/
void COPCDEMODlg::ReleaseSource()
{
 // 释放同步接口
 if(m_IOPCSyncIO != NULL)
 {
  m_IOPCSyncIO->Release();
  m_IOPCSyncIO = NULL;
 }
 // 释放item管理接口
 if(m_IOPCItemMgt != NULL)
 {
  m_IOPCItemMgt->Release();
  m_IOPCItemMgt = NULL;
 }
 
 // 释放 OPC服务器
 if(m_IOPCServer != NULL)
 {
  m_IOPCServer->Release();
  m_IOPCServer = NULL;
 }
   
 //关闭COM库
 ::CoUninitialize();
}
BOOL COPCDEMODlg::foo()
{
 int ret = 10;
 return ret == 10 ? TRUE : FALSE;
}


void COPCDEMODlg::OnButton2()
{
 // TODO: Add your control notification handler code here

 BOOL ret;
 OPCITEMSTATE *pValues = new OPCITEMSTATE; //保存读取的状态值
 //OPCDATASOURCE dwSource = bDeviceRead ? OPC_DS_DEVICE : OPC_DS_CACHE;
 ret = ReadOPCServe(&pValues, &pdwServerHandles[0], OPC_DS_CACHE); //pValues初始化与操作后地址不一致 OPC_DS_DEVICE : OPC_DS_CACHE
 if(ret == FALSE)
 {

  return;
 }

    ret = ChkState(pValues, 0, 8);
 AfxMessageBox("检查状态完成!");
 if(ret == FALSE)
 {
  return;
 }
    AfxMessageBox("检查状态完成!");
// delete pValues;
}



void COPCDEMODlg::OnButton3()
{
 // TODO: Add your control notification handler code here
 ReleaseSource();
}

void COPCDEMODlg::OnButton4()
{
 // TODO: Add your control notification handler code here
 BOOL ret;
    ret= WriteOPCServe(&pdwServerHandles[0],  0xFF) ;
 if(ret == FALSE)
 {
  return;
 }
}

标签: c 通信 计算机 计算

实例下载地址

PLC上使用OPC和计算机通信例子

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警