前言:最近在做一個項目,需要使用ModBus RTU與PLC進行通訊,現在將使用過程記錄,以便備查。 一、什麼是ModBus通訊協議 Modbus協議是應用於電子控制器上的一種通用語言,此協議支持傳統的RS-232、RS-422、RS-485和乙太網設備。 ModBus功能碼 二、ModBus通訊協 ...
前言:最近在做一個項目,需要使用ModBus RTU與PLC進行通訊,現在將使用過程記錄,以便備查。
一、什麼是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的開源實現類庫:NModBus4,github地址:https://github.com/NModbus4/NModbus4。針對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 |
每個方法都有各自的非同步方法實現。
這裡以RTU展示其使用方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 創建 ModBus RTU 連接 3 /// </summary> 4 /// <param name="portName">埠號</param> 5 /// <param name="baudRate">波特率</param> 6 /// <param name="parity">奇偶校驗位</param> 7 /// <param name="dataBits">數據位</param> 8 /// <param name="stopBits">停止位</param> 9 /// <returns></returns> 10 public IModbusSerialMaster CreateModBusRtuConnection(string portName,int baudRate,Parity parity,int dataBits,StopBits stopBits) 11 { 12 return CreateModBusRtuConnect(new SerialPort(portName, baudRate, parity, dataBits, stopBits)); 13 } 14 15 public IModbusSerialMaster CreateModBusRtuConnection(SerialPort serialPort) 16 { 17 IModbusSerialMaster master = null; 18 if (!serialPort.IsOpen) 19 { 20 try 21 { 22 serialPort.Open(); 23 } 24 catch (Exception e) 25 { 26 throw e; 27 } 28 } 29 try 30 { 31 master = ModbusSerialMaster.CreateRtu(serialPort); 32 ///同時也可以配置master的一些參數 33 master.Transport.ReadTimeout = 100;//讀取數據超時100ms 34 master.Transport.WriteTimeout = 100;//寫入數據超時100ms 35 master.Transport.Retries = 3;//重試次數 36 master.Transport.WaitToRetryMilliseconds = 10;//重試間隔 37 38 } 39 catch(Exception e) 40 { throw e; 41 } 42 return master; 43 } 44 }View Code