栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

上位机使用C++通过ADS协议与倍福PLC通信例程-字符串变量读取

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

上位机使用C++通过ADS协议与倍福PLC通信例程-字符串变量读取

前言

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

字符串知识 C/C++对字符串的处理

字符串是字符按一定顺序排列的结果,大部分情况下就是由字母组成的单词和句子,在C/C++中,字符串不是一个基本变量类型,基本变量类型是指char,int,float等这种变量类型,C/C++把字符串储存在字符数组中,即char类型的数组中,并在数组的末尾添加“”空字符来表示字符串的结束,可以理解为这是一个结束标记,这样处理以后,实际字符串占的存储单元就多了1个字节,如果声明一个char[20]的数组,那它最多能存储19个字符,如果直接声明一个例如string类型的变量,例如下面这个

// string类型的变量
std::string VarString1 = "Trump is back";

那么 VarString1将占用14个字节(空格也要占用一个字节)

TwinCAT对字符串的处理

在TwinCAT中,如果使用的是ST编程语言(IEC61131-3中规定的PLC编程语言中的一种),它是提供string类型的变量的,但其存储方式与C/C++对字符串的处理是一样的,同样用字符数组来存储,如果不指定大小,系统默认会分配一个80个字符的空间留给用户使用,在存储单元中则占据81个字节(因为要存储结束符号),如下图所示,我们实际赋值的时候,不要超过80个字符就可以了。

上位机程序实现

在上位机中,声明一个char Data1[81]的数组用来存放从PLC中读取上来的字符串值,这里的81即和PLC中string声明出来的变量所占空间匹配的结果。

#include 
#include
#include 
#include
#include
#include "TcAdsDef.h" //结构体和常量的声明
#include "TcAdsAPI.h" // ADS函数的声明

long      nErr, nPort;		//定义端口变量
AmsAddr   LocalAddr;				//定义上位机AMS地址变量
PAmsAddr  LocalpAddr = &LocalAddr;	//定义上位机ADS端口地址变量(上位机用来进行ADS通信的端口)

AmsAddr   Tc3Addr;				//定义安装有TwinCAT3的下位机AMS地址变量(由于是本机测试,上位机和下位机的AMS地址是一样的)
PAmsAddr  Tc3pAddr = &Tc3Addr;	//定义下位机端口地址变量(这里是读取PLC程序中变量,所以该端口固定为851)

unsigned long IndexGroup = 0xF020;   //要读取的对象的索引编号
unsigned long IndexOffset = 0x5DE93; // 要读取对象的偏移量编号
unsigned long Length = 1;            //要读取对象的大小,计量单位为byte
bool Data;                         //该变量用来存放读上来的值,变量类型要和待读取的值匹配

unsigned long IndexGroup1 = 0x4040;//要读取的对象的索引编号
unsigned long IndexOffset1 = 0x6CF40; // 要读取对象的偏移量编号
unsigned long Length1 = 81;            //要读取对象的大小,计量单位为byte
char Data1[81];                       //该变量用来存放读上来的值,变量类型要和待读取的值匹配

void ReadBoolen(void);
void ReadString(void);

int main()
{
	//建立接口通讯连接
	nPort = AdsPortOpen();		//打开ADS通讯端口
	nErr = AdsGetLocalAddress(LocalpAddr); //自动获取本地地址
	if (nErr)
		std::cerr << "Error: AdsGetLocalAddress: " << nErr << 'n';
	else
	{
		std::cout << "LocalAdsAddress is: ";
		printf("%d.", LocalpAddr->netId.b[0]);
		printf("%d.", LocalpAddr->netId.b[1]);
		printf("%d.", LocalpAddr->netId.b[2]);
		printf("%d.", LocalpAddr->netId.b[3]);
		printf("%d.", LocalpAddr->netId.b[4]);
		printf("%d.", LocalpAddr->netId.b[5]);
		std::cout << std::endl;
		std::cout << "LocalAdsPort Assigned is:" << LocalpAddr->port << std::endl;
	}
	if (nPort == LocalpAddr->port)
	{
		std::cout << "LocalAdsPort: " << nPort << " opened!" << std::endl;
	}
	else
	{
		std::cout << "LocalAdsPort open failed!" << std::endl;
	}
	Tc3pAddr->netId.b[0] = 5; //填入下位机的地址,即远程PLC的AmsNetID
	Tc3pAddr->netId.b[1] = 19;
	Tc3pAddr->netId.b[2] = 218;
	Tc3pAddr->netId.b[3] = 60;
	Tc3pAddr->netId.b[4] = 1;
	Tc3pAddr->netId.b[5] = 1;
	Tc3pAddr->port = 851; //填入下位机的TC3 PLC的通讯端口(851),这是倍福官方规定的,固定为851,TC2中为801,增加几个PLC,就依次增加为852,853...
	std::cout << "The Remote PLC AmsNetID is: ";
	printf("%d.", Tc3pAddr->netId.b[0]);
	printf("%d.", Tc3pAddr->netId.b[1]);
	printf("%d.", Tc3pAddr->netId.b[2]);
	printf("%d.", Tc3pAddr->netId.b[3]);
	printf("%d.", Tc3pAddr->netId.b[4]);
	printf("%d.", Tc3pAddr->netId.b[5]);
	std::cout << std::endl;
	std::cout << "The Remote PLC ADS ComunicationPort is : "<port< 
下位机程序实现 


变量声明区的内容

PROGRAM MAIN
VAR
	bVarOut1 AT%Q*:BOOL;
	bVarIn1 AT%I*:BOOL;
	sString:STRING;
END_VAR

程序区的内容

bVarOut1 := bVarIn1;
sString :='Trump is back!';

运行上位机程序和远程PLC(切换到运行状态下),可以看见能成功读取到PLC中声明的string类型变量

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1018933.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号