使用modbus單點讀取地址是輪詢可能會導致效率很低,頻繁發送讀取報文會導致plc響應時間拉長,批量讀取可大大減少數據通信的過程,每次讀取完成后,在內存中異步處理返回來的數據數組。
modbus 功能碼簡介 :
0x01: 讀線圈寄存器
0x02: 讀離散輸入寄存器
0x03: 讀保持寄存器
0x04: 讀輸入寄存器
0x05: 寫單個線圈寄存器
0x06: 寫單個保持寄存器
0x0F 寫多個線圈寄存器
0x10: 寫多個保持寄存器
讀取指令多用到 01~04 功能碼。在這里用到的包有 NModbus4,Nuget可直接獲取。開發語言C#
以 讀取保持寄存器 03 為例 看下Nmodbus4里的方法簽名
// // 摘要: // Reads contiguous block of holding registers. // // 參數: // slaveAddress: // Address of device to read values from. // // startAddress: // Address to begin reading. // // numberOfPoints: // Number of holding registers to read. // // 返回結果: // Holding registers status ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints);
返回類型為 ushort[] 數組,slaveAddress 從機地址,也就是plc的設備id,startAddress 讀取起始地址,numberOfPoints 這個是重點,這個參數決定每次讀取的點號數量。寫1的話表示每次讀取一個點號。
private ushort[] registerBuffer;
registerBuffer = master.ReadHoldingRegisters(1, 1, 100);
定義一個字節數組用來接收返回值
當讀取到數據組時 registerBuffer 可根據需要處理,可拼接成json發送至平台消費者,或者開啟子線程循環字節數組,將點號值返回消費者。
可以計算下,正常工控一個設備點號可能在 100個左右,如果單點讀取,輪詢可能需要1分鍾時間,如果開啟100個子線程同時讀取,還可以接受,但是1000個點呢,對計算機資源耗費巨大。綜合考慮
批量讀取還是經濟換算的。
for (int i = 0; i < registerBuffer.Length; i++) { { PublishMessage(registerBuffer[i]); } }
需要注意的是,使用modbus協議批量讀取 PLC 數據時需要跟PLC程序開發者做好溝通規划好數據區,將返回數據集中在相鄰的寄存器地址里,方便讀取。
