一、什么是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 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
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
}
|