本手册使用一台SX21作为ACP服务器,Ubuntu电脑作为客户端来读取、写入和订阅PLC变量功能。如下图所示:
下表概述了本手册各个产品组件
产品组件 | 描述说明 |
---|---|
DeviceManager_0.0.1.9 | 工智机插件安装管理器 |
acpsymbollib_1.0.1_amd64.deb | Ubuntu客户端deb组件 |
libacp_0.2.3_amd64.deb | acpsymbollib依赖文件 |
CppAcpServer.projectarchive | PLC工程存档 |
AcpClient.cpp | Linux客户端C++示例程序 |
安装要求
安装过程
1、工智机安装acpplcaccess.deb组件
1.打开Device Manager软件,使用工智机固定网口与个人电脑通讯。
2.初次使用,需要安装ACP通讯服务。点击左下角“安装ACP服务”。
3.输入工智机固定IP地址、端口、用户名和密码后,点击“在线安装”。
IP地址 | 192.168.1.200 |
---|---|
端口 | 2224 |
用户名 | sinsegye |
密码 | 1 |
等待安装完成。
4.安装完成后,点击“扫描”,即可扫描出固定网口192.168.1.200连接的工智机。
点击进入工智机后,左下角显示“已连接”状态。
5.点击“安装RTE插件服务”
6.输入用户名:sinsegye,密码:1,点击“在线安装”
7.安装完成后,点击“软件”,在下拉菜单下选择“组件管理”
8.点击浏览,可以在线浏览可以安装的组件。
9.在组件中找到“SF1000-acpplcaccess”--点击“安装”
10.等待deb包传送到工智机中,传送完成后点击“确定”进行安装。
11.安装完成后,点击“确认”重启生效。
12.安装完成后,可以在“本地”页面浏览到SF1000-acpplcaccess已安装成功。
2、Ubuntu 20.04电脑安装acpsymbollib和libacp库文件
将官网下载的acpsymbollib_1.0.1_amd64.deb文件和libacp_0.2.3_amd64.deb文件拷贝到Ubuntu客户端/home文件夹下。
打开Ubuntu终端,安装acpsymbollib_1.0.1_amd64.deb
sudo dpkg -i acpsymbollib\_1.0.1\_amd64.deb
安装libacp_0.2.3_amd64.deb
sudo dpkg -i libacp\_0.2.3\_amd64.deb
3、Ubuntu安装VScode
使用Ubuntu Sofeware 安装VScode。没有Ubuntu-soft先使用命令下载。
sudo apt-get update
sudo apt -y install ubuntu-software
打开VScode,点击“Extensions”。
搜索“chinese”—— 选择中文(简体)—— 安装
搜索“C++”——点击安装
重启Ubuntu系统。
、设置VScode C++编译环境
Ubuntu打开VScode软件,点击“选择我的默认编辑器”
选择使用g++编译器
点击“打开文件夹”
新建一个文件夹
点击“OPEN”
点击“信任作者”
新建一个cpp文件
编写测试程序
#include\<iostream>
using namespace std;
int main(void)
{
cout<<"Hello"<\<endl;
return 0;
}
点击“终端”——“配置默认生成任务”
选择“g++生成活动文件”
添加“-lacpsymbollib”和“-lacpsymbolapi-c”
点击“运行生成任务”
点击“运行”——“添加配置”
选择“C++”
点击“添加配置”——“(gdb)启动”
修改“program”参数为"{fileDirname}/{fileBasenameNoExtension}"
同时,添加属性“preLaunchTask”:“C/C++: g++ 生成活动文件”
选择Hello.cpp文件——调试,可以在终端看到调试结果。
更新安装
1.ACP服务器更新acpplcaccess组件
在插件管理器Device Mananger--组件管理--本地组件中,点击SF1000-acpplcaccess,选择可更新的版本后,点击“更新”。
2.Linux系统更新acpsymbollib和libacp库文件
从中科时代官网下载最新的acpsymbollib和libacp库文件,使用dpkg -i 重新安装
sudo dpkg -i acpsymbollib\_1.0.1\_amd64.deb
sudo dpkg -i libacp\_0.2.3\_amd64.deb
卸载过程
1. ACP服务器卸载acpplcaccess组件
在插件管理器Device Mananger--组件管理--本地组件中,点击SF1000-acpplcaccess,选择“卸载”
点击“确定”
卸载成功后,点击“确定”重启生效。
卸载成功后,“本地”页面组件消失。
2、卸载Ubuntu客户端acpsymbollib和libacp库文件
使用dpkg -r命令进行卸载
sudo dpkg -r acpsymbollib
sudo dpkg -r libacp
重启
sudo reboot
3、Ubuntu客户端卸载VScode
使用Ubuntu-Software卸载VScode
快速启动
(一)本例软、硬件配置
硬件: | 软件 |
---|---|
工智机SX21 | 插件管理器DeviceManager_0.0.1.9 |
Ubuntu 20.04系统客户端 | 客户端组件acpsymbollib_1.0.1_amd64.deb |
个人电脑 | 依赖库文件libacp_0.2.3_amd64.deb |
服务端PLC工程存档CppAcpServer.projectarchive | |
客户端C++测试程序AcpClient.cpp | |
中科时代IDE MetaFacture V1.0.6.6 |
(二)本例实验操作步骤
1.实验要求
a.工智机使用插件管理器成功安装acpplcaccess组件;
b.Linux系统客户端安装acpsymbollib和liblibacp库文件;
c.Linux系统客户端安装VScode软件,并配置C++编译环境。
2.实验原理图
3.实验步骤
3.1 解压官网下载的工程存档文件“CppAcpServer.projectarchive”,登录工智机,下载运行程序。
3.2 将官网下载的C++程序“AcpClient.cpp”拷贝到Ubuntu的Project文件夹中
3.3 在VScode中选择AcpClient.cpp程序,在main()函数中取消ReadSymbol()注释
修改程序ReadSymbol()中的工智机IP地址:
3.4 点击Debug,读取PLC_PRG程序中的变量
修改程序WriteSymbol()中的工智机IP地址:
3.5 在main()函数中注释ReadSymbol(),取消Writesymbol()注释。点击Debug,写入变量值。
查看工智机的PLC变量值,写入成功。
3.6 在main()函数中注释Writesymbol(),取消SubSymbol()注释。点击Debug,订阅变量。
修改程序SubSymbol()中的工智机IP地址:
订阅的变量数值不断在变化。
通过实例化的connParam结构传递TCP连接参数和IP地址,使用AcpCreatConnHandler获得连接句柄。
创建读取变量结构体,设定变量类型,读取路径和读取字符大小,使用AcpReadTagList进行读取。
详细参数说明见功能介绍。
void ReadSymbol()
{
ConnParam connParam;
connParam.connType = AcpConnType::ACP_CONN_TYPE_TCP;
const char* ipAddress = "192.168.110.114";
strncpy(connParam.szConnParam, ipAddress, sizeof(connParam.szConnParam) - 1);
connParam.szConnParam[sizeof(connParam.szConnParam) - 1] = '\0'; // 确保以 null 结尾
auto handle = AcpCreatConnHandler(&connParam);
TagInfo readinfo[15];
ST_BOOL bool1_ = false;
std::string strBoolPath = "Application.PLC_PRG.xVar1";
ST_BYTE byte1_ = 0;
std::string strBytePath = "Application.PLC_PRG.bVar2";
ST_WORD word1_=0;
std::string strWordPath = "Application.PLC_PRG.wVar3";
ST_DWORD dword1_=0;
std::string strDwordPath = "Application.PLC_PRG.dwVar4";
ST_LWORD lword1_=0;
std::string strLwordPath = "Application.PLC_PRG.lwVar5";
ST_SINT sint1_=0;
std::string strSintPath = "Application.PLC_PRG.siVar6";
ST_USINT usint1_=0;
std::string strUsintPath = "Application.PLC_PRG.usiVar7";
ST_INT int1_=0;
std::string strIntPath = "Application.PLC_PRG.iVar8";
ST_UINT uint1_=0;
std::string strUintPath = "Application.PLC_PRG.uiVar9";
ST_DINT dint1_=0;
std::string strDintPath = "Application.PLC_PRG.diVar10";
ST_UDINT udint1_=0;
std::string strUdintPath = "Application.PLC_PRG.udiVar11";
ST_LINT lint1_=0;
std::string strLintPath = "Application.PLC_PRG.liVar12";
ST_REAL real1_=0;
std::string strRealPath = "Application.PLC_PRG.rVar13";
ST_LREAL lreal1_=0;
std::string strLrealPath = "Application.PLC_PRG.lrVar14";
ST_STRING str[81];
std::string strStringPath = "Application.PLC_PRG.sVar15";
readinfo[0].tagDesc.szSymbolFullName = strBoolPath.c_str();
readinfo[0].tagValue.pValueData = &bool1_;
readinfo[0].tagValue.nValueSize = sizeof(ST_BOOL);
readinfo[1].tagDesc.szSymbolFullName = strBytePath.c_str();
readinfo[1].tagValue.pValueData = &byte1_;
readinfo[1].tagValue.nValueSize = sizeof(ST_BYTE);
readinfo[2].tagDesc.szSymbolFullName = strWordPath.c_str();
readinfo[2].tagValue.pValueData = &word1_;
readinfo[2].tagValue.nValueSize = sizeof(ST_WORD);
readinfo[3].tagDesc.szSymbolFullName = strDwordPath.c_str();
readinfo[3].tagValue.pValueData = &dword1_;
readinfo[3].tagValue.nValueSize = sizeof(ST_DWORD);
readinfo[4].tagDesc.szSymbolFullName = strLwordPath.c_str();
readinfo[4].tagValue.pValueData = &lword1_;
readinfo[4].tagValue.nValueSize = sizeof(ST_LWORD);
readinfo[5].tagDesc.szSymbolFullName = strSintPath.c_str();
readinfo[5].tagValue.pValueData = &sint1_;
readinfo[5].tagValue.nValueSize = sizeof(ST_SINT);
readinfo[6].tagDesc.szSymbolFullName = strUsintPath.c_str();
readinfo[6].tagValue.pValueData = &usint1_;
readinfo[6].tagValue.nValueSize = sizeof(ST_USINT);
readinfo[7].tagDesc.szSymbolFullName = strIntPath.c_str();
readinfo[7].tagValue.pValueData = &int1_;
readinfo[7].tagValue.nValueSize = sizeof(ST_INT);
readinfo[8].tagDesc.szSymbolFullName = strUintPath.c_str();
readinfo[8].tagValue.pValueData = &uint1_;
readinfo[8].tagValue.nValueSize = sizeof(ST_UINT);
readinfo[9].tagDesc.szSymbolFullName = strDintPath.c_str();
readinfo[9].tagValue.pValueData = &dint1_;
readinfo[9].tagValue.nValueSize = sizeof(ST_DINT);
readinfo[10].tagDesc.szSymbolFullName = strUdintPath.c_str();
readinfo[10].tagValue.pValueData = &udint1_;
readinfo[10].tagValue.nValueSize = sizeof(ST_UDINT);
readinfo[11].tagDesc.szSymbolFullName = strLintPath.c_str();
readinfo[11].tagValue.pValueData = &lint1_;
readinfo[11].tagValue.nValueSize = sizeof(ST_LINT);
readinfo[12].tagDesc.szSymbolFullName = strRealPath.c_str();
readinfo[12].tagValue.pValueData = &real1_;
readinfo[12].tagValue.nValueSize = sizeof(ST_REAL);
readinfo[13].tagDesc.szSymbolFullName = strLrealPath.c_str();
readinfo[13].tagValue.pValueData = &lreal1_;
readinfo[13].tagValue.nValueSize = sizeof(ST_LREAL);
readinfo[14].tagDesc.szSymbolFullName = strStringPath.c_str();
readinfo[14].tagValue.pValueData = &str;
readinfo[14].tagValue.nValueSize = sizeof(str);
auto var_size = sizeof(readinfo) / sizeof(TagInfo);
auto result = AcpReadTagList(handle, &readinfo[0], var_size, 500);
if (result != false)
{
printf("读取变量失败!\n");
}
else
{
printf("读取变量成功!\n");
printf("xVar1=%d\n",bool1_);
printf("bVar2=%d\n",byte1_);
printf("wVar3=%d\n",word1_);
printf("dwVar4=%u\n",dword1_);
printf("lwVar5=%ld\n",lword1_);
printf("siVar6=%d\n",sint1_);
printf("usiVar7=%d\n",usint1_);
printf("iVar8=%d\n",int1_);
printf("uiVar9=%d\n",uint1_);
printf("diVar10=%d\n",dint1_);
printf("udiVar11=%u\n",udint1_);
printf("liVar12=%ld\n",lint1_);
printf("rVar13=%f\n",real1_);
printf("lrVar14=%.8lf\n",lreal1_);
printf("sVar15=%s \n",str);
}
}
通过实例化的connParam结构传递TCP连接参数和IP地址,使用AcpCreatConnHandler获得连接句柄。
创建写入变量结构体,设定变量类型,写入路径和写入字符大小,使用AcpWriteTagList进行读取。
详细参数说明见功能介绍。
void WriteSymbol()
{
ConnParam connParam;
connParam.connType = AcpConnType::ACP_CONN_TYPE_TCP;
const char* ipAddress = "192.168.110.114";
strncpy(connParam.szConnParam, ipAddress, sizeof(connParam.szConnParam) - 1);
connParam.szConnParam[sizeof(connParam.szConnParam) - 1] = '\0'; // 确保以 null 结尾
auto handle = AcpCreatConnHandler(&connParam);
TagInfo writeinfo[15];
ST_BOOL bool1_ = false;
std::string strBoolPath = "Application.PLC_PRG.xVar1";
ST_BYTE byte1_ = 27;
std::string strBytePath = "Application.PLC_PRG.bVar2";
ST_WORD word1_=55533;
std::string strWordPath = "Application.PLC_PRG.wVar3";
ST_DWORD dword1_=4000000000;
std::string strDwordPath = "Application.PLC_PRG.dwVar4";
ST_LWORD lword1_=6666666666;
std::string strLwordPath = "Application.PLC_PRG.lwVar5";
ST_SINT sint1_=-88;
std::string strSintPath = "Application.PLC_PRG.siVar6";
ST_USINT usint1_=222;
std::string strUsintPath = "Application.PLC_PRG.usiVar7";
ST_INT int1_=-32666;
std::string strIntPath = "Application.PLC_PRG.iVar8";
ST_UINT uint1_=33355;
std::string strUintPath = "Application.PLC_PRG.uiVar9";
ST_DINT dint1_=2121212121;
std::string strDintPath = "Application.PLC_PRG.diVar10";
ST_UDINT udint1_=3000000000;
std::string strUdintPath = "Application.PLC_PRG.udiVar11";
ST_LINT lint1_=8888888888;
std::string strLintPath = "Application.PLC_PRG.liVar12";
ST_REAL real1_=543.9876;
std::string strRealPath = "Application.PLC_PRG.rVar13";
ST_LREAL lreal1_=678.1234567;
std::string strLrealPath = "Application.PLC_PRG.lrVar14";
ST_STRING str[81];
const char* source = "Sinsegye and sinsegye";
strcpy(str, source); // NOLINT
std::string strStringPath = "Application.PLC_PRG.sVar15";
writeinfo[0].tagDesc.szSymbolFullName = strBoolPath.c_str();
writeinfo[0].tagValue.pValueData = &bool1_;
writeinfo[0].tagValue.nValueSize = sizeof(ST_BOOL);
writeinfo[1].tagDesc.szSymbolFullName = strBytePath.c_str();
writeinfo[1].tagValue.pValueData = &byte1_;
writeinfo[1].tagValue.nValueSize = sizeof(ST_BYTE);
writeinfo[2].tagDesc.szSymbolFullName = strWordPath.c_str();
writeinfo[2].tagValue.pValueData = &word1_;
writeinfo[2].tagValue.nValueSize = sizeof(ST_WORD);
writeinfo[3].tagDesc.szSymbolFullName = strDwordPath.c_str();
writeinfo[3].tagValue.pValueData = &dword1_;
writeinfo[3].tagValue.nValueSize = sizeof(ST_DWORD);
writeinfo[4].tagDesc.szSymbolFullName = strLwordPath.c_str();
writeinfo[4].tagValue.pValueData = &lword1_;
writeinfo[4].tagValue.nValueSize = sizeof(ST_LWORD);
writeinfo[5].tagDesc.szSymbolFullName = strSintPath.c_str();
writeinfo[5].tagValue.pValueData = &sint1_;
writeinfo[5].tagValue.nValueSize = sizeof(ST_SINT);
writeinfo[6].tagDesc.szSymbolFullName = strUsintPath.c_str();
writeinfo[6].tagValue.pValueData = &usint1_;
writeinfo[6].tagValue.nValueSize = sizeof(ST_USINT);
writeinfo[7].tagDesc.szSymbolFullName = strIntPath.c_str();
writeinfo[7].tagValue.pValueData = &int1_;
writeinfo[7].tagValue.nValueSize = sizeof(ST_INT);
writeinfo[8].tagDesc.szSymbolFullName = strUintPath.c_str();
writeinfo[8].tagValue.pValueData = &uint1_;
writeinfo[8].tagValue.nValueSize = sizeof(ST_UINT);
writeinfo[9].tagDesc.szSymbolFullName = strDintPath.c_str();
writeinfo[9].tagValue.pValueData = &dint1_;
writeinfo[9].tagValue.nValueSize = sizeof(ST_DINT);
writeinfo[10].tagDesc.szSymbolFullName = strUdintPath.c_str();
writeinfo[10].tagValue.pValueData = &udint1_;
writeinfo[10].tagValue.nValueSize = sizeof(ST_UDINT);
writeinfo[11].tagDesc.szSymbolFullName = strLintPath.c_str();
writeinfo[11].tagValue.pValueData = &lint1_;
writeinfo[11].tagValue.nValueSize = sizeof(ST_LINT);
writeinfo[12].tagDesc.szSymbolFullName = strRealPath.c_str();
writeinfo[12].tagValue.pValueData = &real1_;
writeinfo[12].tagValue.nValueSize = sizeof(ST_REAL);
writeinfo[13].tagDesc.szSymbolFullName = strLrealPath.c_str();
writeinfo[13].tagValue.pValueData = &lreal1_;
writeinfo[13].tagValue.nValueSize = sizeof(ST_LREAL);
writeinfo[14].tagDesc.szSymbolFullName = strStringPath.c_str();
writeinfo[14].tagValue.pValueData = &str;
writeinfo[14].tagValue.nValueSize = sizeof(str);
auto var_size = sizeof(writeinfo) / sizeof(TagInfo);
auto result = AcpWriteTagList(handle, &writeinfo[0], var_size, 500);
if (result != false)
{
printf("写入变量失败!\n");
}
else
{
printf("写入变量成功!\n");
}
}
通过实例化的connParam结构传递TCP连接参数和IP地址,使用AcpCreatConnHandler获得连接句柄。
使用AcpRegisterNotifyCallBack注册回调函数NotifyCallback;
创建订阅变量结构体,设定订阅变量路径,使用AcpAddTagsNotification添加订阅变量列表。
详细参数说明见功能介绍。
void SubSymbol() {
ConnParam connParam;
const char* ipAddress = "192.168.110.114";
strncpy(connParam.szConnParam, ipAddress, sizeof(connParam.szConnParam) - 1);
connParam.szConnParam[sizeof(connParam.szConnParam) - 1] = '\0'; // 确保以 null 结尾
auto handle = AcpCreatConnHandler(&connParam);
auto result = AcpRegisterNotifyCallBack(handle, NotifyCallback, nullptr);//注册回调函数
TagInfo symbol[15];
std::string str0 = "Application.GVL.BOOL1";
std::string str1 = "Application.GVL.BYTE2";
std::string str2 = "Application.GVL.WORD3";
std::string str3 = "Application.GVL.DWORD4";
std::string str4 = "Application.GVL.LWORD5";
std::string str5 = "Application.GVL.SINT6";
std::string str6 = "Application.GVL.USINT7";
std::string str7 = "Application.GVL.INT8";
std::string str8 = "Application.GVL.UINT9";
std::string str9 = "Application.GVL.DINT10";
std::string str10 = "Application.GVL.UDINT11";
std::string str11 = "Application.GVL.LINT12";
std::string str12 = "Application.GVL.REAL13";
std::string str13 = "Application.GVL.LREAL14";
std::string str14 = "Application.GVL.STRING15";
symbol[0].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str0.c_str()));
symbol[1].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str1.c_str()));
symbol[2].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str2.c_str()));
symbol[3].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str3.c_str()));
symbol[4].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str4.c_str()));
symbol[5].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str5.c_str()));
symbol[6].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str6.c_str()));
symbol[7].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str7.c_str()));
symbol[8].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str8.c_str()));
symbol[9].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str9.c_str()));
symbol[10].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str10.c_str()));
symbol[11].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str11.c_str()));
symbol[12].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str12.c_str()));
symbol[13].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str13.c_str()));
symbol[14].tagDesc.szSymbolFullName = static_cast<const char*>(const_cast<char*>(str14.c_str()));
auto nameSize = sizeof(symbol) / sizeof(TagInfo);
int reqid = 6; //订阅ID
TagSubParam subParam;
subParam.nIntervalMs = 15; //订阅间隔时间
subParam.nRequestId = reqid; //订阅ID
result = AcpAddTagsNotification(handle, &symbol[0], nameSize, &subParam, 500);//添加订阅
}
当订阅变量的值发生改变,进入回调函数。判断返回的变量名,将数值赋给相应的变量。
void NotifyCallback(TagSubInfo* pTagSubInfos, void* lpContext) {
ST_BOOL Subbool1=false;
ST_BYTE Subbyte1=0;
ST_WORD Subword1=0;
ST_DWORD Subdword1=0;
ST_LWORD Sublword1=0;
ST_SINT Subsint1=0;
ST_USINT Subusint1=0;
ST_INT Subint1= 0;
ST_UINT Subuint1=0;
ST_DINT Subdint1=0;
ST_UDINT Subudint1=0;
ST_LINT Sublint1=0;
ST_REAL Subreal1= 0;
ST_LREAL Sublreal1=0;
ST_STRING Substring1[80]="";
if (pTagSubInfos->enReplyType == AcpSubReplyType::subscribefailed)
{
printf("订阅失败! \n");
if (pTagSubInfos->subFailSize > 0)
{
printf("订阅失败的变量: ");
for (uint64_t i = 0; i < pTagSubInfos->subFailSize; i++)
{
std::string name = std::string(pTagSubInfos->subFailTagsInfo[i].tagDesc.szSymbolFullName);
printf("%s ", name.c_str());
}
printf("\n");
}
}
else if (pTagSubInfos->enReplyType == AcpSubReplyType::subscribedelok)
{
printf("取消订阅成功! \n");
}
else if (pTagSubInfos->enReplyType == AcpSubReplyType::subscribeNotify)
{
printf("symbolSubReply->symbolSize:%d\n", pTagSubInfos->subOkSize);
for (uint64_t i = 0; i < pTagSubInfos->subOkSize; i++)
{
auto itemName = std::string(pTagSubInfos->subOkTagsInfo[i].tagDesc.szSymbolFullName);
if (itemName == "Application.GVL.BOOL1")
{
memcpy(&Subbool1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.BOOL1: %d\n", Subbool1);
}
else if (itemName == "Application.GVL.BYTE2")
{
memcpy(&Subbyte1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.BYTE2: %d\n", Subbyte1);
}
else if (itemName == "Application.GVL.WORD3")
{
memcpy(&Subword1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.WORD3: %d\n", Subword1);
}
else if (itemName == "Application.GVL.DWORD4")
{
memcpy(&Subdword1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.DWORD4: %u\n", Subdword1);
}
else if (itemName == "Application.GVL.LWORD5")
{
memcpy(&Sublword1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.LWORD5: %ld\n", Sublword1);
}
else if (itemName == "Application.GVL.SINT6")
{
memcpy(&Subsint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.SINT6: %d\n", Subsint1);
}
else if (itemName == "Application.GVL.USINT7")
{
memcpy(&Subusint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.USINT7: %d\n", Subusint1);
}
else if (itemName == "Application.GVL.INT8")
{
memcpy(&Subint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.INT8: %d\n", Subint1);
}
else if (itemName == "Application.GVL.UINT9")
{
memcpy(&Subuint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.UINT9: %d\n", Subuint1);
}
else if (itemName == "Application.GVL.DINT10")
{
memcpy(&Subdint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.DINT10: %d\n", Subdint1);
}
else if (itemName == "Application.GVL.UDINT11")
{
memcpy(&Subudint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.UDINT11: %u\n", Subudint1);
}
else if (itemName == "Application.GVL.LINT12")
{
memcpy(&Sublint1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.LINT12: %ld\n", Sublint1);
}
else if (itemName == "Application.GVL.REAL13")
{
memcpy(&Subreal1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.REAL13: %f\n", Subreal1);
}
else if (itemName == "Application.GVL.LREAL14")
{
memcpy(&Sublreal1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.LREAL14: %lf\n", Sublreal1);
}
else if (itemName == "Application.GVL.STRING15")
{
memcpy(&Substring1, pTagSubInfos->subOkTagsInfo[i].tagValue.pValueData,
pTagSubInfos->subOkTagsInfo[i].tagValue.nValueSize);
printf("Application.GVL.STRING15: %s\n", Substring1);
}
}
}
}
取消相应的注释来调用读取变量、写入变量和订阅变量的方法。
int main() {
//ReadSymbol();//读取变量
//WriteSymbol();//写入变量
//SubSymbol();//订阅变量
while (1)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));//暂停1s
}
return 0;
}