NModbus API 手冊 版本 1.1, 2013.8 Written by Renee Lin
目錄 目錄... 2 1. 關於手冊... 4 2. NModbus API 函數... 5 2.1. Master API... 5 2.1.1. CreateRtu... 5 2.1.2. CreateIp... 6 2.1.3. CreateAscii... 7 2.1.4. WriteSingleCoil... 7 2.1.5. ReadCoils... 8 2.1.6. ReadInputs... 9 2.1.7. WriteSingleRegister... 10 2.1.8. ReadHoldingRegisters... 11 2.1.9. ReadInputRegisters... 12 2.1.10. ReadTimeout[ 屬性 ]... 13 2.1.11. Retries [ 屬性 ]... 13 2.2. Slave API... 15 2.2.1. CreateRtu... 15 2.2.2. CreateTcp... 16 2.2.3. CreateAscii... 17 2.2.4. Listen... 18 2.2.5. ModbusSlaveRequestReceived[ 事件 ]... 18 2.2.6. CreateDefaultDataStore... 19 2.2.7. DataStoreWrittenTo[ 事件 ]... 19 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:2
2.2.8. CoilDiscretes [DO 資料陣列 ]... 20 2.2.9. InputDiscretes [DI 資料陣列 ]... 20 2.2.10. HoldingRegisters [AO 資料陣列 ]... 20 2.2.11. InputRegisters [AI 資料陣列 ]... 21 2.3. 通用 API... 22 2.3.1. Dispose... 22 附錄 : 錯誤訊息... 23 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:3
1. 關於手冊 此手冊對於 NModbus 中所使用的 API 說明 什麼是 NModbus? 利用 NModbus 可實現 Modbus 的通訊協定, 它是由一群自願者所開發以及維護, 並且免費開放使用 ICP DAS 基於官方發佈的 NModbus 原始碼進行功能確認與改善, 程式開發員可以利用 ICP DAS 發佈的 DLL 進行 Windows 版 PC 或是 WinCE 版的 Modbus 程式開發 這個 DLL 具備以下功能 a. Modbus/RTU Master/Slave b. Modbus/ASCII Master/Slave c. Modbus/TCP Master/Slave d. Modbus/UDP Master/Slave 下載 DLL 與程式 a. WinForm 版本 DLL 和文件 :nmodbuspc.dll, log4net.dll 程式 b. WinCE 版本 DLL 和文件 :nmodbusce.dll, CABC.dll, FC19.dll 程式了解更多有關 Modbus http://www.icpdas.com/products/pac/i-8000/modbus_c.htm 適用 NModbus 開發的 PAC WinForm XPAC(WES 2009) Win8,Win7,Vista,Xp( 需有.NET framework) WinCE ViewPAC(CE5) WinPAC(CE5) XPAC(CE6) NModbus API 手冊, v1.1 最後編輯 2013.8 Page:4
2. NModbus API 函數 2.1. Master API 建立 Master 連線 Master.Read 更新資料至 UI UI 觸發事件 Master.Write Master.Dispose 2.1.1. CreateRtu 建立 modbus master RTU 的連線 ModbusSerialMaster CreateRtu( SerialPort serialport ) NModbus API 手冊, v1.1 最後編輯 2013.8 Page:5
serialport serialport 是由 new SerialPort() 建立, 而序列埠必需先被 serialport.open() 開啟 若 serialport 沒有指定值, 則會由系統帶入預設的值 例如 : 連接埠名稱為 COM1, 同位檢查為 None, 資料位元為 8, 停止位元為 1 回傳 ModbusSerialMaster [] SerialPort serialport = new SerialPort(); //Create a new SerialPort object. serialport.open(); ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort); 2.1.2. CreateIp 建立 modbus master IP 的連線 ModbusIpMaster CreateIp( TcpClient tcpclient ) tcpclient tcpclient 是由 new TcpClient() 建立, 而 tcpclient 必需由 tcpclient.beginconnect() 產生連接 回傳 ModbusIpMaster NModbus API 手冊, v1.1 最後編輯 2013.8 Page:6
[] string ipaddress = 10.0.0.69 ; int tcpport = 502; TcpClient tcpclient = new TcpClient(); //Create a new TcpClient object. tcpclient.beginconnect(ipaddress, tcpport, null, null); ModbusIpMaster master = ModbusIpMaster.CreateIp(tcpClient); 2.1.3. CreateAscii 建立 modbus master Ascii 的連線 ModbusSerialMaster CreateAscii( SerialPort serialport ) serialport serialport 是由 new SerialPort() 建立, 而序列埠必需先被 serialport.open() 開啟 回傳 ModbusSerialMaster [] SerialPort serialport = new SerialPort(); //Create a new SerialPort object. serialport.open(); ModbusSerialMaster master = ModbusSerialMaster.CreateAscii(serialPort); 2.1.4. WriteSingleCoil 寫入值到 DO 位址 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:7
void WriteSingleCoil( byte slaveid, ushort coiladdress, bool value ) slaveid 欲寫入裝置的 ID coiladdress 欲寫入的位址 value 若該位址要被寫入, 則寫入值為是 (TRUE); 若該位址沒有被寫入, 則值為否 (FALSE) 無 [] byte slaveid = 1; ushort coiladdress =1; bool value = true; master.writesinglecoil(slaveid, coiladdress,value); 2.1.5. ReadCoils 讀取 DO 的狀態 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:8
bool[] ReadCoils( byte slaveid, ushort startaddress, ushort numofpoints ) slaveid 欲讀取裝置的 ID startaddress 開始讀取的位址 numofpoints 讀取的長度 回傳 bool[] [] byte slaveid = 1; ushort startaddress = 0; ushort numofpoints = 10; bool[] coilstatus = master.readcoils(slaveid, startaddress, numofpoints); 2.1.6. ReadInputs 讀取 DI 的狀態 bool[] ReadInputs( byte slaveid, ushort startaddress, NModbus API 手冊, v1.1 最後編輯 2013.8 Page:9
) ushort numofpoints slaveid 欲讀取裝置的 ID startaddress 開始讀取的位址 numofpoints 讀取的長度 回傳 bool[] [] byte slaveid = 1; ushort startaddress =0; ushort numofpoints = 10; bool[] status = master.readinputs(slaveid, startaddress, numofpoints); 2.1.7. WriteSingleRegister 寫入值到 AO 位址 void WriteSingleRegister( byte slaveid, ushort registeraddress, ushort value ) NModbus API 手冊, v1.1 最後編輯 2013.8 Page:10
slaveid 欲寫入裝置的 ID registeraddress 欲寫入的位址 value 欲寫入的值 無 [] byte slaveid = 1; ushort registeraddress = 1; ushort value = 1000; master.writesingleregister(slaveid, registeraddress, value); 2.1.8. ReadHoldingRegisters 讀取 AO 的值 ushort[] ReadHoldingRegisters( byte slaveid, ushort startaddress, ushort numofpoints ) slaveid 欲讀取裝置的 ID NModbus API 手冊, v1.1 最後編輯 2013.8 Page:11
startaddress 開始讀取的位址 numofpoints 讀取暫存區的長度 回傳 ushort[] Exampls [] byte slaveid = 1; ushort startaddress =0; ushort numofpoints = 10; ushort[] holding_register = master.readholdingregisters(slaveid, startaddress, numofpoints); 2.1.9. ReadInputRegisters 讀取 AI 的值 ushort[] ReadInputRegisters( byte slaveid, ushort startaddress, ushort numofpoints ) slaveid 欲讀取裝置的 ID startaddress NModbus API 手冊, v1.1 最後編輯 2013.8 Page:12
開始讀取的位址 numofpoints 讀取暫存區的長度 回傳 ushort[] [] byte slaveid = 1; ushort startaddress =0; ushort numofpoints = 10; ushort[] register = master.readinputregisters(slaveid, startaddress, numofpoints); 2.1.10. ReadTimeout[ 屬性 ] [ 屬性 ] 取得或設定讀取作業未完成時, 發生逾時之前的毫秒數 int ReadTimeout { get; set; } [] SerialPort serialport = new SerialPort();//use RTU for example serialport.open(); ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort); master.transport.readtimeout = 300; //milliseconds 2.1.11. Retries [ 屬性 ] [ 屬性 ] 在遇到 IO 錯誤 逾時或損壞訊息等等的失敗情況後, 重試發送訊息的次數 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:13
int Retries { get; set; } [] string ipaddress = 10.0.0.69 ; //use TCP for example int tcpport = 502; TcpClient tcpclient = new TcpClient(); tcpclient.beginconnect(ipaddress, tcpport, null, null); ModbusIpMaster master = ModbusIpMaster.CreateIp(tcpClient); master.transport.retries = 0; 注意 Retries = 0 表示不需要重試 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:14
2.2. Slave API 取得裝置上的值 建立 Slave 連線 更新至 DataStore Slave.Listen 裝置觸發事件 : DataStoreWrittenTo Slave.Dispose 設定 DO 設定 AO 2.2.1. CreateRtu 建立 Modbus slave Rtu 的連線 ModbusSerialSlave CreateRtu( byte slaveid, SerialPort serialport ) slaveid serialport 欲建立連線裝置的 ID 序列埠必需被 serialport.open() 開啟, 而 serialport 是由 new SerialPort() 建立 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:15
回傳 ModbusSerialSlave [] byte slaveid = 1; SerialPort serialport = new SerialPort(); serialport.open(); ModbusSlave slave = ModbusSerialSlave.CreateRtu(slaveID, serialport); 2.2.2. CreateTcp 建立 Modbus slave TCP 的連線 ModbusTcpSlave CreateTcp( byte slaveid, TcpListener tcplistener ) slaveid 欲建立連線裝置的 ID tcplistener tcplistener 是由 new TcpListener () 建立, 而 tcplistener 必需由 tcplistener.start() 開始接聽 回傳 ModbusTcpSlave NModbus API 手冊, v1.1 最後編輯 2013.8 Page:16
[] int port = 502; IPHostEntry ipentry = Dns.GetHostEntry(Dns.GetHostName()); IPAddress[] addr = ipentry.addresslist; TcpListener tcplistener = new TcpListener(addr[0], port); tcplistener.start(); ModbusSlave slave = ModbusTcpSlave.CreateTcp(slaveID, slavetcplistener); 2.2.3. CreateAscii 建立 Modbus slave Ascii 的連線 ModbusSerialSlave CreateAscii( byte slaveid, SerialPort serialport ) slaveid 欲建立連線裝置的 ID serialport 序列埠必需被 serialport.open() 開啟, 而 serialport 是由 new SerialPort() 建立 回傳 ModbusSerialSlave [] byte slaveid = 1; SerialPort serialport = new SerialPort(); serialport.open(); NModbus API 手冊, v1.1 最後編輯 2013.8 Page:17
ModbusSlave slave = ModbusSerialSlave.CreateAscii(slaveID, serialport); 2.2.4. Listen Slave 開始監聽要求 void Listen() [] int port = 502; //use Tcp for example IPHostEntry ipentry = Dns.GetHostEntry(Dns.GetHostName()); IPAddress[] addr = ipentry.addresslist; TcpListener tcplistener = new TcpListener(addr[0], port); tcplistener.start(); ModbusSlave slave =ModbusTcpSlave.CreateTcp(slaveID, tcplistener); slave.listen(); 無 2.2.5. ModbusSlaveRequestReceived[ 事件 ] 當 slave 收到要求的時候觸發事件 EventHandler<ModbusSlaveRequestEventArgs> ModbusSlaveRequestReceived [] NModbus API 手冊, v1.1 最後編輯 2013.8 Page:18
slave.modbusslaverequestreceived += new EventHandler<ModbusSlaveRequestEventArgs>(Modbus_Request_Event); 2.2.6. CreateDefaultDataStore 將 AO,AI 預設為 0,DO,DI 預設為 false DataStore CreateDefaultDataStore() [] Slave.DataStore = Modbus.Data.DataStoreFactory.CreateDefaultDataStore(); 回傳 DataStore 2.2.7. DataStoreWrittenTo[ 事件 ] 當 slave 的 DataStore 被 master 之命令寫入時觸發事件 EventHandler<DataStoreEventArgs> DataStoreWrittenTo [] slave.datastore.datastorewrittento += new EventHandler<DataStoreEventArgs>(Modbus_DataStoreWriteTo); NModbus API 手冊, v1.1 最後編輯 2013.8 Page:19
2.2.8. CoilDiscretes [DO 資料陣列 ] DO 的資料陣列 ModbusDataCollection<bool> CoilDiscretes { get; private set; } [] slave.datastore.coildiscretes[0] = true; slave.datastore.coildiscretes[1] = false; 2.2.9. InputDiscretes [DI 資料陣列 ] DI 的資料陣列, 可將裝置的 DI 數值儲存至此 ModbusDataCollection<bool> InputDiscretes { get; private set; } [] slave.datastore.inputdiscretes[0] = true; slave.datastore.inputdiscretes[1] = false; 2.2.10. HoldingRegisters [AO 資料陣列 ] AO 的資料陣列 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:20
ModbusDataCollection<ushort> HoldingRegisters { get; private set; } [] slave.datastore.holdingregisters[0] = 222; slave.datastore.holdingregisters[1] = 333; 2.2.11. InputRegisters [AI 資料陣列 ] AI 的資料陣列, 可將裝置的 AI 值儲存至此 ModbusDataCollection<ushort> InputRegisters { get; private set; } [] slave.datastore.inputregisters[0] = 222; slave.datastore.inputregisters[1] = 333; NModbus API 手冊, v1.1 最後編輯 2013.8 Page:21
2.3. 通用 API 2.3.1. Dispose 對已定義的應用程序執行釋放或重設相關聯沒有應用的資源 void Dispose() 無 無 [] string ipaddress = 10.0.0.69 ; //use master tcp for example int tcpport = 502; TcpClient tcpclient = new TcpClient(); tcpclient.beginconnect(ipaddress, tcpport, null, null); //Create a new TcpClient object. ModbusIpMaster master = ModbusIpMaster.CreateIp(tcpClient); master.dispose(); NModbus API 手冊, v1.1 最後編輯 2013.8 Page:22
附錄 : 錯誤訊息 以下為 NModbus 錯誤代碼對應表 代碼 名稱 說明 01 不支援的功能 收到不被允許的指令碼 02 不合法的位址 收到不正當的位址 03 不合法的數值 收到不正確的數值 04 Slave 裝置失效 要回復要求給 master 時, 發生無法復原的錯誤 05 確認 ( 命令執行中 ) 當 master/slave 需要一段時間處理收到的要求時, 會發出此代碼以避免發生逾時錯誤 06 Slave 裝置忙碌 當 master/slave 正在處理長時間的要求時, 對方必須等到處理完畢後再傳送訊息 08 記憶體同位錯誤 當 master/slave 要讀取記錄檔時, 偵測到記憶體同位錯誤 0A 無效的閘道 閘道配置錯誤或過載 0B 目標裝置閘道沒有回應 目標裝置沒有回應 通常表示裝置目前不在線上 NModbus API 手冊, v1.1 最後編輯 2013.8 Page:23