分享

S7-200 OPC C++读写PC Access服务器

 紫殿 2013-08-05
操作系统:Windows 7旗舰版
开发工具:VS2010 
开发语言:MFC
描述:对S7-200的VD100-VD220的31个双字寄存器进行写;

头文件:OPCComm.h
#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);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多