Modbus TCP

csharp 复制代码
using EasyModbus;
using System;
using System.Net;
using System.Threading;
/**
                0x01 读取线圈的操作,
                0x02 读取离散的操作,
                0x03 读取寄存器的值,
                0x05 写一个线圈操作,
                0x06 写一个寄存器值,
                0x0F 批量写线圈操作,
                0x10 批量写寄存器值,
                // 1. 保持寄存器 (功能码03读、06写单个、16写多个) → 最常用 ✅
                // 类型:ushort[] ,取值范围 0~65535 ,地址 0~n
                modbusServer.HoldingRegisters[0] = 100; // 赋值
                ushort val = modbusServer.HoldingRegisters[0]; // 取值

                // 2. 线圈寄存器 (功能码01读、05写单个、15写多个) → 开关量 ✅
                // 类型:bool[] ,true=通/1 ,false=断/0 ,地址 0~n
                modbusServer.Coils[1] = true; // 赋值
                bool coilVal = modbusServer.Coils[1]; // 取值

                // 3. 输入寄存器 (功能码04读) → 只读,通常存传感器输入数据
                modbusServer.InputRegisters[5] = 250;

                // 4. 离散输入寄存器 (功能码02读) → 只读,通常存开关量输入数据
                modbusServer.DiscreteInputs[3] = true;

                角色分为主站(Mater)、从站(Slave);
                数据类型分为线圈(Coil)、离散输入(Input)、
                保持寄存器(HoldingRegister)、输入寄存器(InputRegister)
                线圈(Coils):1 位布尔值,可读写。
                离散输入(Discrete Inputs):1 位布尔值,只读。
                保持寄存器(Holding Registers):16 位寄存器,可读写。
                输入寄存器(Input Registers):16 位寄存器,只读。

                每个数据类型都有它自己的地址范围:
                线圈地址范围:000001~065536
                离散量输入地址范围:100001~165536
                输入寄存器地址范围:300001~365536
                保持寄存器地址范围:400001~465536

                但别被这些数字吓到,实际应用中,我们通常只用到10000以内的地址。比如:
                线圈地址范围:00001~09999
                离散量输入地址范围:10001~19999
                输入寄存器地址范围:30001~39999
                保持寄存器地址范围:40001~49999
                如何解读Modbus地址? 🔍

                当你看到地址40001或30004时,怎么判断它是什么类型的寄存器呢?其实很简单:
                40001 / 400001:最前面的4表明它是一个保持寄存器,后面的0001或00001都指第一个保持存储器,地址是0。
                30004:表明它是输入寄存器,地址是3。
                10008:表明它是离散量输入,地址是7。
                */
namespace ConsoleApp12
{
    /// <summary>
    /// EasyModbus 客户端
    /// string clientIp = client.Client.RemoteEndPoint.ToString().Split(':')[0];
    /// </summary>
    internal class Program
    {
        static void Main(string[] args)
        {
            ModbusClient modbusClient = new ModbusClient("127.0.0.1", 502);

            try
            {
                Console.WriteLine("正在连接Modbus服务器...");
                modbusClient.Connect();

                // 读取保持寄存器
                Console.WriteLine("读取保持寄存器...");


                int[] registers = modbusClient.ReadHoldingRegisters(0, 5);
                for (int i = 0; i < registers.Length; i++)
                {
                    Console.WriteLine($"寄存器 {i}: {registers[i]}");
                }

                // 写入寄存器
                Console.WriteLine("写入寄存器...");
                int ii = 1;
                /*while (true)
                {
                    ii++;
                    modbusClient.WriteSingleRegister(1, ii);
                    Thread.Sleep(500);
                }*/
                while (true)
                {
                    registers = modbusClient.ReadHoldingRegisters(0, 5);
                    for (int i = 0; i < registers.Length; i++)
                    {
                        Console.WriteLine($"寄存器 {i}: {registers[i]}");
                    }
                    Thread.Sleep(1000);
                }

                

                // 1、线圈------读写,布尔类型,主要用于设置某个值。
                // 读取多个输出线圈
                // 读取线圈状态 (功能码01)
                // 从地址0开始读取5个线圈
                // bool[] coilStatus = modbusClient.ReadCoils(0, 5); 

                // 写入单个线圈 (功能码05)
                // 向地址0写入true
                //modbusClient.WriteSingleCoil(0, true); 

                //2、离散量输入------只读,布尔类型,获取某个IO状态(1bit)。


                //3、输入寄存器------只读,无符号2字节整型,获取某个16bit数据的值。
                // 读取输入寄存器
                //int[] inputRegisters = modbusClient.ReadInputRegisters(0, 5);

                //4、保持寄存器------读写,无符号2字节整型,设置某个16bit数据的值。
                // 读取保持寄存器 (功能码03)
                // 从地址0开始读取10个寄存器
                //int[] holdingRegisters = modbusClient.ReadHoldingRegisters(0, 10); 

                // 写入单个保持寄存器
                //modbusClient.WriteSingleRegister(0, 1234);

                // 写入多个保持寄存器
                // 写入多个寄存器 (功能码16)
                //int[] valuesToWrite = { 100, 200, 300 };
                // 从地址0开始写入
                //modbusClient.WriteMultipleRegisters(0, valuesToWrite); 

                // 验证写入
                //int value = modbusClient.ReadHoldingRegisters(10, 1)[0];
                //Console.WriteLine($"寄存器10的新值: {value}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"错误: {ex.Message}");
            }
            finally
            {
                modbusClient.Disconnect();
                Console.WriteLine("连接已关闭");
            }
        }

        
    }
}

要安装这个包

相关推荐
程序员老乔3 小时前
Java 新纪元 — JDK 25 + Spring Boot 4 全栈实战(二):Valhalla落地,值类型如何让电商DTO内存占用暴跌
java·spring boot·c#
祝大家百事可乐3 小时前
嵌入式——02 数据结构
c++·c#·硬件工程
我是唐青枫4 小时前
深入理解 C#.NET TaskScheduler:为什么大量使用 Work-Stealing
c#·.net
疆鸿智能研发小助手5 小时前
疆鸿智能ETHERNET IP转MODBUDS TCP晶圆不再破防!
编码器·modbus tcp·工业自动化·ethernet ip·工业通讯·协议转换网关·阀岛
唯情于酒6 小时前
net core web api 使用log4net
c#·.net core
SunnyDays10116 小时前
C# 实战:快速查找并高亮 Word 文档中的文字(普通查找 + 正则表达式)
开发语言·c#
人工智能AI技术6 小时前
Qwen3.5-Plus登顶|C#集成通义千问,高并发服务实战优化
人工智能·c#
SunnyDays10118 小时前
如何使用 C# 在 Word 文档中插入超链接 (含文本与图片链接)
开发语言·c#
一念春风8 小时前
证件照制作工具(WPF C#)
c#·wpf
似水明俊德16 小时前
02-C#.Net-反射-面试题
开发语言·面试·职场和发展·c#·.net