当前位置: 首页 > news >正文

C# OMRON PLC FINS TCP协议简单测试

       FINS(factory interface network service)通信协议是欧姆龙公司开发的用于工业自动化控制网络的指令/响应系统。运用 FINS指令可实现各种网络间的无缝通信,包括用于信息网络的 Etherne(以太网),用于控制网络的Controller Link和SYSMAC LINK。

      ORMON PLC的FINS协议看起来非常简单,但其中数据内容涉及高低位转换、16进制整数、字符串,有时需要自己写代码来进行通讯处理。

1、PLC的数据类型

数据类型

说明

布尔型

单个位

短整型

有符号 16 位值
位 0 是低位
位 14 是高位
位 15 是符号位

无符号 16 位值
位 0 是低位
位 15 是高位

长整型

有符号 32 位值
位 0 是低位
位 30 是高位
位 31 是符号位

双字型

无符号 32 位值
位 0 是低位
位 31 是高位

浮点型

32 位实数

BCD

两个字节封装的 BCD
值的范围是 0 至 9999。对于超出此范围的值,未定义行为。

LBCD

四个字节封装的 BCD
值的范围是 0 至 99999999。对于超出此范围的值,未定义行为。

字符串

空终止 ASCII 字符串。
支持多达 512 个字符的字符串长度,并支持择由高到低的字节排序、由低到高的字节排序、仅高位字节和仅低位字节。

短整型、长整型、双字等也可以是BCD码,需要根据PLC的程序设定进行解析。

1、FINS帧定义

FINS/UDP运用的是一种嵌套格式数据包,即Ethernet报头、IP报头、 UDP报头和FINS帧。一个UDP数据段(FINS 帧)超过1472字节将被分成若干个数据包来传送。分开的UDP数据将在UDP/IP协议层自动组合。通常不须要关注运用 层的数据分段,但是在一个多层 IP网络中1427字节的UDP包可能无法 发送。在这种系统中就须要运用 FINS/TCP方式。

ICF为信息控制域,用于标明指令和响应;

RSV为系统保留;

GCT为网关允许数目;

DNA为目的网络号;

DA1为目的节点号;

DA2为目的单元号;

SNA为源网络号;

SA1为源节点号;

SA2为源单元号;

SID为服务和响应的标识号,可任意配置,指令和响应对应相同;

MRC和SRC分别为 FINS指令的主指令和从指令;

参数/数据域,用于标明所操作的数据地址、范围等,在响应帧中前两个字节MRES和SRES构成响应码,用来诊断不正确信息

填充示例:

2、PLC连接、数据读取和解析示例

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace PascalMing
{public class Tcp_FINS_PascalMingTest{TcpClient _tcpClient = new TcpClient();int _port;string _host;byte plcAddr = 0;byte pcAddr = 0;int headDm = 30;const int readDMStart = 5000;const int readDMCount = 60;EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);CancellationTokenSource cts = new CancellationTokenSource();//返回:46 49 4E 53 00 00 00 10 00 00 00 01 00 00 00 00 00 00 00 F0 00 00 00 9B //PC,PLC IP最后一位(4个字节一组)//不同网络配置返回值有区别,需要根据实际进行替换byte[] cmdConnect = { 0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };//最后一位:PC端IP最后一位//读D5000,连续100个byte[] cmdReadD5000 = { 0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x9B, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x01, 0x01, 0x82, (byte)(readDMStart / 0x100), (byte)(readDMStart % 0x100), 0x00, (byte)(readDMCount/0x100), (byte)(readDMCount%0x100) };public bool ConnectDevice(string ip, int port){_host = ip;_port = port;try{_tcpClient = new TcpClient();_tcpClient.Connect(_host, _port);//_tcpClient.ReceiveTimeout = 5_000;_tcpClient.Client.Send(cmdConnect);byte[] rx = new byte[100];for (int k = 0; k < 100; k++){if (_tcpClient.Available >= 24)break;Thread.Sleep(50);}int ret = _tcpClient.Client.Receive(rx);Console.WriteLine($"connect recv Len:{ret},{rx[0]},{rx[1]},{rx[2]},{rx[3]},{rx[7]}");if (ret == 24 && rx[0] == 0x46 && rx[1] == 0x49 && rx[2] == 0x4E && rx[3] == 0x53){pcAddr = rx[19];plcAddr = rx[23];cmdReadD5000[20] = plcAddr;cmdReadD5000[23] = pcAddr;Console.WriteLine("connect ok");Task.Run(() =>{myTaskExecute(cts.Token);});                return true;}Console.WriteLine("connect fail,check fail");return false;}catch (Exception ex){Console.WriteLine("connect fail,ex:"+ex.Message);return false;}}int count = 0;async Task myTaskExecute(CancellationToken token){Stopwatch sw = Stopwatch.StartNew();int timeOutMs = 30_000;List<byte[]> cmdIndex = new List<byte[]>();ushort txCount = 0;try{while (!token.IsCancellationRequested){int ret = -1;byte[] rx = new byte[4096];Console.WriteLine($"{DateTime.Now} send read");_tcpClient.Client.Send(cmdReadD5000);for(int k = 0; k < 200; k ++){if (_tcpClient.Available >= headDm+ readDMCount*2)break;await Task.Delay(20, token);}Console.WriteLine($"{DateTime.Now} send Available:{_tcpClient.Available}");if (_tcpClient.Available > 0){sw.Restart();ret = _tcpClient.Client.Receive(rx);try{Console.WriteLine($"{DateTime.Now} DataReceived len:{ret},data:{rx[7]},{rx[19]},{rx[23]}");if (ret >= 16 && rx[0] == 0x46 && rx[1] == 0x49 && rx[2] == 0x4E && rx[3] == 0x53){//数据解析根据PLC定义进行,包括数据值。此处使用比较简单的测试方案Console.WriteLine($"D{5000}:{GetInt16(rx,0)}");Console.WriteLine($"D{5001}:{GetInt16(rx,1)}");Console.WriteLine($"D{5010}:{GetInt32_2(rx, 10)}");Console.WriteLine($"D{5012}:{GetInt32_2(rx, 12)}");Console.WriteLine($"D{5014}:{GetInt16(rx, 14)}");Console.WriteLine($"D{5015}:{GetString(rx, 15,40)}");Console.WriteLine();                            }}catch (Exception ex){Console.WriteLine("DataReceived parse err:" + ex.Message);}}await Task.Delay(2000, token);}}catch (Exception ex){Console.WriteLine("DataReceived ex:" + ex.Message);}Console.WriteLine("DataReceived leave");}public int GetInt16(byte[]data,int offset){string sV = $"{data[headDm+ offset*2]:X2}{data[headDm+offset*2+1]:X2}";int iV = int.Parse(sV);return iV;}public int GetInt32(byte[] data, int offset){string sV = $"{data[headDm + offset*2]:X2}{data[headDm + offset*2 + 1]:X2}{data[headDm + offset*2 + 2]:X2}{data[headDm + offset*2 + 3]:X2}";int iV = int.Parse(sV);return iV;}public int GetInt32_2(byte[] data, int offset){string sV = $"{data[headDm + offset * 2+2]:X2}{data[headDm + offset * 2 + 3]:X2}{data[headDm + offset * 2 + 0]:X2}{data[headDm + offset * 2 + 1]:X2}";int iV = int.Parse(sV);return iV;}public string GetString(byte[] data, int offset,int len){int headDm = 30;StringBuilder sb = new StringBuilder();for(int k = 0; k < len; k ++){if (data[headDm + offset*2 + k] == 0)break;sb.Append($"{(char)data[headDm+offset*2+k]}");}return sb.ToString();}public void DisconnectDevice(){_tcpClient?.Close();}}
}

验证:

Tcp_FINS_PascalMingTest tcp_fins = new Tcp_FINS_PascalMingTest();
void Do_Tcp_FINS()
{tcp_FINS_Yinlun.ConnectDevice("192.168.0.1", 9600);
}

3、参考资料

FinsTCP协议报文详细分析 - 知乎
基于FINS协议的OMRON PLC与上位机以太网通信的实现_omron nx fins上位机配置-CSDN博客
 

相关文章:

C# OMRON PLC FINS TCP协议简单测试

FINS(factory interface network service)通信协议是欧姆龙公司开发的用于工业自动化控制网络的指令&#xff0f;响应系统。运用 FINS指令可实现各种网络间的无缝通信&#xff0c;包括用于信息网络的 Etherne(以太网)&#xff0c;用于控制网络的Controller Link和SYSMAC LINK。…...

MQTT在linux下服务端和客户端的应用

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级、开放标准的消息传输协议&#xff0c;设计用于受限设备和低带宽、不稳定网络的通信。 MQTT的一些关键特点和概念&#xff1a; 发布/订阅模型&#xff1a; MQTT采用发布/订阅&#xff08;Publ…...

韦达定理用处多

文章目录 前言一、一元二次方程中根和系数之间的关系二、韦达定理的数学推导和作用1. 韦达定理的数学推导2. 韦达定理的作用 三、韦达定理的应用举例1. 解题示例12. 解题示例23. 解题示例34. 解题示例45. 解题示例56. 解题示例67. 解题示例7 总结 前言 韦达定理说明了一元n次方…...

Kotlin-类

构造函数 Java final File file new File("file.txt");Kotlin val file File("file.txt")类 Java public final class User { }Kotlin class User公开类 Java public class User { }Kotlin open class User属性类 Java final class User {pri…...

redis基本数据结构介绍

Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的高性能键值对数据库&#xff0c;它支持多种数据结构&#xff0c;包括字符串、哈希、列表、集合、有序集合等。这些数据结构为开发者提供了丰富的数据操作方式&#xff0c;使得Redis在缓存、消息队列、排行榜…...

云数据库RDS云监控

1. 什么是云数据库RDS&#xff1f;它有哪些特点&#xff1f; 云数据库RDS是一种在线关系型数据库服务&#xff0c;它具备的特点包括&#xff1a; 安全可靠&#xff1a;提供了容灾、备份、恢复等高可用性功能&#xff0c;确保数据的安全与可靠。弹性伸缩&#xff1a;用户可以根…...

全自动网页生成系统重构版源码

全自动网页生成系统重构版源码分享&#xff0c;所有模板经过精心审核与修改&#xff0c;完美兼容小屏手机大屏手机&#xff0c;以及各种平板端、电脑端和360浏览器、谷歌浏览器、火狐浏览器等等各大浏览器显示。 为用户使用方便考虑&#xff0c;全自动网页制作系统无需繁琐的注…...

Leetcode—33. 搜索旋转排序数组【中等】

2024每日刷题&#xff08;110&#xff09; Leetcode—33. 搜索旋转排序数组 实现代码 class Solution { public:int search(vector<int>& nums, int target) {int n nums.size();int l 0, r n - 1;while(l < r) {int m l (r - l) / 2;if(nums[m] target) …...

vulhub中Apache APISIX Dashboard API权限绕过导致RCE(CVE-2021-45232)

Apache APISIX是一个动态、实时、高性能API网关&#xff0c;而Apache APISIX Dashboard是一个配套的前端面板。 Apache APISIX Dashboard 2.10.1版本前存在两个API/apisix/admin/migrate/export和/apisix/admin/migrate/import&#xff0c;他们没有经过droplet框架的权限验证&…...

JavaSE习题 使用函数求最大值、求最大值方法的重载和求和方法的重载

目录 1 使用函数求最大值2 求最大值方法的重载3 求和方法的重载 1 使用函数求最大值 使用函数求最大值&#xff1a;创建方法求两个数的最大值max2&#xff0c;随后再写一个求3个数的最大值的函数max3。 ​要求&#xff1a; 在max3这个函数中&#xff0c;调用max2函数&#xff…...

英码科技携手昇腾共建算力底座:推出EA500I超强AI处理能力边缘计算盒子!

在数字经济浪潮中&#xff0c;算力已成为不可或缺的驱动力&#xff0c;为各行各业的数字化转型提供了强大的推动力。面对多元化和供需不平衡的挑战&#xff0c;需要实现从理论架构到软硬件实现的质的飞跃&#xff0c;以满足持续增长的算力需求&#xff0c;华为昇腾在这一方面展…...

蓝桥杯每日一题-----数位dp练习

题目 链接 参考代码 写了两个&#xff0c;一个是很久以前写的&#xff0c;一个是最近刚写的&#xff0c;很久以前写的时候还不会数位dp所以写了比较详细的注释&#xff0c;这两个代码主要是设置了不同的记忆数组&#xff0c;通过这两个代码可以理解记忆数组设置的灵活性。 im…...

JS(react)图片压缩+图片上传

上传dome var fileNodeTakeStock: any createRef();<inputref{fileNodeTakeStock}onChange{showPictureTakeStock}style{{ display: "none" }}id"fileInpBtn"type"file"accept"image/*" //限制上传格式multiple{false}capture&qu…...

WPF DispatcherTimer用法

System.Windows.Threading.DispatcherTimer 类主要用于WPF应用程序中进行周期性任务调度&#xff0c;并且保证这些任务在UI线程上执行。 这对于需要更新界面或与UI元素交互的定时操作非常有用&#xff0c;因为WPF的所有UI操作都必须在主线程&#xff08;即Dispatcher线程&…...

【网络安全实验】snort实现高级IDS

注&#xff1a;本实验分别使用kali和CentOS6.8进行测试&#xff0c;可惜的是使用kali进行实验过程中遇到了困难&#xff0c;未能完成完整实验&#xff0c;而使用CentOS6.8成功完成了完整实验。 实验中用到的软件&#xff1a; https://download.csdn.net/download/weixin_5255…...

19.HarmonyOS App(JAVA)依赖布局DependentLayout使用方法

layout/ability_main.xml 显示位置不对&#xff1a;检查布局文件ohos:lef_of "id:tuzi",比如显示在兔子的左侧&#xff0c;这里就会显示不对。 需要id前没有$符号。改为&#xff1a; ohos:lef_of "$id:tuzi" <?xml version"1.0" encodi…...

玩家笔记:幻兽帕鲁搭建服务器开服教程

玩转幻兽帕鲁服务器&#xff0c;阿里云推出新手0基础一键部署幻兽帕鲁服务器教程&#xff0c;傻瓜式一键部署&#xff0c;3分钟即可成功创建一台Palworld专属服务器&#xff0c;成本仅需26元&#xff0c;阿里云服务器网aliyunfuwuqi.com分享2024年新版基于阿里云搭建幻兽帕鲁服…...

Liunx基本指令

目录 1、ls 列出当前路径下的文件 2、pwd 打印当前工作目录 (print working directory) 3、cd 进入路径 4、mkdir 创建文件夹(make dirctory) 5、touch 创建文件 6、cp 复制(copy) 7、mv 移动/剪切、重命名 8、rm 删除 (remover) 9、vim 文本编辑器 10、cat 打开文件…...

面试题:Redis 分布式锁存在什么问题 ?如何解决 ?

文章目录 如何实现分布式锁2. Redis 分布式锁存在什么问题2.1 解决死锁问题2.2 解决锁误删问题 如何实现分布式锁 Redis 天生就可以作为一个分布式系统来使用&#xff0c;所以它实现的锁都是分布式锁。 Redis 可以通过 setnx&#xff08;set if not exists&#xff09;命令实…...

Container 命令ctr、crictl 命令

1、 Containerd和Docker的架构区别 Docker vs. Containerd&#xff1a; 2、ctr & crictl的区别 ctr是containerd的一个客户端工具 crictl 是 CRI 兼容的容器运行时命令行接口&#xff0c;可以使用它来检查和调试 Kubernetes 节点上的容器运行时和应用程序 crictl 则直接对…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...

深度解析云存储:概念、架构与应用实践

在数据爆炸式增长的时代&#xff0c;传统本地存储因容量限制、管理复杂等问题&#xff0c;已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性&#xff0c;成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理&#xff0c;云存储正重塑数据存储与…...

Qt的学习(二)

1. 创建Hello Word 两种方式&#xff0c;实现helloworld&#xff1a; 1.通过图形化的方式&#xff0c;在界面上创建出一个控件&#xff0c;显示helloworld 2.通过纯代码的方式&#xff0c;通过编写代码&#xff0c;在界面上创建控件&#xff0c; 显示hello world&#xff1b; …...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统

核心速览 研究背景 ​​研究问题​​&#xff1a;这篇文章要解决的问题是当前大型语言模型&#xff08;LLMs&#xff09;在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色&#xff0c;但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成&#xff08;RA…...