C#使用 ModeBusTCP读取汇川Easy521PLC

news2024/12/28 8:42:25

Modbus TCP是一种基于以太网TCP/IP的Modbus协议变种,它允许Modbus协议在以太网网络上运行,使得设备之间可以通过IP网络交换数据。Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准,广泛应用于工业自动化领域。

 #region  ModBusTCP 地址解释
 /* 00 01->事务标识符,随意指定
  00 00->协议标识符,Modbus TCP协议标识符为0x0000
  00 06->报文长度,表示后面的报文长度为6个字节
  01->广播地址
  03->功能码  0x01   读输出线圈
              0x02    读离散输入
              0x03    读保持寄存器
              0x04    读输入寄存器
              0x05    写单个线圈
              0x06    写单个保持寄存器
              0x0F    写多个线圈
              0x10    写多个保持寄存器
 00 64 读写地址高八位 低八位
 00 01 寄存器数量 
 */

using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace ModbusTcpExample
{
    class Program
    {
        static void Main(string[] args)
        {
            MBTCP mBTCP = new MBTCP();
            mBTCP.MDConnection("192.168.1.2", 502);
            


        }
    }
    class MBTCP
    {
        private bool ConnectionStatus = false;
        NetworkStream stream;

        //ModBusTCP启动
        public void MDConnection(string ipAddress, int port)
        {
            try
            {
                TcpClient client = new TcpClient(ipAddress, port);
                stream = client.GetStream();
                ConnectionStatus = true;
            }
            catch (Exception e)
            {
                Console.WriteLine("TCP connection failed: " + e.Message);
                ConnectionStatus = false;
            }

        }
        //读单个D寄存器
        public int ReadRegister(int address)
        {
            if (ConnectionStatus)
            {
                try
                {
                    #region  ModBusTCP 地址解释
                    /* 00 01->事务标识符,随意指定
                     00 00->协议标识符,Modbus TCP协议标识符为0x0000
                     00 06->报文长度,表示后面的报文长度为6个字节
                     01->广播地址
                     03->功能码  0x01   读输出线圈
                                 0x02    读离散输入
                                 0x03    读保持寄存器
                                 0x04    读输入寄存器
                                 0x05    写单个线圈
                                 0x06    写单个保持寄存器
                                 0x0F    写多个线圈
                                 0x10    写多个保持寄存器
                    00 64 读写地址高八位 低八位
                    00 01 寄存器数量 
                    */
                    #endregion
                    byte H = (byte)((address >> 8) & 0xFF);
                    byte L = (byte)(address & 0xFF);
                    byte[] request = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, H, L, 0x00, 0x01 };

                    stream.WriteAsync(request, 0, request.Length);  // 发送请求报文  
                    byte[] response = new byte[12]; // 根据实际情况调整长度
                    stream.ReadAsync(response, 0, response.Length);
                    int decimalValue = (response[9] << 8) | response[10];
                    return decimalValue;
                }
                catch (Exception e)
                {
                    Console.WriteLine("TCP connection failed: " + e.Message);
                    ConnectionStatus = false;
                    return 888;
                }
            }
            else
            {
                Console.WriteLine("TCP connection failed");
                return 888;
            }


        }
        //写单个D寄存器
        public bool WriteRegister(int address, int Wvalue)
        {
            if (ConnectionStatus)
            {
                try
                {
                    byte H = (byte)((address >> 8) & 0xFF);
                    byte L = (byte)(address & 0xFF);
                    byte WH = (byte)((Wvalue >> 8) & 0xFF);
                    byte WL = (byte)(Wvalue & 0xFF);
                    byte[] request = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, H, L, WH, WL };

                    stream.WriteAsync(request, 0, request.Length);  // 发送请求报文  
                    byte[] response = new byte[12]; // 根据实际情况调整长度
                    return false;
                }
                catch (Exception e)
                {
                    Console.WriteLine("TCP connection failed: " + e.Message);
                    ConnectionStatus = false;
                    return false;
                }
            }
            else
            {
                Console.WriteLine("TCP connection failed");
                return false;
            }
        }

        //读多个M寄存器
        public bool[] ReadMixeds(int address, int quantity)
        {
            bool[] MB = new bool[quantity];
            if (ConnectionStatus)
            {
               
                try
                {
                    byte H = (byte)((address >> 8) & 0xFF);
                    byte L = (byte)(address & 0xFF);
                    byte QH = (byte)((quantity >> 8) & 0xFF);
                    byte QL = (byte)(quantity & 0xFF);
                    byte[] request = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, H, L, QH, QL };

                    stream.WriteAsync(request, 0, request.Length);  // 发送请求报文  
                    byte[] response = new byte[10 + quantity / 8]; // 根据实际情况调整长度
                    stream.ReadAsync(response, 0, response.Length);

                    Console.WriteLine("Received response:");
                    foreach (var b in response)
                    {
                        Console.Write(b.ToString("X2") + " ");
                    }
                    //bool[] MB = new bool[quantity];
                    Console.WriteLine("\nMMMMReceived response:");
                    int MT = 0;
                    for (int n = 0; n < quantity / 8 + 1; n++)
                    {
                        for (int i = 0; i < 8 && MT < quantity; i++)
                        {
                            MB[MT] = ((response[9 + n] >> i) & 0x01) != 0;
                            //int F = MT + address;
                            //Console.WriteLine("M{0}.{1}", F, MB[MT]);
                            MT++;
                        }
                    }
                    return MB;

                }
                catch (Exception e)
                {
                    Console.WriteLine("TCP connection failed: " + e.Message);
                    ConnectionStatus = false;
                    return MB;
                }
            }
            else
            {
                Console.WriteLine("TCP connection failed");
                return MB;
            }
        }
        //写单个M寄存器
        public bool WriteMixed(int address, bool Wvalue)
        {
            if (ConnectionStatus)
            {
                try
                {
                    byte H = (byte)((address >> 8) & 0xFF);
                    byte L = (byte)(address & 0xFF);
                    byte WByte = 0x00;
                    if (Wvalue) { WByte = 0x01; }
                    byte[] request = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, H, L, 0x00, WByte };

                    stream.WriteAsync(request, 0, request.Length);  // 发送请求报文  
                    byte[] response = new byte[12]; // 根据实际情况调整长度
                    return true;
                }
                catch (Exception e)
                {
                    Console.WriteLine("TCP connection failed: " + e.Message);
                    ConnectionStatus = false;
                    return false;
                }
            }
            else
            {
                Console.WriteLine("TCP connection failed");
                return false;
            }
        }


    }



}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【嵌入式】总结指南——Linux下的裸机驱动开发

板型:正点原子 I.MX6UL MINI 屏幕&#xff1a;7寸 1024*600 立意&#xff1a;既是这一段学习的总结&#xff0c;也可作为入门指南的参考&#xff0c;不过并不能作为教程来看&#xff0c;实际学习还是要找相应的视频或文章教程。 一、历程 应该和使用这块板子的大部分人一样&a…

理解List AbstractList ArrayList

ArrayList 实现了 List 接口&#xff0c;继承了 AbstractList 抽象类。 Q: 为什么要ArrayList继承AbstractList&#xff0c;让AbstractList实现List&#xff1f;而不是让ArrayList直接实现List&#xff1f; A: 接口中全都是抽象的方法&#xff0c;而抽象类中可以有抽象方法&am…

【达梦数据库】shell脚本获取集群内确认监视器地址

目录 1、需求2、想法3、实现代码4、检验效果4.1、集群内任意节点使用非dmdba用户执行4.2、集群内任意节点使用dmdba用户执行4.2.1、数据库主备节点执行4.2.1、数据库确认监视器节点执行 4.3、非集群内节点执行 1、需求 有确认监视器的集群&#xff0c;在集群的任何一个集群上执…

Android13 app后台无法启动Abort background activity starts from

总纲 android13 rom 开发总纲说明 目录 1.前言 2.log分析 3.代码查找分析 4.修改方法 5.编译测试 6彩蛋 1.前言 Android13 用户app后台无法启动,提示Abort background activity starts from 10111 2.log分析 08-07 21:37:36.703: W/ActivityTaskManager(440): Back…

Llama3.1大模型

背景 Llama 3.1是一款由Meta&#xff08;前Facebook&#xff09;推出的先进大型语言模型。它在自然语言处理领域具有显著优势&#xff0c;为用户提供高质量的文本生成、理解和推理能力。 Transformer架构 Transformer是一种神经网络架构&#xff0c;可以处理文本、音频、视频和…

无线数传模块有啥特点?

一 、 模块特点  支持 RS485RTU 、RS232、UART 标准协议  AES加密  供电电压DC4.5V——5.5V  工作频段 410~525MHz, 免申请频段  标准配置提供多达 115信道 …

数据结构-递归算法-第四天

参考文献&#xff1a; 华为云 博客园 labuladong 的算法笔记 递归是一种编程技巧&#xff0c;一种解决问题的思维方式&#xff1b;分治算法和动态规划很大程度上是递归思想基础上的&#xff08;虽然动态规划的最终版本大都不是递归了&#xff0c;但解题思想还是离不开递归&…

数学建模之数据分析【七】:对Pandas DataFrame 进行切片

文章目录 一、切片简介二、创建Pandas数据框三、使用iloc进行切片3.1 对行进行切片3.2 对列进行切片3.3 Dataframe选中特定单元格 四、使用loc创建切片4.1 使用Python对Dataframe中的行进行切片4.2 指定单元格 五、在Python中使用布尔条件六、结论 对 Pandas DataFrames 进行切…

水战再起波澜,“怡宝”要下好怎样一盘棋?

不少投资者常把那些刚需性强、永远也不可能淘汰的产业称为“日不落产业”&#xff0c;从细分板块来看&#xff0c;水无疑具有一定代表性。农夫山泉掌门人钟晱晱曾直言&#xff1a;“我选择了一个日不落的产业&#xff0c;你永远要喝水&#xff0c;不可能不喝水。” 多年下来&a…

Python | Leetcode Python题解之第367题有效的完全平方数

题目&#xff1a; 题解&#xff1a; class Solution:def isPerfectSquare(self, num: int) -> bool:x0 numwhile True:x1 (x0 num / x0) / 2if x0 - x1 < 1e-6:breakx0 x1x0 int(x0)return x0 * x0 num

SpringBoot集成kafka-获取生产者发送的消息(阻塞式和非阻塞式获取)

说明 CompletableFuture对象需要的SpringBoot版本为3.X.X以上&#xff0c;需要的kafka依赖版本为3.X.X以上&#xff0c;需要的jdk版本17以上。 1、阻塞式&#xff08;等待式&#xff09;获取生产者发送的消息 生产者&#xff1a; package com.power.producer;import org.ap…

<数据集>车内视角行人识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;6470张 标注数量(xml文件个数)&#xff1a;6470 标注数量(txt文件个数)&#xff1a;6470 标注类别数&#xff1a;1 标注类别名称&#xff1a;[pedestrian] 序号类别名称图片数框数1pedestrian647029587 使用标注…

c++链表(list)

前言 链表作为一个常见的数据结构&#xff0c;在高频插入删除的场景下有独特的优势&#xff0c;在内存的使用上也极少有浪费可以按需申请。今天我们就来简单的学习一下这种数据结构&#xff0c;链表也有很多不同的实现&#xff0c;我们这里和标准库保持一致&#xff0c;实现带…

UDP通信函数补充 | TCP

UDP流程补充&#xff1a; recvfrom() 这是一个系统调用&#xff0c;用于从套接字接收数据的函数。该函数通常与无连接的数据报服务&#xff08;如 UDP&#xff09;一起使用&#xff0c;但也可以与其他类型的套接字使用。 函数原型为&#xff1a; ssize_t recvfrom(int sock…

使用Node-RED实现和部署物联网入侵检测的机器学习管道

整理自 《Implementing and Deploying an ML Pipeline for IoT Intrusion Detection with Node-RED》&#xff0c;由 Yimin Zhang 等人撰写&#xff0c;发表于 2023 年 CPS-IoT Week Workshops。以下是根据提供的 PDF 内容整理的论文的详细主要内容&#xff1a; 摘要 (Abstra…

Linux入门——09 共享内存

1.共享内存原理 OS内的每个进程都会有自己的内核结构&#xff08;task_struct&#xff09;和虚拟地址空间,通过页表与物理内存进程映射。 如果让两个不同的进程共享内存&#xff0c;首先就是在内存中申请一块空间&#xff08;共享内存&#xff09;&#xff0c; 然后将建立好…

Unity XR Interaction Toolkit 踩坑记录

1&#xff1a;按下 grap/select 键 物品直接飞到手上 2 按下 grap/select 键 物品一点点的想自己移动

《机器学习》—— AUC评估指标

文章目录 一、什么是AUC&#xff1f;1、什么是ROC曲线&#xff1f;2、ROC曲线的绘制 二、如何计算AUC的值三、代码实现AUC值的计算四、AUC的优缺点 一、什么是AUC&#xff1f; 机器学习中的AUC&#xff08;Area Under the Curve&#xff09;是一个重要的评估指标&#xff0c;特…

走进虚拟机逃逸技术之VMware Escape漏洞CVE-2023-20872复现

走进虚拟机逃逸技术之VMware Escape漏洞CVE-2023-20872复现 技术分享 技术分享 起初&#xff0c;为了学习虚拟机逃逸相关技术&#xff0c;也为了搞懂硬件虚拟化。于是请教了某巨佬后告诉我一本书&#xff0c;看完之后为了验证我理解到的硬件虚拟化及虚拟化逃逸原理是否正确&am…

图书管理系统详细设计

需求概述 按照需求分析文档中的规格要求&#xff0c;使用条形码扫描器进书、借书、还书&#xff0c;使得信息传递准确、流畅。同时&#xff0c;系统最大限度地实现易安装&#xff0c;易维护性&#xff0c;易操作性&#xff0c;运行稳定&#xff0c;安全可靠。 软件结构 系统由…