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("连接已关闭");
}
}
}
}
要安装这个包
