在qt中使用c++实现与Twincat3 PLC变量通信

发布于:2025-05-29 ⋅ 阅读:(21) ⋅ 点赞:(0)

这是一个只针对新手的教程,下载安装就不说了,我下的是TC31-Full-Setup.3.1.4024.66.exe是这个版本,其他版本应该问题不大。

先创建一个项目

选中SYSTEM,在右侧点击Choose Target(接下来界面跟我不一样没关系,因为是从已有的项目上截的图,像plc可能你们没有文件,后面会讲),选择Search,进去再选择Broadcast Search,选择你要的那个,你们可能没有那个“x”,“x”代表连接成功,接下来点击Add Route,取消勾选Secure ADS(本次用不到),输入密码(查了下,默认密码应该是1或者没有),点击ok,接下来应该就有“x”了,代表连接成功了,点击close,记住你设备对应地址,接下来在c++会用到,点击ok(说一下跳出什么提示都点是,后面也是)。

接下来编写pcl代码,右键PLC添加新项,选择Standard PLC Project,点击添加,这样plc下就会出来一堆文件,找到POUS文件,点击里面的MAIN,这样就可以编写plc程序了。

我这边定义了a,b,c,sum如图所示(我也是第一次写plc程序,稍微查了一下,这边上下两部分,上面是初始化变量区域,下面是逻辑运算区域),自己写入a,b,c的值,最后相加得到sum,右键点击你的plc文件名,再点击生成,编译完之后点击上方activate configuration,跳出提示框一直点ok/是,进入run mode,这里应该能看见你设备上的TC灯变成绿色,这样Twincat端的基本已经完成,现在写c++程序。

我这边使用qt编写c++程序(其他应该也可以),先创建一个c++程序,在.pro中添加ads的库与头文件的路径,路径按自己实际情况改。添加头文件#include <windows.h>,#include <TcAdsDef.h>
#include <TcAdsAPI.h>,严格根据这个顺序来,不然可能会报错,定义端口变量,AMS地址变量,端口地址变量,以及对应的用来接收你在pcl中定义变量的值的变量(这里我用short定义是因为pcl中int只有2字节,为了对应,c++中使用short定义),使用AdsPortOpen()函数打开ads端口通信,设置端口为851(默认端口),手动填写目标设备的AMSNETID,即上面让你们记得的那个地址(这里手动填写是因为我不知道啥原因自动填写有问题,感兴趣可以试试,就我注释掉那一部分)。

TEMPLATE = app
CONFIG += console c++17
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += \
        main.cpp


INCLUDEPATH += $$quote(C:/TwinCAT/AdsApi/TcAdsDll/Include)

LIBS += $$quote(C:/TwinCAT/AdsApi/TcAdsDll/x64/lib/TcAdsDll.lib)

 

    long        nErr, nPort;//定义端口变量
    AmsAddr     Addr;//定义AMS地址变量
    PAmsAddr    pAddr = &Addr;//定义端口地址变量
    short       a,b,c;
    short       sum;

    nPort = AdsPortOpen();//打开ADS通讯端口
    // nErr = AdsGetLocalAddress(pAddr);
    // if (nErr) cerr << "Error:AdsGetLocalAddress:" << nErr << '\n';
    pAddr->port = 851;//TC3通讯使用的为851端口
    pAddr->netId.b[0] = 169; //手动填写目标设备的AMSNETID
    pAddr->netId.b[1] = 254;
    pAddr->netId.b[2] = 100;
    pAddr->netId.b[3] = 116;
    pAddr->netId.b[4] = 1;
    pAddr->netId.b[5] = 1;

通过AdsSyncWriteReq 函数,自行写入a,b,c的值,在Twincat中按下ctrl+q进入查找功能,输入browser,选择第一个就可以跳到Target Browser界面,可以查看变量的段地址和偏移地址,按图中写入代码,循环读取a,b,c,sum的值(看自己要求要不要循环读取),最后记得用AdsPortClose()函数关闭ads通信端口。

    //写入a的值
    cout << "a = ";
    cin >> a;
    nErr = AdsSyncWriteReq(pAddr,0x4020,0x8,0x2,&a);
    if (nErr) cerr << "Error : AdsSyncWriteReq:" << nErr << '\n';

    //写入b的值
    cout << "b = ";
    cin >> b;
    nErr = AdsSyncWriteReq(pAddr,0x4020,0x10,0x2,&b);
    if (nErr) cerr << "Error : AdsSyncWriteReq:" << nErr << '\n';

    //写入c的值
    cout << "c = ";
    cin >> c;
    nErr = AdsSyncWriteReq(pAddr,0x4020,0x18,0x2,&c);
    if (nErr) cerr << "Error : AdsSyncWriteReq:" << nErr << '\n';

do{
        //读取a的值
        nErr = AdsSyncReadReq(pAddr,0x4020,0x8,0x2,&a);
        if (nErr) cerr << "Error : AdsSyncReadReq:" << nErr << '\n';
        cout << a << endl;
        //读取b的值
        nErr = AdsSyncReadReq(pAddr,0x4020,0x10,0x2, &b);
        if (nErr) cerr << "Error : AdsSyncReadReq:" << nErr << '\n';
        cout << b << endl;
        //读取c的值
        nErr = AdsSyncReadReq(pAddr,0x4020,0x18,0x2,&c);
        if (nErr) cerr << "Error : AdsSyncReadReq:" << nErr << '\n';
        cout << c << endl;
        //读取sum的值
        nErr = AdsSyncReadReq(pAddr,0x4020,0x20,0x2,&sum);
        if (nErr) cerr << "Error : AdsSyncReadReq:" << nErr << '\n';
        cout << "sum = " << sum << '\n';
        cout << "--------------" << endl;
        cout << endl;
        Sleep(200);
    }while(1);

    nErr = AdsPortClose();
    if (nErr) cerr << "Error:AdsPortClose:" << nErr << '\n';

 回到plc端点击loin按钮,我是直接运行的,有些版本可能还要点在一下三角图案来运行,运行之后会自动跳出一个MAIN[Online]界面,可以看到初始值都为0,在qt中勾选上在终端中运行,接下来运行c++程序,可以看到我给a,b,c分别赋值1,2,3,最终得到sum为6,同时Twincat中的a,b,c,sum也跟着变化了(其实如果只有读取可以不按login也能成功,但如果你要写入一定要点login才能成功改变值)。

这是全部的源代码

#include <iostream>
//#include <conio.h>
#include <windows.h>
#include <TcAdsDef.h>
#include <TcAdsAPI.h>

using namespace std;

int main()
{
    long        nErr, nPort;//定义端口变量
    AmsAddr     Addr;//定义AMS地址变量
    PAmsAddr    pAddr = &Addr;//定义端口地址变量
    short       a,b,c;
    short       sum;

    nPort = AdsPortOpen();//打开ADS通讯端口
    // nErr = AdsGetLocalAddress(pAddr);
    // if (nErr) cerr << "Error:AdsGetLocalAddress:" << nErr << '\n';
    pAddr->port = 851;//TC3通讯使用的为851端口
    pAddr->netId.b[0] = 169; //手动填写目标设备的AMSNETID
    pAddr->netId.b[1] = 254;
    pAddr->netId.b[2] = 100;
    pAddr->netId.b[3] = 116;
    pAddr->netId.b[4] = 1;
    pAddr->netId.b[5] = 1;


    //写入a的值
    cout << "a = ";
    cin >> a;
    nErr = AdsSyncWriteReq(pAddr,0x4020,0x8,0x2,&a);
    if (nErr) cerr << "Error : AdsSyncWriteReq:" << nErr << '\n';

    //写入b的值
    cout << "b = ";
    cin >> b;
    nErr = AdsSyncWriteReq(pAddr,0x4020,0x10,0x2,&b);
    if (nErr) cerr << "Error : AdsSyncWriteReq:" << nErr << '\n';

    //写入c的值
    cout << "c = ";
    cin >> c;
    nErr = AdsSyncWriteReq(pAddr,0x4020,0x18,0x2,&c);
    if (nErr) cerr << "Error : AdsSyncWriteReq:" << nErr << '\n';



    do{
        //读取a的值
        nErr = AdsSyncReadReq(pAddr,0x4020,0x8,0x2,&a);
        if (nErr) cerr << "Error : AdsSyncReadReq:" << nErr << '\n';
        cout << a << endl;
        //读取b的值
        nErr = AdsSyncReadReq(pAddr,0x4020,0x10,0x2, &b);
        if (nErr) cerr << "Error : AdsSyncReadReq:" << nErr << '\n';
        cout << b << endl;
        //读取c的值
        nErr = AdsSyncReadReq(pAddr,0x4020,0x18,0x2,&c);
        if (nErr) cerr << "Error : AdsSyncReadReq:" << nErr << '\n';
        cout << c << endl;
        //读取sum的值
        nErr = AdsSyncReadReq(pAddr,0x4020,0x20,0x2,&sum);
        if (nErr) cerr << "Error : AdsSyncReadReq:" << nErr << '\n';
        cout << "sum = " << sum << '\n';
        cout << "--------------" << endl;
        cout << endl;
        Sleep(200);
    }while(1);


    nErr = AdsPortClose();
    if (nErr) cerr << "Error:AdsPortClose:" << nErr << '\n';
}

 

以上就是在qt中使用c++实现与Twincat3 PLC变量通信全过程,本人也是第一次接触也是摸索了很久,希望能帮到大家。
如果要长时间接触倍福可以虚拟倍福学园自己学习一下https://tr.beckhoff.com.cn/


网站公告

今日签到

点亮在社区的每一天
去签到