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

前言

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

字符串知识

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

字符串是字符按一定顺序排列的结果,大部分情况下就是由字母组成的单词和句子,在C/C++中,字符串不是一个基本变量类型,基本变量类型是指char,int,float等这种变量类型,C/C++把字符串储存在字符数组中,即char类型的数组中,并在数组的末尾添加“\0”空字符来表示字符串的结束,可以理解为这是一个结束标记,这样处理以后,实际字符串占的存储单元就多了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个字节(因为要存储\0结束符号),如下图所示,我们实际赋值的时候,不要超过80个字符就可以了。
在这里插入图片描述

上位机程序实现

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

#include <iostream>
#include<conio.h>
#include <stdio.h>
#include<iomanip>
#include<Windows.h>
#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)
/* 读取bool量的配置信息 */
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 : "<<Tc3pAddr->port<<std::endl;

	while (1)
	{		
		Sleep(500);
		ReadBoolen();
		ReadString();
	}
}

void ReadBoolen(void)
{
	nErr = AdsSyncReadReq(Tc3pAddr, IndexGroup, IndexOffset, Length, &Data);
	if (nErr)
		std::cerr << "ReadFailed! The Error Code is: " << nErr << '\n';
	else
	{
		std::cout << "Operation Succeed!" << std::endl;
		std::cout << "The Value Read is:" << Data << std::endl;
	}
	Sleep(500);//每500ms刷新一次值
}

void ReadString(void)
{
	nErr = AdsSyncReadReq(Tc3pAddr, IndexGroup1, IndexOffset1, Length1, &Data1);
	if (nErr)
		std::cerr << "ReadFailed! The Error Code is: " << nErr << '\n';
	else
	{
		std::cout << "Operation Succeed!" << std::endl;
		std::cout << "The Value Read is:" << Data1 << std::endl;
	}
	Sleep(500);//每500ms刷新一次值
}

下位机程序实现

在这里插入图片描述
变量声明区的内容

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

程序区的内容

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

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

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值