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("连接已关闭");
            }
        }

        
    }
}

要安装这个包

相关推荐
用户788477316348 小时前
用 C# 把每周 6 小时的 PDF 录入干到 20 分钟:一份可复制的桌面 OCR 方案
c#
csdn_aspnet10 小时前
C# .NetCore Swagger ISchemaFilter 处理枚举、特殊类型
c#·.netcore·swagger
滴滴答答哒10 小时前
C# 技巧:优雅实现对象的“局部更新”与“字段合并”
开发语言·c#
code_long15 小时前
.net core 连接打印机 使用zpl指令打印机,并且位图本地渲染zpl指令
c#·.netcore·位图·打印机·模板编辑·模板预览
csdn_aspnet17 小时前
C# .NetCore Swagger ISchemaFilter Long 转 String 防精度丢失
c#·.netcore·swagger
下页、再停留1 天前
【C#桌面客户端系列学习-11】将SQLite数据库打包到exe里
数据库·c#·visual studio
下页、再停留1 天前
【C#桌面客户端系列学习-12】封装SQLite数据库基础操作工具类(CURD)
数据库·c#·visual studio
dwm888888882 天前
c# 创建使用本地NuGet包
开发语言·c#
进击的大海贼2 天前
【无标题】
c#