摘要:進(jìn)行基于Modbus協(xié)議和TCP/IP協(xié)議相結(jié)合的遠(yuǎn)程網(wǎng)絡(luò)通信,采用了套接字和多線程技術(shù),使得Modbus協(xié)議的信息可以在TCP/IP協(xié)議的Internet上傳輸,從而擴(kuò)展了Modbus 協(xié)議的應(yīng)用,并用基于以太網(wǎng)的控制器和制冷機(jī)組設(shè)備組成的網(wǎng)絡(luò)上實(shí)現(xiàn)了遠(yuǎn)程網(wǎng)絡(luò)通信。
關(guān)鍵詞:Modbus TCP/IP;制冷機(jī)組;套接字
中圖分類號(hào):TP393文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2008)30-0553-02
Based on The Mobus TCP/IP Protocol Realization
WANG Ke-peng
(Tongji University, Shanghai 201804, China)
Abstract: Based on the combination of the Modbus protocol and TCP/IP protocol, remote network communication was realized. Due to adopting technology of socket and multithread, it makes information of Modbus protocol to be transmited in Internet via TCP/IP protocol, more expanded application of Modbus protocol, and realized remote network communication in Modbus network that is made up of the controller and related chiller devices.
Key words: modbus TCP/IP; chiller; socket
1 引言
Modbus是一種通訊協(xié)議,是基于客戶機(jī)端和服務(wù)器端方式連設(shè)備,實(shí)現(xiàn)設(shè)備間的數(shù)據(jù)交換?;贛odbus應(yīng)用協(xié)議族的工業(yè)以太網(wǎng)解決方案已經(jīng)逐漸應(yīng)用于各種現(xiàn)場(chǎng)測(cè)控領(lǐng)域。而工業(yè)以太網(wǎng)的領(lǐng)先者M(jìn)odbus TCP/IP也正逐漸成為一種自動(dòng)化控制的通信協(xié)議標(biāo)準(zhǔn),在我們的風(fēng)洞監(jiān)控系統(tǒng)中的子系統(tǒng)制冷機(jī)組的監(jiān)控功能就是利用Modbus TCP/IP 協(xié)議來(lái)實(shí)現(xiàn)了對(duì)遠(yuǎn)程制冷機(jī)組的數(shù)據(jù)提取和數(shù)據(jù)傳輸從而達(dá)到監(jiān)控目的。
2 Modbus TCP/IP協(xié)議簡(jiǎn)介
Modbus/TCP報(bào)文服務(wù)采用客戶端/服務(wù)器的模式交換實(shí)時(shí)信息,該模式基于以下四種類型的報(bào)文:Modbus請(qǐng)求、Modbus確認(rèn)、Modbus指示和Modbus響應(yīng)。(如圖1)
請(qǐng)求(Request):客戶端為開始事物處理而發(fā)出的信息。
指示(Indication):服務(wù)器端接收到的請(qǐng)求信息。
響應(yīng)(Response):由服務(wù)器端發(fā)出的響應(yīng)信息。
確認(rèn)(Confirmation):客戶端接收到響應(yīng)信息。
3 Modbus TCP/IP協(xié)議結(jié)構(gòu)
常用的Modbus報(bào)文格式由附加地址、功能代碼、數(shù)據(jù)域組成,與通常的Modbus不同,在Modbus/TCP報(bào)文不再需要CRC-16或LRC校驗(yàn)域。因?yàn)門CP/IP協(xié)議和以太網(wǎng)的鏈路層校驗(yàn)機(jī)制保證了數(shù)據(jù)包傳遞的正確性。報(bào)文的具體格式(如圖2)。
另外,報(bào)文中增加的專用的MAPH頭(Modbus Application Protocol Header),用以識(shí)別Modbus應(yīng)用數(shù)據(jù)單元ADU(Application Data Unit),該頭的具體組成及含義如表1所示。
Modbus TCP功能代碼概要:功能代碼劃分:按應(yīng)用深淺,可分為3個(gè)類別。
類別0,對(duì)于客戶機(jī)/服務(wù)器最小的可用子集:讀多個(gè)保持寄存器(fc.3);寫多個(gè)保持寄存器(fc.16)。
類別1,可實(shí)現(xiàn)基本互易操作的常用代碼:讀線圈(fc.1);讀開關(guān)量輸入(fc.2);讀輸入寄存
(fc.4);寫線圈(fc.5);寫單一寄存器(fc.6)。
類別2,用于人機(jī)界面、監(jiān)控系統(tǒng)的例行操作和數(shù)據(jù)傳送功能:強(qiáng)制多個(gè)線圈(fc.15);讀通用寄存器(fc.20);寫通用寄存器(fc.21);屏蔽寫寄存器(fc.22);讀寫寄存器(fc.23)
4 結(jié)合Modbus TCP/IP在風(fēng)洞監(jiān)測(cè)系統(tǒng)的應(yīng)用
涉及到Modbus TCP/IP通信的模塊流程:其中該模塊用到的Modbus的功能代碼為寫線圈(fc.5)、讀多個(gè)保持寄存器(fc.3)。
該模塊對(duì)象在風(fēng)動(dòng)系統(tǒng)中為chiller,其中封裝了寫線圈(fc.5)和讀多個(gè)保持寄存器(fc.3),在模塊對(duì)象chiller的接口分別為
ForeceSingleCoils(int _transaction, int _protocolIdentifier, int _length, byte _unitId, byte _function, int _dataAddress, int _inputData)
ReadHoldingRegister(int _transaction, int _protocolIdentifier, int _length, byte _unitId, byte _function, int _dataAddress, int _numUnit)
在服務(wù)端有兩臺(tái)制冷機(jī)組 compressor F1,compressor F2
1) 開關(guān)控制步驟:其中A1為對(duì)compressor F1的開關(guān)控制,A2為對(duì)compressor F2的開關(guān)控制
首先向server發(fā)送連接請(qǐng)求進(jìn)行基于tcp的以太網(wǎng)的連接,如果連接成功,則做A1到F1的連接,起動(dòng)過(guò)程如下:
由B判斷是否與Server連接成功,如果未連接成功,則轉(zhuǎn)向繼續(xù)想Server請(qǐng)求連接,如果連接成功,則轉(zhuǎn)向C調(diào)用chiller.ForceSingleCoils()再到D調(diào)用Assemble()返回封裝好的buffer,最后到E調(diào)用m_Socket.SendData().,其中compressor1_ID是compressor F1的unitId。
發(fā)命令:chiller.ForceSingleCoils(1, 0, 6, compressor1_ID, 5, 61, 1))->
SubSystemSocket.m_Socket.SendData(Assemble(1, 0, 6, compressor1_ID, 5, 61, 1))(其中Assemble()是根據(jù)Modbus tcp規(guī)定對(duì)數(shù)據(jù)進(jìn)行封裝的過(guò)程,并返回一個(gè)數(shù)據(jù)塊buffer供套接字作參數(shù)發(fā)送到server再根據(jù)其中的unitId找到對(duì)應(yīng)的compressor,并將其設(shè)置為開啟狀態(tài),如果開啟成功,則返回原命令,如果開啟不成功,則把5+80作為functioncode的值返回。
2) 監(jiān)測(cè)compressor各參數(shù)數(shù)值步驟:
當(dāng)發(fā)送一個(gè)讀取數(shù)據(jù)的命令時(shí)由B判斷是否與compressor F1連接成功,如果未連接成功,則轉(zhuǎn)向繼續(xù)向compressor F1請(qǐng)求連接,如果連接成功,則轉(zhuǎn)向C調(diào)用chiller.ReadHoldingRegitsters再到D調(diào)用Assemble()返回封裝好的buffer,最后到E調(diào)用m_Socket.SendData().,其中compressor1_ID是compressor F1的unitId)
發(fā)命令:chiller.ReadHoldingRegisters(1, 0, 6, compressor1_ID, 3, 62, 5))->
SubSystemSocket.m_Socket.SendData(Assemble(1, 0, 6, compressor1_ID, 3, 62, 5))其中Assemble()是根據(jù)Modbus tcp規(guī)定對(duì)數(shù)據(jù)進(jìn)行封裝的過(guò)程,并返回一個(gè)數(shù)據(jù)塊buffer供套接字作參數(shù)發(fā)送到server再根據(jù)其中的unitId找到對(duì)應(yīng)的compressor,并讀取從_dataAddress開始的連續(xù)_numUnit個(gè)值,如果讀取成功,則返回值,如果讀取不成功,則把3+80作為functioncode的值返回。
如下為Assemble()的封裝源碼(其中的封裝順序是由Modbus文檔規(guī)定的):
注:本文中所涉及到的圖表、注解、公式等內(nèi)容請(qǐng)以PDF格式閱讀原文