关于PC端与PLC端以太网通信

article/2025/10/14 6:36:39

一、TCPIP通信

以太网通信基本上最先想到的是TCPIP

就是在PC端的VS上布置服务器端,我用的是VS2015,最长用的是WinSock2.h

大致的步骤就是:

      a.初始化版本号

      b.建立套接字

      c.定义并绑定地址

      d.进入监听状态

      e.接收连接请求

      f.交换数据

有一点值得注意的是,Inter的CPU和西门子的CPU的储存方式不同,大端和小端储存方式。就是你VS定义的一个int型数据,在传输的时候char[0]是高位,而西门子的储存方式是char[3]是高位。这个也是做了大量的实验发现的问题,后来在西门子提供的prodave库中的函数也得到了证明。

send_text[0] = temp_send[3];
send_text[1] = temp_send[2];
send_text[2] = temp_send[1];
send_text[3] = temp_send[0];

转换以后再发送,数就能对的上了,但是还有问题。

做实验的时候发现,可能PLC通信的时候还需要时序的信息,还有一些不为人知的数据结构,这就导致PC发送的时候,PLC收到的是不含时序或者混乱的信息。比如我发送三个数,一个浮点一个整型,一个bool型给PLC,PLC的DB块负责接收,发现第1次接收是正确的,第2次就错了,第3次错,第4次错,第5次错,第6次正确。。。就是这样的情况。

PLC			PC
123			64
20			-34
-34			20
64			123
-20			65
81			4
4			81
65			-20
0			0
0			0
-34			0
64			0-89			64
-116			-34
123			20
20			123
82			65
-114			4
-20			81
21			-20
-89			0
-116			0
123			0
20			0-20			64
81			-34
4			20
65			123
123			65
20			4
-34			81
64			-20
0			0
0			0
4			0
65			082			64
-114			-34
-20			20
21			123
-89			65
-116			4
123			81
20			-20
82			0
-114			0
-20			0
21			082			64
-114			-34
-20			20
21			123
-89			65
-116			4
123			81
20			-20
82			0
-114			0
-20			0
21			0123			64
20			-34
-34			20
64			123
-20			65
81			4
4			81
65			-20
0			0
0			0
-34			0
64			0

就像这样的。还有一个问题就是,当第一个数只要是浮点就会发生这样的情况,但是换成第一个是整型,第二个数是浮点,问题就不会发生了。所以这样的通信是不能让人接受的。

二、OPC方式

OPC方式需要直接在PLC组态的时候就要和Windows的OPC进行OPC组态,连接成功就能通信。

需要通过vs读取windows opc中的数据,查资料知道MatrikonOPC可以简单的和VS搭配

这个需要提前安装MatrikonOPCSimulation工具,默认路径安装就行。这是代码:

#import "C://Windows//SysWOW64//OPCAuto.dll"
#pragma warning( disable : 4786 )
#include <comdef.h>
#include <vector>
#include <iostream>using namespace std;using namespace OPCAutomation;//声明全局变量
typedef struct OLEInit {OLEInit() { CoInitialize(NULL); }~OLEInit() { CoUninitialize(); }
} OLEInit;OLEInit oleInit;
OPCAutomation::IOPCAutoServerPtr opcSvr;
OPCAutomation::IOPCGroupsPtr opcGrps;
OPCAutomation::IOPCGroupPtr opcGrp;
vector<OPCAutomation::OPCItemPtr> opcItems;//连接到OPC Server
void agOPConn(const char * opcSvrName)
{HRESULT hr;hr = opcSvr.CreateInstance(_uuidof(OPCServer));if (FAILED(hr)){cerr << "OPCSever CreateInstance failed, hr = " << hr << endl;exit(1);}opcSvr->Connect(opcSvrName);
}//断开连接void agOPCDisc()
{opcGrps->RemoveAll();opcSvr->Disconnect();
}//创建一个组void agOPCCreateGroup()
{opcGrps = opcSvr->OPCGroups;opcGrp = opcGrps->Add(_variant_t("group1"));
}void agOPCAddItems()
{OPCItemPtr opcItm;opcItm = opcGrp->OPCItems->AddItem(_bstr_t("Bucket Bridge.Int4"),1);opcItems.push_back(opcItm);opcItm = opcGrp->OPCItems->AddItem(_bstr_t("Bucket Bridge.Int2"), 1);opcItems.push_back(opcItm);opcItm = opcGrp->OPCItems->AddItem(_bstr_t("Bucket Bridge.String"), 1);opcItems.push_back(opcItm);}//显示读取的值void agDumpVariant(VARIANT *v)
{switch (v->vt){case VT_I2:printf("value(VT_I2) = %d ", v->iVal);break;case VT_I4:printf("value(VT_I4) = %ld", v->lVal);break;case VT_BSTR:printf(" value(VT_BSTR) = %ls ", v->bstrVal);break;default:printf(" value(unknown type:%d) ", v->vt);break;}
}//同步读取三个Item的值,同步在很多情况下都是简单有效的选择方案,其实读取的异步方式在C++中可以建立一个工作线程来执行同步读的操作,等有新的Item值的时候再通过某种线程间通信的方式告诉主线程“数据改变”的事件
void agOPCReadItems() {_variant_t            quality;_variant_t            timestamp;SAFEARRAY            *pServerHandles;SAFEARRAY            *pValues;SAFEARRAY            *pErrors;SAFEARRAYBOUND        rgsabound[1];long                dim[1];long                svrHdl;vector<_variant_t>    values;vector<long>        errs;int                    i;_variant_t            value;long                err;// VC数组索引从0开始,而在OPCAuto.dll需要中从1开始,所以是rgsabound[ 0 ].cElements = 4,而给pServerHandles赋值的时候应该给索引是1,2,3相应的赋值Server Handlergsabound[0].cElements = 4;rgsabound[0].lLbound = 0;pServerHandles = SafeArrayCreate(VT_I4, 1, rgsabound); //构建一个1维数组,类型是VT_I4for (i = 0; i < opcItems.size(); i++) {svrHdl = opcItems[i]->ServerHandle;dim[0] = i + 1;// 给数组的每个元素赋值,对应的索引值是1, 2, 3SafeArrayPutElement(pServerHandles, dim, &svrHdl);}opcGrp->SyncRead(OPCDevice,3,                      // 读取的Item数目&pServerHandles,        // 输入的服务器端句柄数组&pValues,               // 输出的Item值数组&pErrors,               // 输出的Item错误状态数组&quality,               // 读取的值的状态&timestamp);           // 读取的事件戳for (i = 1; i <= opcItems.size(); i++) {dim[0] = i;SafeArrayGetElement(pValues, dim, &value); // 读取Item值在value中SafeArrayGetElement(pErrors, dim, &err);   // 读取错误状态值在err中   values.push_back(value);errs.push_back(err);}for (i = 0; i < values.size(); i++) {agDumpVariant(&values[i]);   // 显示读取的Item值cout << ", err = " << errs[i] << endl;}SafeArrayDestroy(pServerHandles);SafeArrayDestroy(pValues);SafeArrayDestroy(pErrors);
}// 写入3个Item的值,为了演示实例简单,参数传递3个对应的Item值
void agOPCWriteItems(vector<_variant_t> values) {_variant_t    quality;_variant_t    timestamp;SAFEARRAY    *pServerHandles;SAFEARRAY    *pValues;SAFEARRAY    *pErrors;long        dim[1];long        svrHdl;int            i;SAFEARRAYBOUND rgsabound[1];rgsabound[0].cElements = values.size() + 1;rgsabound[0].lLbound = 0;pServerHandles = SafeArrayCreate(VT_I4, 1, rgsabound);pValues = SafeArrayCreate(VT_VARIANT, 1, rgsabound);for (i = 0; i < values.size(); i++) {svrHdl = opcItems[i]->ServerHandle;dim[0] = i + 1;SafeArrayPutElement(pServerHandles, dim, &svrHdl);SafeArrayPutElement(pValues, dim, &values[i]);}opcGrp->SyncWrite(3, &pServerHandles, &pValues, &pErrors);SafeArrayDestroy(pServerHandles);SafeArrayDestroy(pValues);SafeArrayDestroy(pErrors);
}//main主程序
int main()
{try{agOPConn("Matrikon.OPC.Simulation.1");agOPCCreateGroup();agOPCAddItems();// 第一次写和读vector<_variant_t> values;values.push_back((long)156);values.push_back((short)11);values.push_back("opc");agOPCWriteItems(values);agOPCReadItems();cout << "---------------------------------------" << endl;// 第二次写和读vector<_variant_t> values1;values1.push_back((long)123456);values1.push_back((short)666);values1.push_back("hello");agOPCWriteItems(values1);agOPCReadItems();}catch (_com_error &e) {// 应该在上面的子函数里面捕捉异常,但为了演示简单,在主函数里面捕捉异常_bstr_t bstrSource(e.Source());_bstr_t bstrDescription(e.Description());cout << "Code = " << e.Error() << endl;cout << "Code meaning = " << e.ErrorMessage() << endl;cout << "Source = " << (LPCTSTR)bstrSource << endl;cout << "Description = " << (LPCTSTR)bstrDescription << endl;}system("pause");getchar();return 0;
}

因为网上的代码import的时候加了no_namespace 但是得到的.tlh找不到OPCAuto.dll的底层函数接口,所以我就加上了,namespace问题解决。这样的通信方法,一组数大约需要100ms,可能不是因为数据量的问题,可能就是这样的速度。

三、prodave

prodave是西门子提供的库,用来和vs进行通信。现在我能找到最新的是6.2版本,需要安装prodave安装包,并注册激活。

安装完成目录下会生成VB、VC的demo,但是VC的demo需要改一些东西才能在C++中编译成功。

Prodave6.2    密码:yak3

授权               密码:qr7b

我改的demo   密码:c8ce


http://chatgpt.dhexx.cn/article/Tf0d3lGA.shtml

相关文章

施耐德PLC与西门子PLC以太网通讯

摘要 施耐德PLC(如&#xff1a;Quantum系列)需要和西门子S7300、S7200等PLC进行以太网数据通讯。。本文通过通讯桥接器NET30&#xff0c;实现西门子PLC与施耐德PLC进行modbusTCP以太网通讯连接。 网络拓扑图&#xff1a; 方案实施介绍 一、西门子PLC参数设置 1、西门子S7300配置…

西门子PLC1500系列开放式以太网通讯方式分享

西门子产品众多&#xff0c;应用十分广泛&#xff0c;但是面对种类繁多的说明书&#xff0c;大家可能没有时间深入阅读。天拓四方作为西门子核心合作伙伴&#xff0c;在平时的项目实施中总结出了大量的产品应用经验。如果您有任何问题&#xff0c;欢迎联系我们&#xff0c;在解…

欧姆龙plc之间的以太网通讯

捷米特JM-ETH-CP转以太网模块控&#xff0c;用于欧姆龙 CP1L/ CP1E/ CP1H 系列 PLC 的以太网数据采集&#xff0c;非常方便构建生产管理系统。 支持 FINS/UDP、FINS/TCP 以太网协议通信&#xff0c;支持上位机软件&#xff08;组态王、MCGS、力控、KepWare OPC 服务器等&#…

PLC不用编程,以太网方式与多台智能仪表、变频器等串口设备通讯(基于智能网关)

案例是通过一个IGT-SER智能网关&#xff0c;实现远程IO模块、智能仪表&#xff0c;变频器与PLC通讯。不同品牌的PLC之间通讯 网关与变频器之间采用ModbusRTU串口通讯&#xff0c;网关与变远程IO模块也是之间采用ModbusRTU串口通讯&#xff0c;都接成RS485网络后分别接入网关的串…

西门子PLC能否通过以太网数据模块实现无线通讯?

在实际系统中&#xff0c;同一个车间里分布多台PLC&#xff0c;通常距离在几十米到上百米不等。在有通讯需求的时候&#xff0c;如果布线的话&#xff0c;工程量较大且不美观&#xff0c;这种情况下比较适合采用无线通信方式。西门子S7-200 SMART系列PLC随着不断地升级功能也越…

西门子PLC串口协议与以太网通信协议对比

西门子plc品牌众多&#xff0c;通信协议的类型就更多了&#xff0c;具体可分为串口协议和以太网通信协议两大类。 串口协议主要有&#xff1a;MODBUS RTU 通信协议&#xff1b;PROFIBUS 通信协议&#xff1b;USS通信协议&#xff1b;PPI通信协议&#xff1b;MPI通信协议&#…

一个功能块实现PLC与安川机器人以太网通讯

PLC调用一个功能块实现与安川机器人通讯。 用最简单的通讯方式---标准以太网通讯来控制安川机器人&#xff0c;实现最全面的功能。开发背景见 屠龙技应用之--安川机器人。 安川机器人无需增加各类Profibus&#xff0c;ethernet/ip&#xff0c;CC-Link等专用网卡&#xff0c;无…

LabVIEW通过以太网(TCP)与S7-1200 PLC通信

LabVIEW通过以太网&#xff08;TCP&#xff09;与S7-1200 PLC通信 laiping 20170901 摘要&#xff1a;本文介绍LabView采用以太网&#xff08;TCP&#xff09;方式与西门子S7-1200PLC通讯 关键字&#xff1a;LabView、S7-1200、TCP、PLC、通信 1、概述 西门子S7-1200 PLC支…

不用编程,快速实现西门子PLC与罗克韦尔(AB)PLC之间以太网通讯

智能网关IGT-DSER支持多点对多点的PLC之间通讯&#xff0c;支持以太网&#xff0c;串口设备混合数据交换&#xff1b;无需编程开发&#xff0c;只须配置数据的起始地址和数量即可&#xff0c;支持热插拔&#xff0c;断电重启后自恢复运行&#xff0c;支持网络跨网段&#xff0c…

西门子S7-300型PLC与西门子S7200smart型PLC的以太网通讯例程

西门子S7-300型PLC与西门子S7200smart型PLC的以太网通讯例程 为程序 300PLC的IP地址&#xff1a;192.168.0.1 200PLC的IP地址&#xff1a;192.168.0.4 S7-300 与smart200以太网通讯 通信简介 S7 通信是S7系列PLC基于MPI、PROFIBUS、ETHERNET网络的一种优化的通信协议&#xff0…

西门子PLC 以太网通讯

云锋 个人主页给TA发消息加TA为好友发表于&#xff1a;2011-03-04 14:44:55楼主 实际工程中用过的PLC 以太网通信案例&#xff0c;需要把PLC型号、与PLC通信的设备、通信的各种参数及情况、通信实现的功能等说明清楚&#xff0c;贴出程序并加以说明。 PLC及与PLC通信的设备类…

三菱PLC内置以太网通讯

三菱PLC在与外界进行数据交换时可以使用内置以太网与PC建立连接。 实际使用三菱Q系列PLC&#xff0c;在连接之前测试网络是否连通&#xff0c;我采用的TCP/UDP测试工具&#xff0c;将PC端设置与PLC内网在同一网段&#xff0c;然后在编程软件中配置PLC参数。 如图所示&#xff…

不用编程实现PLC之间通讯-西门子与三菱以太网实时通讯

PLC通讯智能网关IGT-DSER支持各种PLC之间多对多通讯&#xff1b;PLC无需编程&#xff0c;只需配置寄存器地址&#xff0c;还带有字节顺序调整功能&#xff0c;方便快速实施&#xff1b;因为是多线程的交互模式&#xff0c;所以可以保证高实时性&#xff1b;支持串口、网口通讯&…

PLC 以太网通讯

&#xfeff; 云锋 个人主页给TA发消息加TA为好友发表于&#xff1a;2011-03-04 14:44:55楼主 实际工程中用过的PLC 以太网通信案例&#xff0c;需要把PLC型号、与PLC通信的设备、通信的各种参数及情况、通信实现的功能等说明清楚&#xff0c;贴出程序并加以说明。 PLC及与P…

同感,在另外一个小华为待过,也差不多是这样的

最近很多朋友咨询的一些硬件问题&#xff0c;发现朋友们没有仔细的看datasheet&#xff0c;也没有好好的做电路分析。我讲一讲华为是怎么做硬件开发的&#xff0c;给正在做硬件开发的朋友一些启示。说的不对的地方&#xff0c;大家批评指正。 曾经2007年&#xff0c;刚工作2年的…

转载的硬件十万个为什么

硬件十万个为什么 微信号 Hardware_10W 功能介绍 热爱技术&#xff0c;乐于分享 1、电源类 1.1 电源基础 各种“地”—— 各种“GND” 板载电源设计规范 电源环路稳定性评价方法 深入芯片内部&#xff0c;理解去耦电容的作用 减小DC/DC变换器中的接 地反弹——一些接地要点…

华为内部硬件开发设计流程

点击上方“大鱼机器人”&#xff0c;选择“置顶/星标公众号” 福利干货&#xff0c;第一时间送达 华为内部硬件开发设计流程 2007年&#xff0c;以2年的工作经验去一家小公司去面试。当时笔试完&#xff0c;对方对我很认可。但当时他说&#xff1a;“我需要招一个&#xff0c;在…

python语言创意绘画-校招资讯|拼多多、百度、中建六局等名企校园招聘

原标题&#xff1a;校招资讯&#xff5c;拼多多、百度、中建六局等名企校园招聘 1、【上海】拼多多 【公司简介】 拼多多是国内目前主流的手机购物APP。用户通过发起和朋友&#xff0c;家人&#xff0c;邻居等的拼团&#xff0c;以更低的价格&#xff0c;拼团购买商品。旨在…

嵌入式工程师是青春饭吗?越老越吃香吗?

信息来自火哥&#xff0c;朱晓明&#xff0c;CSDN等 一位不愿透露姓名的嵌入式工程师说过&#xff0c;“我是一名嵌入式软件工程师&#xff0c;我现在慌得一笔&#xff01;”并非计算机科班出身的他&#xff0c;整个七年下来感觉自己学习的课程也不比电子信息科班出身的少&…

关于硬件工程师的真相:敢问路在何方?

关于硬件工程师的真相&#xff1a;敢问路在何方&#xff1f; 硬件工程师&#xff0c;曾经有多少人希望从事的职业&#xff1f;在别人眼里好像能够从事硬件设计需要你了解很多东西&#xff0c;可以从事这个职业之后才逐渐发现&#xff0c;硬件工程师处在一种非常难受的困境当中…