操作系统:Windows 7旗舰版 开发工具:VS2010 开发语言:MFC 描述:对S7-200的VD100-VD220的31个双字寄存器进行写; #pragma once #include "StdAfx.h" const LPWSTR g_szItemID[31] = {L"2, VD100, real", L"2, VD104, real", L"2, VD108, real", L"2, VD112, real", L"2, VD116, real", L"2, VD120, real", L"2, VD124, real", L"2, VD128, real", L"2, VD132, real", L"2, VD136, real", L"2, VD140, real", L"2, VD144, real", L"2, VD148, real", L"2, VD152, real", L"2, VD156, real", L"2, VD160, real", L"2, VD164, real", L"2, VD168, real", L"2, VD172, real", L"2, VD176, real",//VD164 L"2, VD180, real", L"2, VD184, real", L"2, VD188, real", L"2, VD192, real", L"2, VD196, real", L"2, VD200, real", L"2, VD204, real", L"2, VD208, real", L"2, VD212, real", L"2, VD216, real", L"2, VD220, real"}; class COPCComm { public: COPCComm(void); ~COPCComm(void); public: DWORD m_dwAdvise; OPCITEMDEF m_Items[31]; VARIANT m_ItemValues[31]; LPWSTR m_ItemID[31]; OPCITEMATTRIBUTES *m_pItAttr; IUnknown* m_pUnknown; IOPCServer* m_IOPCServer; IOPCItemMgt* m_IOPCItemMgt; IOPCSyncIO* m_pOPCSync; IOPCGroupStateMgt* m_IOPCGroupStateMgt; IOPCAsyncIO2* m_IOPCAsyncIO2; OPCITEMRESULT* m_ItemResult; HRESULT* m_pErrors; OPCHANDLE m_GrpSrvHandle; MULTI_QI m_arrMultiQI[6]; DWORD m_TransactionID; OPCITEMDEF* m_pItems; OPCITEMSTATE* bdg; public: bool ConnectSrv(void); bool Disconnect(void); bool AddGroup(void); bool AddItem(DWORD NumItems); bool Write(DWORD NumItems); bool RemoveGroup(void); bool RemovItem(DWORD NumItems); float Read(DWORD NumItems); }; 源文件:OPCComm.cpp #include "StdAfx.h" #include "OPCComm.h" COPCComm::COPCComm(void) { int i; m_pItAttr = new OPCITEMATTRIBUTES[31]; for(i = 0; i < 31; i++) { m_pItAttr[i].szItemID = L""; m_pItAttr[i].szAccessPath = L""; m_pItAttr[i].hClient = 0; m_pItAttr[i].hServer = 0; m_pItAttr[i].dwAccessRights = -1; m_pItAttr[i].bActive = FALSE; } m_IOPCServer = NULL; m_IOPCItemMgt = NULL; } COPCComm::~COPCComm(void) { if(m_pItAttr != NULL) { delete[] m_pItAttr; } } bool COPCComm::ConnectSrv() { // TODO: Add your control notification handler code here CLSID OPCclsid; HRESULT r1; /* r1 = CoInitialize(NULL); if (r1 != S_OK) { if (r1 == S_FALSE) { AfxMessageBox(_T("COM库已经初始化")); return true; } else { AfxMessageBox(_T("COM库初始化失败")); return true;; } } */ r1 = CLSIDFromProgID(L"S7200.OPCServer",&OPCclsid); if(S_OK!=r1) { if(CO_E_CLASSSTRING == r1) { AfxMessageBox(_T("The ProgID is invalid!")); return true; } else if(REGDB_E_WRITEREGDB == r1) { AfxMessageBox(_T("Regedit occurs an error!")); return true; } } r1 = CoCreateInstance(OPCclsid, NULL, CLSCTX_LOCAL_SERVER, IID_IOPCServer, (void**)&m_IOPCServer); if(S_OK != r1) { AfxMessageBox(_T("Create server failed!")); m_IOPCServer = NULL; //CoUninitialize(); return true;; } return false; } bool COPCComm::Disconnect() { // TODO: Add your control notification handler code here if(m_IOPCServer) { m_IOPCServer->RemoveGroup(m_GrpSrvHandle,true); m_IOPCItemMgt->Release(); m_IOPCServer->Release(); } return false; } bool COPCComm::AddGroup() { // TODO: Add your control notification handler code here LONG TimBias; FLOAT PercDeadband; DWORD dwLCID; DWORD RevUpRate; //out HRESULT r1; TimBias = 0; PercDeadband = 0.0; dwLCID = 0x409; r1 = m_IOPCServer->AddGroup(L"gru1", TRUE, 500, 1, &TimBias, &PercDeadband, dwLCID, &m_GrpSrvHandle, &RevUpRate, IID_IOPCItemMgt, (LPUNKNOWN*)&m_IOPCItemMgt); if(!FAILED(r1)) { //AfxMessageBox(_T("Successfully added group to server!")); return false; } else { AfxMessageBox(_T("Can't add group to server!")); m_IOPCItemMgt = NULL; return true; } return false; } bool COPCComm::AddItem(DWORD NumItems) { // TODO: Add your control notification handler code here OPCITEMDEF* pItems; OPCITEMRESULT* pItResult; HRESULT* pErrors; HRESULT r1; DWORD i; //DWORD NumItems; //NumItems = 31; pItems = new OPCITEMDEF[NumItems]; for(i = 0; i < NumItems; i++) { pItems[i].szAccessPath = L""; pItems[i].szItemID = g_szItemID[i]; pItems[i].bActive = TRUE; pItems[i].hClient = i + 1; pItems[i].dwBlobSize = 0; pItems[i].pBlob = NULL; pItems[i].vtRequestedDataType = VT_R4; } r1 = m_IOPCItemMgt->AddItems(NumItems, pItems, &pItResult, &pErrors); if(FAILED(r1) &&(r1 != S_FALSE)) { AfxMessageBox(_T("AddItems- failed!")); if(m_IOPCServer != NULL) { m_IOPCServer->Release(); } delete[] pItems; return true; //exit(1); } for (i = 0; i < NumItems; i++) { if(FAILED(pErrors[i])) { AfxMessageBox(_T("erorr!")); delete[] pItems; return true; } else { m_pItAttr[i].szItemID = g_szItemID[i]; m_pItAttr[i].szAccessPath = pItems[i].szAccessPath; m_pItAttr[i].hClient = pItems[i].hClient; m_pItAttr[i].hServer = pItResult[i].hServer; m_pItAttr[i].dwAccessRights = pItResult[i].dwAccessRights; m_pItAttr[i].bActive = pItems[i].bActive; } } if(pItResult[0].dwAccessRights != (OPC_READABLE + OPC_WRITEABLE)) { AfxMessageBox(_T("Item can't write and read!")); delete[] pItems; return true; } /* r1 = m_IOPCItemMgt->QueryInterface(IID_IOPCAsyncIO2, (void**)&m_IOPCAsyncIO2); if (r1 < 0) { AfxMessageBox("IOPCAsyncIO2没有发现,错误的查询!"); CoTaskMemFree(m_ItemResult); m_IOPCItemMgt->Release(); m_IOPCItemMgt = NULL; m_GrpSrvHandle = NULL; m_IOPCServer->Release(); m_IOPCServer = NULL; CoUninitialize(); return; }*/ delete[] pItems; return false; } bool COPCComm::Write(DWORD NumItems) { // TODO: Add your control notification handler code here /* m_ItemID[0] = g_szItemID[0]; m_ItemValues[0].vt = VT_R4; m_ItemValues[0].fltVal = 258.5; //要写入的一Item值 m_ItemID[1] = g_szItemID[1]; m_ItemValues[1].vt = VT_R4; m_ItemValues[1].fltVal = 345.2; //要写入的另一Item值 */ IOPCAsyncIO* pAsyncIO; OPCHANDLE* phServer; HRESULT r1, r2; HRESULT* pErrors; BOOL found = FALSE; DWORD i; //NumItems = 31; phServer = new OPCHANDLE[NumItems]; for(i = 0; i < NumItems; i++) { phServer[i] = m_pItAttr[i].hServer; } r1 = m_IOPCItemMgt->QueryInterface(IID_IOPCAsyncIO, (void **)&pAsyncIO); if(FAILED(r1)) { AfxMessageBox(_T("IOPCAsyncIO - Not supported !")); CoTaskMemFree(pErrors); delete[] phServer; return true; } else { //using IOPCAsyncIO::Write(..), look at OPC spezifikation r2 = pAsyncIO->Write(0, NumItems, phServer, m_ItemValues, &m_TransactionID, &pErrors); if(FAILED(r2) && (r2 == E_FAIL)) { AfxMessageBox(_T("Error - Write")); delete[] phServer; return true; //exit(1); } } pAsyncIO->Release(); //CoTaskMemFree(pItemValue); CoTaskMemFree(pErrors); delete[] phServer; return false; } float COPCComm::Read(DWORD NumItems) { // TODO: Add your control notification handler code here IOPCSyncIO* pSyncIO; OPCHANDLE* phServer; HRESULT r1, r2; HRESULT* pErrors; BOOL found = FALSE; DWORD i; CString temp; //NumItems = 31; phServer = new OPCHANDLE[NumItems]; for(i = 0; i < NumItems; i++) { phServer[i] = m_pItAttr[i].hServer; } r1 = m_IOPCItemMgt->QueryInterface(IID_IOPCSyncIO, (void **)&pSyncIO); if(FAILED(r1)) { AfxMessageBox(_T("IOPCAsyncIO - Not supported !")); delete[] phServer; return true; } else { //using IOPCAsyncIO::Read(..), look at OPC spezifikation r2 = pSyncIO->Read(OPC_DS_DEVICE, NumItems, phServer, &bdg, &pErrors); if(FAILED(r2) && (r2 == E_FAIL)) { AfxMessageBox(_T("Error - Read")); VariantClear (&bdg[0].vDataValue); CoTaskMemFree(pErrors); delete[] phServer; return -999.0;//赋不可能值 //exit(1); } } temp.Format(_T("%.2f"), bdg[0].vDataValue.fltVal); retData = bdg[1].vDataValue.fltVal; VariantClear (&bdg[0].vDataValue); pSyncIO->Release(); CoTaskMemFree(pErrors); delete[] phServer; return (float)_ttof(temp); } bool COPCComm::RemoveGroup() { // TODO: Add your control notification handler code here HRESULT r1; r1 = m_IOPCServer->RemoveGroup(m_GrpSrvHandle, TRUE); if(SUCCEEDED(r1)) { //AfxMessageBox(_T("Successfully removed group !")); m_GrpSrvHandle = NULL; m_IOPCItemMgt->Release(); m_IOPCItemMgt = NULL; } else { AfxMessageBox(_T("Can't remove group ! ")); return true; } return false; } bool COPCComm::RemovItem(DWORD NumItems) { // TODO: Add your control notification handler code here HRESULT r1; HRESULT* pErrors; OPCHANDLE* phServer; DWORD i; phServer = new OPCHANDLE[NumItems]; for(i = 0; i < NumItems; i++) { phServer[i] = m_pItAttr[i].hServer; } r1 = m_IOPCItemMgt->RemoveItems(NumItems, phServer, &pErrors); if(FAILED(r1) && (r1 != S_FALSE)) { AfxMessageBox(_T("RemoveItems - failed!")); delete[] phServer; return true; //exit(1); } delete[] phServer; return false; } 主程序调用: if(m_OPC.ConnectSrv()) { AfxMessageBox(_T("本地服务器没连上!!")); return; } if(m_OPC.AddGroup()) { AfxMessageBox(_T("添加组失败!!")); return; } if(m_OPC.AddItem((DWORD)31)) { AfxMessageBox(_T("添加项失败!!")); return; } j = 0; for(i = 0; i < 16; i ++) { m_OPC.m_ItemValues[i].vt = VT_R4; //m_OPC.m_ItemValues[i].fltVal = m_PIC.m_Len[i]; } j = 0; for(i = 16; i < 31; i ++, j ++) { m_OPC.m_ItemValues[i].vt = VT_R4; //m_OPC.m_ItemValues[i].fltVal = m_PIC.m_Angle[j]; } m_OPC.Write((DWORD)31); |
|
来自: 紫殿 > 《wincc_OPC》