ADS通信 C++ 设置通知方式读取指定变量

方向

自动化, 使用C++访问 TwinCAT (PLC)指定名称变量,其数值变化由ADS Server主动通知

验证平台

TwinCAT 3.1.4024.56

资源

需结合资源中的PLC代码运行验证

https://tr.beckhoff.com.cn/mod/folder/view.php?id=2058https://tr.beckhoff.com.cn/mod/folder/view.php?id=2058

代码例子

cpp 复制代码
#include "stdafx.h"
using namespace std;
void _stdcall Callback(AmsAddr*, AdsNotificationHeader*, unsigned long);
void main()	//定义变量
{
	long                   nErr, nPort;
	AmsAddr                Addr;
	PAmsAddr               pAddr = &Addr;
	ULONG                  hNotification, hUser;
	AdsNotificationAttrib  adsNotificationAttrib; //为adsNotificationAttrib包含的所有属性定义一个通知

    unsigned long lHdlVar3;
    char szVar3[] = {"MAIN.INT2"};
    short INT2=0xff;


  //打开ADS router的通讯端口
	nPort = AdsPortOpen();
	nErr = AdsGetLocalAddress(pAddr);
	if (nErr) cerr << "Error: AdsGetLocalAddress: " << nErr << '\n';
	pAddr->port = AMSPORT_R0_PLC_TC3;

	//获取结构体的句柄
	nErr = AdsSyncReadWriteReq(pAddr, ADSIGRP_SYM_HNDBYNAME, 0x0, sizeof(lHdlVar3), &lHdlVar3, sizeof(szVar3), szVar3);
	if (nErr) cerr << "Test: Error: AdsSyncReadWriteReq: " << nErr << '\n';
    cout << "INT2 HANDLE=" << lHdlVar3<< "\n";


	//设置notification的属性值
	adsNotificationAttrib.cbLength = 4; //数据的长度,传递给回调函数
	adsNotificationAttrib.nTransMode = ADSTRANS_SERVERONCHA; //当变量值的变化后,通知的回调函数被调用
	adsNotificationAttrib.nMaxDelay = 20000000; // 2sec,通知的回调函数被调用
	adsNotificationAttrib.nCycleTime = 10000000; // 1sec,ADS服务器检查变量是否改变
  // 32-Bit变量(和指针),这些变量(和指针)可以被传递给callback-function 
	hUser = lHdlVar3;//3474573467;
	//开始PLC变量的传输
	nErr = AdsSyncAddDeviceNotificationReq(pAddr, ADSIGRP_SYM_VALBYHND, lHdlVar3, &adsNotificationAttrib, Callback, hUser, &hNotification); //定义在ADS服务器的通知,当某个事件发生时,回调函数在ADS客户端被调用。pAddr:ADS设备地址 0x4020:段地址 0:偏移地址 Callback:回调函数的名称 
	if (nErr) cerr << "Error: AdsSyncAddDeviceNotificationReq: " << nErr << '\n';
	cout << "Notification: " << hNotification << "\n\n";
	cout.flush();
	//等待用户操作
	_getch();
	//完成PLC变量的传输
	nErr = AdsSyncDelDeviceNotificationReq(pAddr, hNotification);
	if (nErr) cerr << "Error: AdsSyncDelDeviceNotificationReq: " << nErr << '\n';
	//关闭通讯端口
	nErr = AdsPortClose();
	if (nErr) cerr << "Error: AdsPortClose: " << nErr << '\n'; //判断返回值结果
}
//回调函数
void __stdcall Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser)
{
	int                     nIndex;
	static ULONG            nCount = 0;
	SYSTEMTIME              SystemTime, LocalTime;
	FILETIME                FileTime;
	LARGE_INTEGER           LargeInteger;
	TIME_ZONE_INFORMATION   TimeZoneInformation;
	cout << ++nCount << ". Call:\n";
	//打印出变量的数值
	cout << "INT2:" << *(ULONG *)pNotification->data << '\n';
	cout << "Notification: " << pNotification->hNotification << '\n';
	//将timestamp转变成SYSTEMTIME
	LargeInteger.QuadPart = pNotification->nTimeStamp;
	FileTime.dwLowDateTime = (DWORD)LargeInteger.LowPart;
	FileTime.dwHighDateTime = (DWORD)LargeInteger.HighPart;
	FileTimeToSystemTime(&FileTime, &SystemTime);
	//将时间值Zeit转变为local time
	GetTimeZoneInformation(&TimeZoneInformation);
	SystemTimeToTzSpecificLocalTime(&TimeZoneInformation, &SystemTime, &LocalTime);
	//打印出timestamp
	cout << LocalTime.wHour << ":" << LocalTime.wMinute << ":" << LocalTime.wSecond << '.' << LocalTime.wMilliseconds <<
		" den: " << LocalTime.wDay << '.' << LocalTime.wMonth << '.' << LocalTime.wYear << '\n';
	// Size of buffer in bytes
	cout << "SampleSize: " << pNotification->cbSampleSize << '\n';
	// 32-Bit Variable (auch Zeiger), die beim AddNotification gesetzt wurde // (siehe main)
	cout << "hUser: " << hUser << '\n';
	//打印出发送方的ADS-address
	cout << "ServerNetId: ";
	for (nIndex = 0; nIndex < 6; nIndex++)
		cout << (int)pAddr->netId.b[nIndex] << ".";
	cout << "\nPort: " << pAddr->port << "\n\n";
	cout.flush();
}

nMaxDelay

The notification's callback function is invoked at the latest when this time has elapsed. The unit is 100 ns.

nCycleTime

The ADS server checks whether the variable has changed after this time interval. The unit is 100 ns.

++中文解释:1毫秒=10000个(100纳秒)++

相关推荐
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧7 小时前
C++学习:基础知识的掌握
c++·visualstudio
江畔柳前堤7 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
wuyk5557 小时前
第2章:六步换相原理全解+STM32工程实战
c语言·开发语言·stm32·单片机·嵌入式硬件
hey_sml7 小时前
JAVA每日一学---CompletableFuture中thenApply与thenCompose区别详解
java·开发语言
Forever Nore8 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
萧瑟余晖9 小时前
Java深入解析篇十七之SpringCloud
java·开发语言
ttod_qzstudio9 小时前
Java 常用语法极简通关(五):类与对象——字段、方法、构造器、this 与 static
java·开发语言·python
罗西的思考10 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX10 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
萧瑟余晖10 小时前
Java深入解析篇十七之Spring Security
java·开发语言·spring