PC通过变量名访问PLC
BeckOff官网ADS通讯相应说明:
https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_adsdll2/9007199379568907.html&id=
ADS返回错误码:
https://infosys.beckhoff.com/english.php?content=../content/1033/devicemanager/374277003.html&id=
PLC端
PROGRAM MAIN
VAR
TEST : REAL;
BTEST : INT;
CTEST : BYTE;
array1 : ARRAY[0..5] OF INT;
i: INT;
END_VAR
TEST := 3.14159;
BTEST :=17;
CTEST :=65;
FOR i:= 0 TO 5 DO
array1[i]:=i;
END_FOR
访问PLC中INT、UINT、BYTE、REAL时,PC端分别设置nData为USHORT、USHORT、UCHAR、FLOAT类型,可依次传递整形、字符、浮点型数据。
访问PLC数组ARRAY时,PC端nData设置为同上对应数组;
PC端
查看PLC的NetID,在TwinCAT环境可根据
C:\TwinCAT\3.1\Target
目录下的StaticRoutes.xml文件查看:
- 配置
- 包含目录:C:\TwinCAT\AdsApi\TcAdsDll\Include;
- 库目录:C:\TwinCAT\AdsApi\TcAdsDll\Lib;
- 附加依赖项:TcAdsDll.lib;
#include <iostream>
#include <windows.h>
#include "TcAdsDef.h"
#include "TcAdsAPI.h"
#include <conio.h>
using namespace std;
void main()
{
long nErr, nPort;
AmsAddr Addr;
PAmsAddr pAddr = &Addr;
ULONG lHdlVar;
USHORT nData;
//FLOAT nData; //TEST := 3.14159; //浮点型
//UCHAR nData; //CTEST :=65; //字符型
//变量名
char szVar[] = { "MAIN.BTEST" };
//在 ADS 路由器上打开通信端口
nPort = AdsPortOpen();
//PLC的NetID
AmsNetId _AmsId = { 5, 52, 76, 79, 1, 1 };
pAddr->netId = _AmsId;
// TwinCAT 3 PLC1 = 851
pAddr->port = 851;
// 获取 <szVar> PLC 变量的句柄
nErr = AdsSyncReadWriteReq(pAddr, ADSIGRP_SYM_HNDBYNAME, 0x0, sizeof(lHdlVar), &lHdlVar, sizeof(szVar), szVar);
if (nErr) cerr << "Error: AdsSyncReadWriteReq: " << nErr << '\n';
do
{
// 读取 PLC 变量的值(通过句柄)
nErr = AdsSyncReadReq(pAddr, ADSIGRP_SYM_VALBYHND, lHdlVar, sizeof(nData), &nData);
if (nErr)
cerr << "Fehler: AdsSyncReadReq: " << nErr << '\n';
else
cout << "Wert: " << nData << '\n';
cout.flush();
if (nData > 10)
{
// 将 PLC 变量的值重置为 0
nData = 0;
nErr = AdsSyncWriteReq(pAddr, ADSIGRP_SYM_VALBYHND, lHdlVar, sizeof(nData), &nData);
if (nErr) cerr << "Error: AdsSyncWriteReq: " << nErr << '\n';
}
} while (getch() == '\r'); // 用 RETURN 读取下一个值,否则结束
//释放plc变量的句柄
nErr = AdsSyncWriteReq(pAddr, ADSIGRP_SYM_RELEASEHND, 0, sizeof(lHdlVar), &lHdlVar);
if (nErr) cerr << "Error: AdsSyncWriteReq: " << nErr << '\n';
// 关闭通讯口
nErr = AdsPortClose();
if (nErr) cerr << "Error: AdsPortClose: " << nErr << '\n';
}