目录

一、背景

二、可行性验证

三、开发调试


一、背景

在一般场景下,只需一路IO连接,但稍微复杂的场景,就需要不同通讯周期的连接,这就需要有多组IO连接。

而大于一组的连接调试方法是一样的,因此主要解决2组连接的代码开发。

二、可行性验证

在Eip Scanner Demo(主站)、PLC(从站)软件上分别配置两个生产者连接,验证其数据收发可行性及稳定性。得到视频及报文如下:

1、Enip

2、ForwardOpen 1

3、ForwardOpen 2

4、ForwardCloes 2

5、ForwardCloes 1

可见,进行了两次ForwardOpen,建立了两个生产者连接。

由上文可见,两个生产者连接的ForwardOpen的不同点在于:

1、Connection Path 由PLC自动生成,直接配置到Ubuntu中

2、Connecte Serial Number 自由选择,只要是两个连接不同即可,见协议原文

3、Connection Parameter (可选,如果两个收发字节数相同,则此项也相同)

因此,便可满足上述要求情况下,将多生产者连接集成到一个SDK中。

但需要注意多线程下的单一物理网口的数据抢占问题。

三、开发调试

发现在_connectionMap中管理了所有的IO连接。

在forwardopen阶段注册_connectionMap,每开一个IO连接都会注册一个_connectionMap进去

在handleConnections中,若IO连接不存在,则删除掉

而在代码中,无需在两个连接的情况下守护两个connectionManager,于是更改代码如下:

int main() {。。。。parameters.o2tRealTimeFormat = true;parameters.t2oRealTimeFormat = true;parameters.originatorVendorId = 0xaa;parameters.connectionTimeoutMultiplier=2;parameters.priorityTimeTick=10;parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::P2P;parameters.t2oNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;parameters.t2oNetworkConnectionParams |= 0; //size of Assm100 =1parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::P2P;parameters.o2tNetworkConnectionParams |= NetworkConnectionParams::SCHEDULED_PRIORITY;parameters.o2tNetworkConnectionParams |= 4; //size of Assm100 =1parameters.originatorSerialNumber = 0x012345;parameters.o2tRPI = 50000;parameters.t2oRPI = 50000;//50msparameters.transportTypeTrigger |= NetworkConnectionParams::CLASS1;parameters.transportTypeTrigger |= NetworkConnectionParams::TRIG_CYCLIC;  std::chrono::milliseconds timeout(5000);
//connect oneauto si_1 = std::make_shared<SessionInfo>("192.168.2.88", 0xAF12,timeout,50000);ConnectionManager connectionManager_1;parameters.connectionPath = {0x20, 0x04,0x24, 0x01, 0x2C, 0x65, 0x2C, 0xFF}; parameters.connectionSerialNumber = 0xbebc;auto io_1 = connectionManager_1.forwardOpen(si_1, parameters);if (auto ptr = io_1.lock()) {ptr->setDataToSend(std::vector<uint8_t>(4));ptr->setReceiveDataListener([](auto realTimeHeader, auto sequence, auto data) {std::ostringstream ss;ss << "secNum=" << sequence << " data=";for (auto &byte : data) {ss << "[" << std::hex << (int) byte << "]";}Logger(LogLevel::INFO) << "Received: " << ss.str();});ptr->setCloseListener([]() {Logger(LogLevel::INFO) << "Closed";});}//connect twoauto si_2 = std::make_shared<SessionInfo>("192.168.2.88", 0xAF12,timeout,50050);//ConnectionManager connectionManager_2;parameters.connectionPath = {0x20, 0x04,0x24, 0x01, 0x2C, 0x64, 0x2C, 0x6E}; parameters.connectionSerialNumber = 0x275D;//auto io_2 = connectionManager_2.forwardOpen(si_2, parameters);auto io_2 = connectionManager_1.forwardOpen(si_2, parameters);if (auto ptr = io_2.lock()) {ptr->setDataToSend(std::vector<uint8_t>(4));ptr->setReceiveDataListener([](auto realTimeHeader, auto sequence, auto data) {std::ostringstream ss;ss << "secNum=" << sequence << " data=";for (auto &byte : data) {ss << "[" << std::hex << (int) byte << "]";}Logger(LogLevel::INFO) << "Received: " << ss.str();});ptr->setCloseListener([]() {Logger(LogLevel::INFO) << "Closed";});}//handle connectwhile (connectionManager_1.hasOpenConnections()) {connectionManager_1.handleConnections(std::chrono::milliseconds(50));// connectionManager_2.handleConnections(std::chrono::milliseconds(50));}connectionManager_1.forwardClose(si_1, io_1);connectionManager_1.forwardClose(si_2, io_2);。。。。return EXIT_SUCCESS;
}

显示Log如下,能正常维持两个连接

wireshark报文如下:

此系列的b站视频见:

基于EIPScanner的Linux Ethernet/IP的多生产者连接及Tag读写实现分享(一 引言)_哔哩哔哩_bilibili

参考代码见:

咸鱼ID:tb764914262

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/922076.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/922076.shtml
英文地址,请注明出处:http://en.pswp.cn/news/922076.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle APEX 利用卡片实现翻转(方法二)

目录 0. 以 Oracle 的标准示例表 EMP 为例&#xff0c;实现卡片翻转 1. 创建卡片区域 (Cards Region) 2. 定义卡片的 HTML 结构 3. 添加 CSS 实现样式和翻转动画 4. 创建动态操作触发翻转 5. 运行效果 0. 以 Oracle 的标准示例表 EMP 为例&#xff0c;实现卡片翻转 目标如…

低代码拖拽实现与bpmn-js详解

低代码平台中的可视化拖拽功能是其核心魅力所在&#xff0c;它让构建应用变得像搭积木一样直观。下面我将为你梳理其实现原理&#xff0c;并详细介绍 vue-draggable 这个常用工具。 &#x1f9f1; 一、核心架构&#xff1a;三大区域与数据驱动 低代码编辑器界面通常分为三个核心…

【科研绘图系列】R语言绘制模型预测与数据可视化

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍 加载R包 数据下载 函数 导入数据 数据预处理 画图 总结 系统信息 介绍 本文介绍了一种利用R语言进行海洋微生物群落动态分析的方法,该方法通过构建多个统计模型来预测不同环境…

TODO的面试(dw三面、sqb二面、ks二面)

得物的前端三面&#xff08;通常是技术终面&#xff09;会深入考察你的技术深度、项目经验、解决问题的思路以及职业素养。下面我结合搜索结果&#xff0c;为你梳理一份得物前端三面的常问问题及详解&#xff0c;希望能助你一臂之力。 &#x1f9e0; 得物前端三面常问问题及详解…

开发 PHP 扩展新途径 通过 FrankenPHP 用 Go 语言编写 PHP 扩展

通过 FrankenPHP 用 Go 语言编写 PHP 扩展 在 PHPVerse 2025 大会上&#xff08;JetBrains 为纪念 PHP 语言 30 周年而组织的会议&#xff09;&#xff0c;FrankenPHP 开发者 Kvin Dunglas 做了一个开创性的宣布&#xff1a;通过 FrankenPHP&#xff0c;可以使用 Go 语言创建 …

完美解决:应用版本更新,增加字段导致 Redis 旧数据反序列化报错

完美解决&#xff1a;应用版本更新&#xff0c;增加字段导致 Redis 旧数据反序列化报错 前言 在敏捷开发和快速迭代的今天&#xff0c;我们经常需要为现有的业务模型增加新的字段。但一个看似简单的操作&#xff0c;却可能给正在稳定运行的系统埋下“地雷”。 一个典型的场景是…

66-python中的文件操作

1. 文件的编码 UTF-8 GBK GB2312 Big5 GB18030 2. 文件读取 文件操作步骤: 打开文件 读\写文件 关闭文件 open(name,mode,encoding) name:文件名字符串 “D:/haha.txt” mode: 只读、写入、追加 r:以只读方式打开 w: 只用于写 a :用于追加 encoding:编码方式 # -*- coding: utf…

FPGA实例源代码集锦:27个实战项目

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;FPGA是一种可编程逻辑器件&#xff0c;允许用户根据需求配置硬件功能。本压缩包提供27个不同的FPGA应用实例源代码&#xff0c;旨在帮助初学者深入学习FPGA设计&#xff0c;并为专业工程师提供灵感。内容涵盖了…

基于 Vue+Mapbox 的智慧矿山可视化功能的技术拆解

01、项目背景 在全球矿业加速向 “高端化、智能化、绿色化” 转型的浪潮下&#xff0c;传统矿业面临的深地开采难题、效率瓶颈与安全隐患日益凸显。 在矿业转型的迫切需求与政策、技术支撑的背景下依托 GIS 技术&#xff0c;开展了 “中国智矿” GIS 开发项目&#xff0c;旨在…

进程状态(Linux)

进程状态Linux进程状态Linux进程状态进程描述R运行状态S睡眠状态D磁盘休眠状态T停止状态t被追踪状态(调试状态)X死亡状态Z僵死状态其实大致也就可以分为三种运行&#xff0c;阻塞&#xff0c;挂起。运行状态每个cpu里都有一个运行队列&#xff0c;进程在运行队列里&#xff0c;…

物联网领域中PHP框架的最佳选择有哪些?

物联网&#xff08;IoT&#xff09;作为近年来快速发展的技术领域&#xff0c;已经渗透到智能家居、工业自动化、智慧城市等方方面面。作为Web开发中广泛使用的语言&#xff0c;PHP凭借其易学易用、开发效率高和生态丰富的特点&#xff0c;也在物联网领域找到了用武之地。 本文…

java反射(详细教程)

我们平常创建类的实例并调用类中成员需要建立在一个前提下&#xff0c;就是已经知道类名和类中成员的信息&#xff0c;灵活性大大降低。甚至在一些项目中还需要修改源码来满足使用条件&#xff0c;大大降低了操作的灵活性。Java 反射&#xff08;Reflection&#xff09;是 Java…

消息队列-初识kafka

优缺点 消息队列的优点&#xff1a; 实现系统解耦&#xff1a; :::color5 系统解耦解释 有 MQ 时是 “服务 A 发消息到队列&#xff0c;其他服务从队列拿消息&#xff0c;新增服务接队列就行”&#xff1b;无 MQ 时是 “服务 A 直接调其他服务的接口 / 依赖&#xff0c;新增 / …

实践《数字图像处理》之Canny边缘检测、霍夫变换与主动二值化处理在短线段清除应用中的实践

在最近的图像处理项目中&#xff0c;其中一个环节&#xff1a;图片中大量短线&#xff08;不是噪声&#xff09;&#xff0c;需要在下一步处理前进行清除。在确定具体实现时&#xff0c;碰到了Canny边缘检测、霍夫变换与主动二值化处理的辩证使用&#xff0c;相关逻辑从图片灰度…

vue3与ue5通信-工具类

工具 ue5-simple.js /*** UE5 通信工具* 两个核心方法&#xff1a;发送消息和接收消息*/// 确保全局对象存在 if (typeof window ! undefined) {window.ue window.ue || {};window.ue.interface window.ue.interface || {}; }/*** 生成 UUID*/ function generateUUID() {retu…

在kotlin中如何使用像java中的static

在 Kotlin 中&#xff0c;没有直接的 static 关键字&#xff0c;但有几种等效的方式来实现 Java 中静态成员的功能&#xff1a; 1. 伴生对象 (Companion Object) - 最常用 class MyClass {companion object {// 静态常量const val STATIC_CONSTANT "constant value"…

如何在 Spring Boot 中指定不同的配置文件?

介绍 Spring Boot 提供了多种方式来管理和加载配置文件&#xff0c;特别是在多环境配置下&#xff0c;比如开发、测试和生产环境。通过指定不同的配置文件&#xff0c;可以灵活地调整应用程序的行为&#xff0c;以适应不同的需求。本文将介绍在 Spring Boot 中如何指定使用不同…

在centOS源码编译方式安装MySQL5.7

一、前言 在生产环境中部署数据库时&#xff0c;很多人会选择直接使用 yum/apt 包管理器 安装 MySQL&#xff0c;这样简单快速&#xff0c;但缺点是版本受限&#xff0c;灵活性不足。对于需要指定版本、启用特定编译参数或优化的场景&#xff0c;源码编译安装 MySQL 就显得非常…

探讨Hyperband 等主要机器学习调优方法的机制和权衡

本篇文章Master Hyperband — An Efficient Hyperparameter Tuning Method in Machine Learning深入探讨了Hyperband这一高效的超参数调优方法。文章的技术亮点在于其结合了多臂老虎机策略和逐次减半算法&#xff0c;能够在大搜索空间中快速剔除表现不佳的配置&#xff0c;从而…

Mysql:InnoDB 关键特性

目录 一、插入缓冲&#xff08;Change Buffer&#xff09;→ 快递驿站的 “临时存放区” 二、两次写&#xff08;Double Write&#xff09;→ 重要文件的 “备份存档” 三、自适应哈希索引&#xff08;AHI&#xff09;→ 图书馆的 “热门书快捷查找区” 四、异步 IO&#x…