一、什么是ModBus通讯协议
Modbus协议是应用于电子控制器上的一种通用语言,此协议支持传统的RS-232、RS-422、RS-485和以太网设备。
ModBus功能码
01 | READ COIL STATUS |
02 | READ INPUT STATUS |
03 | READ HOLDING REGISTER |
04 | READ INPUT REGISTER |
05 | WRITE SINGLE COIL |
06 | WRITE SINGLE REGISTER |
15 | WRITE MULTIPLE COIL |
16 | WRITE MULTIPLE REGISTER |
二、ModBus通讯协议的.Net实现
推荐一个github的开源实现类库:NModBus,github地址:https://github.com/NModbus/NModbus。针对TCP、UDP、RTU等的ModBus通讯方式都有实现。
读写方法:
方法名 | 作用 | 所需参数 | 返回值 | 对应功能码 |
ReadCoils | 读取DO的状态 | 从站地址(8位) byte slaveAddress 起始地址(16位) ushort startAddress 读取数量(16位) ushort numberOfPoints | bool[] | 01 |
ReadInputs | 读取DI的状态 | 从站地址(8位) byte slaveAddress 起始地址(16位) ushort startAddress 读取数量(16位) ushort numberOfPoints | bool[] | 02 |
ReadHoldingRegisters | 读取AO的值 | 从站地址(8位) byte slaveAddress 起始地址(16位) ushort startAddress 读取数量(16位) ushort numberOfPoints | ushort[] | 03 |
ReadInputRegisters | 读取AI的值 | 从站地址(8 位) byte slaveAddress 起始地址(16位) ushort startAddress 读取数量(16位) ushort numberOfPoints | ushort[] | 04 |
WriteSingleCoil | 写入值到DO | 从站地址(8位) byte slaveAddress 线圈地址(16位) ushort coilAddress 写入值(布尔型) bool value | 无返回值 | 05 |
WriteSingleRegister | 写入值到AO | 从站地址(8位) byte slaveAddress 寄存器地址(16位) ushort registerAddress 写入值(16位) ushort value | 无返回值 | 06 |
WriteMultipleCoils | 写多线圈寄存器 | 从站地址(8位) byte slaveAddress 起始地址(16位) ushort startAddress 写入值(布尔型数组) bool[] data | 无返回值 | 15 |
WriteMultipleRegisters | 写多个保持寄存器 | 从站地址(8位) byte slaveAddress 起始地址(16位) ushort startAddress, 寄存器值(16位整型数组) ushort[] data | 无返回值 | 16 |
ReadWriteMultipleRegisters | 读写多个保持寄存器 | 从站地址(8位) byte slaveAddress 读起始地址(16位) ushort startReadAddress 读取数量(16位) ushort numberOfPointsToRead, 写入起始地址(16位) ushort startWriteAddress, 写入值(16位整型数组) ushort[] writeData | ushort[] | 23 |
每个方法都有各自的异步方法实现。
三、NModBus Master 示例
private static void Main(string[] args)
{
try
{
ModbusSerialRtuMasterWriteRegisters();
ModbusTcpMasterReadInputs();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
/// <summary>
/// Simple Modbus serial RTU master write holding registers example.
/// </summary>
public static void ModbusSerialRtuMasterWriteRegisters()
{
using (SerialPort port = new SerialPort("COM3"))
{
// configure serial port
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open();
var factory = new ModbusFactory();
IModbusMaster master = factory.CreateRtuMaster(port);
byte slaveId = 1;
ushort startAddress = 100;
ushort[] registers = new ushort[] { 1, 2, 3 };
// write three registers
master.WriteMultipleRegisters(slaveId, startAddress, registers);
}
}
/// <summary>
/// Simple Modbus TCP master read inputs example.
/// </summary>
public static void ModbusTcpMasterReadInputs()
{
using (TcpClient client = new TcpClient("127.0.0.1", 502))
{
var factory = new ModbusFactory();
IModbusMaster master = factory.CreateMaster(client);
// read five input values
ushort startAddress = 100;
ushort numInputs = 5;
bool[] inputs = master.ReadInputs(0, startAddress, numInputs);
for (int i = 0; i < numInputs; i++)
{
Console.WriteLine($"Input {(startAddress + i)}={(inputs[i] ? 1 : 0)}");
}
}
// output:
// Input 100=0
// Input 101=0
// Input 102=0
// Input 103=0
// Input 104=0
}
using NModbus;
using NModbus.Serial;//安装库
using System.IO.Ports;
private void button3_Click(object sender, EventArgs e)
{
using (SerialPort port = new SerialPort("COM6"))
{
// configure serial port
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.WriteTimeout = 1000;
port.Open();
var factory = new ModbusFactory();
IModbusMaster master = factory.CreateRtuMaster(new SerialPortAdapter(port));
string A =master.ReadHoldingRegisters(1, 0, 1)[0].ToString();
MessageBox.Show(A);
}
}
转载自: