NModbus4介绍
NModbus4是一个用于Modbus通信的开源库,它提供了一套简单易用的API来实现Modbus协议的通信。Modbus是一种应用层协议,主要用于工业自动化领域的电子设备之间的通信。它支持多种通信方式,包括RTU(二进制模式)、ASCII和TCP/IP。
演示如何使用NModbus4库来创建一个Modbus Master,连接到一个Modbus Slave,并读取保持寄存器的值:
using System;
using NModbus;
class ModbusDemo
{
static void Main(string[] args)
{
// 创建一个Modbus Master,假设使用TCP/IP通信
var master = new ModbusSerialMaster("localhost", 502);
// 连接到Modbus Slave,Slave的地址是1
master.Connect();
Console.WriteLine("Connected to Modbus Slave at address 1.");
// 读取保持寄存器的值,从地址0开始,读取10个寄存器
int[] registers = master.ReadHoldingRegisters(1, 0, 10);
Console.WriteLine("Read 10 holding registers:");
foreach (var register in registers)
{
Console.WriteLine(register);
}
// 断开连接
master.Disconnect();
Console.WriteLine("Disconnected from Modbus Slave.");
}
}
Rtu
// RTU
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
ModbusMaster master = ModbusSerialMaster.CreateRtu(serialPort);
起始地址 “40001” "I0.0" "DB1.DBW100"
ushort[] values = master.ReadHoldingRegisters(1, 0, 2);
ModbusRTU 读保持型寄存器报文处理
if (flag == 1)
{
List<byte> bytes = new List<byte>();
bytes.Add(0x01);// 从站地址
bytes.Add(0x03);// 功能码:读保持型寄存器
ushort addr = 4;
// BitConverter /256 %256
bytes.Add((byte)(addr / 256));// BitConverter.GetBytes(addr)[1];
bytes.Add((byte)(addr % 256));// BitConverter.GetBytes(addr)[0];
ushort len = 2;//寄存器数量
bytes.Add((byte)(len / 256));
bytes.Add((byte)(len % 256));
bytes = CRC16(bytes);// Modbus
// 发送 串口
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
// 协议的发送间隔时间 传输时间
// 发送
serialPort.Write(bytes.ToArray(), 0, bytes.Count);// 事件 C#处理从站逻辑使用 延迟
// 响应
byte[] data = new byte[len * 2 + 5];// 正常 异常
serialPort.Read(data, 0, data.Length);// 串口Read不卡线程 网口Scoket卡线程 事件
// 自动匹配字节 类型
for (int i = 3; i < data.Length - 2; i += 4)
{
// 封装库的需要注意字节序
byte[] vb = new byte[4]
{
data[i + 2],//D
data[i+3 ],//C
data[i ],//B
data[i+1]//A
};
float v = BitConverter.ToSingle(vb);
Console.WriteLine(v);
}
// short 123
// 64+32+16+8+2+1
// 0111 1011 0000 0000
}
static List<byte> CRC16(List<byte> value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
if (value == null || !value.Any())
throw new ArgumentException("");
//运算
ushort crc = crcInit;
for (int i = 0; i < value.Count; i++)
{
crc = (ushort)(crc ^ (value[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //高位置
byte lo = (byte)(crc & 0x00FF); //低位置
List<byte> buffer = new List<byte>();
buffer.AddRange(value);
buffer.Add(lo);
buffer.Add(hi);
return buffer;
}
ModbusRTU 写保持型寄存器报文处理
if (flag == 2)
{
List<byte> bytes = new List<byte>();
bytes.Add(0x01);// 从站地址
bytes.Add(0x06);// 功能码:读保持型寄存器
ushort addr = 3;
// BitConverter /256 %256
bytes.Add((byte)(addr / 256));// BitConverter.GetBytes(addr)[1];
bytes.Add((byte)(addr % 256));// BitConverter.GetBytes(addr)[0];
ushort value = 100;//寄存器数量
bytes.Add((byte)(value / 256));// 高位
bytes.Add((byte)(value % 256));// 低位
bytes = CRC16(bytes);// Modbus
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
serialPort.Write(bytes.ToArray(), 0, bytes.Count);
}
static List<byte> CRC16(List<byte> value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
if (value == null || !value.Any())
throw new ArgumentException("");
//运算
ushort crc = crcInit;
for (int i = 0; i < value.Count; i++)
{
crc = (ushort)(crc ^ (value[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //高位置
byte lo = (byte)(crc & 0x00FF); //低位置
List<byte> buffer = new List<byte>();
buffer.AddRange(value);
buffer.Add(lo);
buffer.Add(hi);
return buffer;
}