VC++与OPC(pc 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;
}

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

1、在Windows11中打开设置。您可以使用Win+I快捷方式或任何其他方法。2、转到应用程序部分,然后单击应用程序和功能。3、查找要阻止在后台运行的应用程序。单击三点按钮并选择高级选项。4、找到【后台应用程序权限】部分并选择所需的值。默认情况下,Windows11设置电源优化模式。它允许Windows管理应用程序在后台的工作方式。例如,一旦启用省电模式以保留电池,系统将自动关闭所有应用程序。5、选择【从不】可防止应用程序在后台运行。请注意,如果您注意到程序不向您发送通知、无法更新数据等,您可

DeepSeek 无法直接将文件转换为 PDF。根据文件类型,可以使用不同方法:常见文档(Word、Excel、PowerPoint):使用微软 Office、LibreOffice 等软件导出为 PDF。图片:使用图片查看器或图像处理软件保存为 PDF。网页:使用浏览器“打印成 PDF”功能或专用的网页转 PDF 工具。不常见格式:找到合适的转换器,将其转换为 PDF。选择合适的工具并根据实际情况制定方案至关重要。

在Java中,"field"是类或接口中的数据成员,用于存储数据或状态。field的属性包括:类型(可为任何Java数据类型)、访问权限、static(属于类而非实例)、final(不可变)和transient(不序列化)。field用于存储类或接口的状态信息,例如存储对象数据和维护对象状态。

Oracle 可以通过以下步骤读取 dbf 文件:创建外部表,引用 dbf 文件;查询外部表,检索数据;将数据导入 Oracle 表。

Java反射机制允许程序动态修改类的行为,无需修改源代码。通过Class对象操作类,可以通过newInstance()创建实例,修改私有字段值,调用私有方法等。但应谨慎使用反射,因为它可能会导致意外的行为和安全问题,并有性能开销。

Java函数开发中常见的异常类型及其修复措施在Java函数开发过程中,可能遇到各种异常,影响函数的正确执行。以下是常见的异常类型及其修复措施:1.NullPointerException描述:当访问一个还未初始化的对象时抛出。修复措施:确保在使用对象之前对其进行非空检查。示例代码:try{Stringname=null;System.out.println(name.length());}catch(NullPointerExceptione){

在 Vue 中解决 iframe 跨域问题的方法:CORS:启用后端服务器中的 CORS 支持,在 Vue 中使用 XMLHttpRequest 或 fetch API 发送 CORS 请求。JSONP:使用后端服务器中的 JSONP 端点,在 Vue 中动态加载 JSONP 脚本。代理服务器:设置代理服务器转发请求,在 Vue 中使用第三方库(如 axios)发送请求并设置代理服务器 URL。

昨日,BotanixLabs宣布累计完成1150万美元融资,PolychainCapital、PlaceholderCapital等参投。融资将用于构建去中心化的EVM等效BTCL2Botanix。Spiderchain结合了EVM的易用性与比特币的安全性。自2023年11月测试网上线以来,已有超过20万个活跃地址。Odaily将于本文解析Botanix的特色机制与测试网交互流程。Botanix按照官方定义,Botanix是一个基于比特币构建的去中心化的图灵完备L2EVM,由两个核心组件以太坊虚
