데이터 베이스 MySQL 튜토리얼 VC++与OPC(pc access)通讯

VC++与OPC(pc access)通讯

Jun 07, 2016 pm 03:43 PM
access 호스트 컴퓨터 개발하다 원하다 의사소통

最近做上位机开发,需要与PLC 通讯 。以前不知道以为要与PLC程序配合写 通讯 程序,后来联系西门子客服才知道这个问题早被解决了。网上《OPC_client_在VC环境下编程.doc》比较适合我(适合你的是最好的),表示感谢作者。在这篇的基础上我添加了一下自己的东

最近做上位机开发,需要与PLC通讯。以前不知道以为要与PLC程序配合写通讯程序,后来联系西门子客服才知道这个问题早被解决了。网上《OPC_client_在VC环境下编程.doc》比较适合我(适合你的是最好的),表示感谢作者。在这篇的基础上我添加了一下自己的东西。具体的Demo在http://download.csdn.net/detail/yuanhaosh/8098867下载

在这之前需要添加几个OPC相关的文件 opccomn_i.c ,opccomn.h, opcda.h, opcda_i.c,  opcerror.h,已经包含在demo中了

这部分是初始化OPC的部分。

BOOL COPCDEMODlg::InitOPCServer()
{
    CLSID clsid;
HRESULT hr = S_OK;
CString strServer = "S7200.OPCServer";  //OPC.SimaticNET S7200.OPCServer


/*初始化COM库*/
if (FAILED(::CoInitialize(NULL))) 
{
AfxMessageBox("Error during CoInitialize", MB_OK );
        return FALSE;
}

/*查找OPC服务*/
hr = CLSIDFromProgID( strServer.AllocSysString(), &clsid );
if( FAILED(hr))
{
        AfxMessageBox("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("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("Error during AddGroup", MB_OK);
hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
if(SUCCEEDED(hr))
{
//输出错误信息
}
else
{
//添加组失败;
}
m_IOPCServer->Release();
m_IOPCServer=NULL;
CoUninitialize();
        return FALSE;
}

Item*  pcItem ;
OPCITEMDEF *m_Items = new OPCITEMDEF[COUNT];                        //项的存取路径, 定义和被请求的数据类等

for(int i = 0; i {
pcItem = new Item;
pcItem->quality = QUAL_BAD;


//pcItem->name = _T("" + TableStr[i]);                             //设置opc节点 Microwin.NewPLC.group.
pcItem->name = _T("Microwin.NewPLC.group.NewItem1");             //这里的字符串填写你的item就行
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("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;
}

/*保存item对应的服务句柄*/
pdwServerHandles = new DWORD[COUNT];
for(i = 0; 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("获取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,                  // Item count
(OPCHANDLE*)phServe,// Array of server handles for items
pValues,            // Array of values
&pErrors);            // Array of errors
        if(FAILED(hr))
   {   
            AfxMessageBox("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;
}

로그인 후 복사


본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

뜨거운 기사 태그

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Windows 11에서 백그라운드 애플리케이션을 비활성화하는 방법_Windows 11 튜토리얼에서 백그라운드 애플리케이션을 비활성화하는 방법 Windows 11에서 백그라운드 애플리케이션을 비활성화하는 방법_Windows 11 튜토리얼에서 백그라운드 애플리케이션을 비활성화하는 방법 May 07, 2024 pm 04:20 PM

Windows 11에서 백그라운드 애플리케이션을 비활성화하는 방법_Windows 11 튜토리얼에서 백그라운드 애플리케이션을 비활성화하는 방법

권장되는 AI 지원 프로그래밍 도구 4가지 권장되는 AI 지원 프로그래밍 도구 4가지 Apr 22, 2024 pm 05:34 PM

권장되는 AI 지원 프로그래밍 도구 4가지

DeepSeek PDF를 변환하는 방법 DeepSeek PDF를 변환하는 방법 Feb 19, 2025 pm 05:24 PM

DeepSeek PDF를 변환하는 방법

iPhone에서 카메라 및 마이크에 대한 접근을 허용할 수 없습니다 iPhone에서 카메라 및 마이크에 대한 접근을 허용할 수 없습니다 Apr 23, 2024 am 11:13 AM

iPhone에서 카메라 및 마이크에 대한 접근을 허용할 수 없습니다

자바에서 dao는 무엇을 의미합니까? 자바에서 dao는 무엇을 의미합니까? Apr 21, 2024 am 02:08 AM

자바에서 dao는 무엇을 의미합니까?

Java에서 필드는 무엇을 의미합니까? Java에서 필드는 무엇을 의미합니까? Apr 25, 2024 pm 10:18 PM

Java에서 필드는 무엇을 의미합니까?

Oracle 저장 프로시저 실행 계획을 읽는 방법 Oracle 저장 프로시저 실행 계획을 읽는 방법 Apr 18, 2024 pm 10:18 PM

Oracle 저장 프로시저 실행 계획을 읽는 방법

Java 리플렉션 메커니즘은 클래스의 동작을 어떻게 수정합니까? Java 리플렉션 메커니즘은 클래스의 동작을 어떻게 수정합니까? May 03, 2024 pm 06:15 PM

Java 리플렉션 메커니즘은 클래스의 동작을 어떻게 수정합니까?

See all articles