上位机使用C++通过ADS协议与倍福PLC通信例程-通过变量名方式读写浮点数

2023-05-16

前言

建议初学者先看这一章节内容,里面包括一些基础的环境配置和项目建立流程,以后开发项目这些流程是通用的,务必掌握并熟练。
链接: 上位机使用C++通过ADS协议与倍福PLC通信例程-布尔变量的读取

ADS读写TwinCAT中变量的方式

ADS读写TwinCAT中变量的方式有两种,一种通过IndexGroup和IndexOffset信息访问变量,另一种方式是通过变量名的形式访问变量。

通过IndexGroup和IndexOffset访问变量

在这里插入图片描述
如上图所示,PLCVar1的IndexGroup和IndexOffset分别是4040和5DFE8,这样在使用倍福提供的库函数时,只需要填写以上信息就可以。例如使用ADS的读取函数,当读取PLCVar1时,若在上位机上声明一个变量 PLCVar1Get来存放读取上来的值,那么nLength=4(按字节计量变量的大小,在函数的形参中通常以sizeof(PLCVar1Get)出现,编程人员应该自己检查确保计算的结果是4bytes),

float PLCVar1Get;

那么pData就是指向PLCVar1Get的指针,一般在形参中以“&PLCVar1Get”出现。

LONG AdsSyncReadReq(
     PAmsAddr  pAddr,
     ULONG  nIndexGroup,
     ULONG  nIndexOffset,
     ULONG  nLength,
     PVOID  pData);  

pAddr结构体包含PLC中的AMS地址和ADS端口号,可参考文章开头部分提供的例程理解,此处不再赘述。
通过IndexGroup和IndexOffset读写有什么劣势呢?
在实际编程中,如果变量名起的不合理,或者类型需要更改时,IndexOffset就有可能变动,导致程序更改麻烦且困难,极容易漏掉一些忘记更改的程序行导致出错,下面以更改变量名字为例,看一下更改后的情况,把PLCVar1更改为PLCVar1_1后,IndexOffset的值由5DEF8变为了608D0,此时就需要把程序中用的5DEF8的地方更改为608D0,程序较大时就显得繁琐低效。
在这里插入图片描述

通过变量名的方式访问变量

倍福的官方文档中是推荐用户优先使用通过变量名方式来访问变量,通过变量名的方式访问变量的本质是先通过变量名获取该变量的句柄,之后对该变量的操作均以句柄进行,这里的句柄是指windows中的句柄,不能简单等同于变量的指针(嵌入式中有此种叫法),详细解释可参阅百度百科的说明
链接: 句柄
例如,我们要通过变量名的方式访问变量PLCVar1,通过上位机来读写PLCVar1,下面给出了上位机中的程序,如果需要更改变量的名字,那么只需要更改szVar[]数组内的字符串即可。
变量名的全称即为上图中的Full-Name栏的内容

#include <iostream>
#include <windows.h>
#include <conio.h>



// ADS headers for TwinCAT 3
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsDef.h"
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h"

using namespace std;
int main()
{
	long nErr, nPort;
	AmsAddr Addr;
	PAmsAddr pAddr = &Addr;
	ULONG lHdlVar;//用来存放MAIN.PLCVar1变量的句柄
	float PLCVar1Get;//该变量存放要写入PLC中的值
	char szVar[] = { "MAIN.PLCVar1" };//需要读写的PLC中的变量名的全称

	// Open communication port on the ADS router
	nPort = AdsPortOpen();
	nErr = AdsGetLocalAddress(pAddr);
	if (nErr) cerr << "Error: AdsGetLocalAddress: " << nErr << '\n';

	// TwinCAT 3 PLC1 = 851
	pAddr->port = 851;

	// 获取MAIN.PLCVar1变量的句柄
	nErr = AdsSyncReadWriteReq(pAddr, ADSIGRP_SYM_HNDBYNAME, 0x0, sizeof(lHdlVar), &lHdlVar, sizeof(szVar), szVar);
	cout << "HandleNum Of Variable:"<<lHdlVar << endl;
	if (nErr) cerr << "Error: AdsSyncReadWriteReq: " << nErr << '\n';
	while(1)
	{
		// Read value of a PLC variable (by handle)
		nErr = AdsSyncReadReq(pAddr, ADSIGRP_SYM_VALBYHND, lHdlVar, sizeof(PLCVar1Get), &PLCVar1Get);
		if (nErr)
			cerr << "Fehler: AdsSyncReadReq: " << nErr << '\n';
		else
			cout << "MAIN.PLCVar1: " << PLCVar1Get << '\n';
		cout.flush();
		cin >> PLCVar1Get;
			nErr = AdsSyncWriteReq(pAddr, ADSIGRP_SYM_VALBYHND, lHdlVar, sizeof(PLCVar1Get), &PLCVar1Get);
			if (nErr) cerr << "Error: AdsSyncWriteReq: " << nErr << '\n';
	} 

/*

	//Release handle of plc variable
	nErr = AdsSyncWriteReq(pAddr, ADSIGRP_SYM_RELEASEHND, 0, sizeof(lHdlVar), &lHdlVar);
	if (nErr) cerr << "Error: AdsSyncWriteReq: " << nErr << '\n';

	// Close communication port
	nErr = AdsPortClose();
	if (nErr) cerr << "Error: AdsPortClose: " << nErr << '\n';
	return 0;
*/
}

下面给出PLC中的程序

PROGRAM MAIN
VAR
	PLCVar1:REAL;
	PLCVar2:BOOL;
	PLCVar3:INT;
END_VAR

运行结果如下图所示,PLC中的变量初始值我们设为30.22,运行上位机程序后可以读到变量是30.22
在这里插入图片描述
在这里插入图片描述
把变量更改为50.1478,可以看到PLC中的变量已经变为50.1478
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

上位机使用C++通过ADS协议与倍福PLC通信例程-通过变量名方式读写浮点数 的相关文章

随机推荐

  • 26从零开始学Java之如何对数组进行排序与二分查找?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套开源项目资料 https github com SunLtd Lear
  • 27从零开始学Java之详解复杂的二维数组与多维数组

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 在前几篇文章中 xff0c 壹哥给大家介绍了Java里的一维数组 x
  • 28从零开始学Java之面向对象和面向过程到底有哪些区别?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 壹哥相信 xff0c 经过你对前面文章中技术点的学习 xff0c 现
  • 29从零开始学Java之如何正确创建Java里的类?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 在上一篇文章中 xff0c 壹哥给大家介绍了面向对象和面向过程的概念
  • 全面图解路由器接口及连接(图)

    路由器所在的网络位置比较复杂 xff0c 既可是内部子网边缘 xff0c 也可位于内 外部网络边缘 同时为了实现强大的适用性 xff0c 它需要连接各种网络 xff0c 这样 xff0c 它的接口也就必须多种多样 对于这些 xff0c 不要
  • blktrace,blkparse,btt工具的制作和使用

    1 软件包交叉编译安装 1 1 blktrace源码下载路径 https git kernel dk cgit blktrace 1 2 源码安装 tar zxvf blktrace 1 2 0 tar gz cd blktrace 1 2
  • cartographer之ceres编译

    1 首先下载ceres xff1b 2 进入ceres目录 xff1b 3 mkdir build amp amp cd build 4 cmake DEIGENSPARSE 5 make 6 sudo make install
  • 一个空文件夹和空文件占多少空间?

    用于显示文件夹和文件大小的命令 span class token function du span h 显示目前在 Linux 系统上的文件系统磁盘使用情况统计 span class token function df span i 一 问
  • 虚拟地址如何访问到物理地址

    环境 xff1a 32bit CPU 一 通过二级页表映射的方式访问物理地址 1 取一级页表的基地址Abase1 2 取虚拟地址的前12bit 31 20 地址O1 3 计算得到新地址Apgd 61 Abase1 amp 0xFFFFF00
  • 添加自定义的section

    一 基本知识点 编译出来的程序 xff08 o so exe ko等等 xff09 都是以elf格式进行排列保存的 elf文件分析情况 xff1a https blog csdn net edonlii article details 87
  • 如何打印堆栈

    一 打印堆栈可以方便问题定位 xff0c 找到具体的函数调用流程 二 打印堆栈的方法 2 1 用户态 include lt stdio h gt include lt stdlib h gt include lt stddef h gt i
  • 内存飞踩问题的几点思考

    1 程序编译 xff0c 链接后生成二进制可执行程序 二进制可执行文件以elf格式实现排列 可以通过readelf S xxxx查看具体section的划分 xff0c 粗略划分如下图所示 在这些section中 xff0c 代码段是只读的
  • CFS调度算法

    1 CFS调度算法 xff0c 顾名思义就是完全公平调度策略 比方说 xff0c 调度延迟时间是10ms xff0c 存在两个进程A和B xff0c 那么两个进程分别占用CPU的时间是5ms 然而 xff0c 阶级总是存在的 xff0c 毕
  • ARM处理器的异常模式

    1 ARM处理器有各种异常模式 xff0c 用于应对ARM出现的不同状态 出现异常时 xff0c 会随即进入相关的异常向量 xff0c 同时CPSR的寄存器也会设置成具体的模式 例 xff1a 当出现中断时 xff0c 不管是哪种中断 xf
  • 内核态和用户态相关的内存泄漏

    应用程序通过系统调用进入内核态代码 假如内核态代码存在内存泄漏 xff0c 此内存泄漏属于内核态还是用户态 xff1f 查看内核态和用户态的统计信息
  • 为什么在telnet登入界面下没有日志输出?

    1 每个进程的输入输出导向目标都可以在进程号下的fd软链接上查看 如 569号进程的输出目标是 dev console xff0c 即串口 其中0是标准输入 xff0c 1是标准输出 xff0c 2是标准错误输出 2 因此我们只需要查看te
  • 【无标题】

    1 将虚拟地址传入到内核态 xff0c 借助内核态中mm struct结构体的pgd页表基地址成员 xff0c 经过查页表的方式最终获取到物理地址 这种方法虽然很直观 xff0c 但是一会内核态 xff0c 一会用户态 xff0c 操作起来
  • C#串口=>发送和接收

    作用 xff1a 串口发送命令后 xff0c 等待下位机应答帧 代码 xff1a 一旦读取到数据就立即返回给上层 public string TXandRX byte buffer string data 发送 RS485专用 start
  • kprobe功能的代码实现

    1 可以借助 sys kernel debug tracing目录下的文件 xff0c linux提供了kprobes功能 xff0c 抓取内核函数中的入参和返回值 kprobes xff0c 强大的调试工具 sydyh43的博客 CSDN
  • 上位机使用C++通过ADS协议与倍福PLC通信例程-通过变量名方式读写浮点数

    前言 建议初学者先看这一章节内容 xff0c 里面包括一些基础的环境配置和项目建立流程 xff0c 以后开发项目这些流程是通用的 xff0c 务必掌握并熟练 链接 上位机使用C 43 43 通过ADS协议与倍福PLC通信例程 布尔变量的读取