c#實(shí)現(xiàn)上位機(jī)與歐姆龍plc通訊(fins)
先介紹下一些基本定義
串行通信:通過(guò)的是plc上的串行口rs232/rs422/485口,上位機(jī)鏈接系統(tǒng) hostlink系統(tǒng)是對(duì)于fa系統(tǒng)一種及優(yōu)化有經(jīng)濟(jì)的通信方式。
適用于一臺(tái)上位機(jī)與一臺(tái)或者多臺(tái)的plc進(jìn)行數(shù)據(jù)通信。
通訊協(xié)議分兩種
1:c-mode commands
只可以通過(guò)串口進(jìn)行通訊
2:fins commands
既可以通過(guò)串口通訊也可以通過(guò)各類(lèi)網(wǎng)絡(luò)通訊(適應(yīng)性較強(qiáng))
本文只介紹fins通訊
fins (factory in terfave network service) 通訊協(xié)議是歐姆龍公司開(kāi)發(fā)的一款自動(dòng)化控制網(wǎng)絡(luò)指令/響應(yīng)系統(tǒng)的通訊協(xié)議;運(yùn)用fins指令可實(shí)現(xiàn)各種網(wǎng)絡(luò)間的無(wú)縫通信
fins幀結(jié)構(gòu)
- 發(fā)送命令結(jié)構(gòu) 命令碼2個(gè)字節(jié)
- 響應(yīng)命令結(jié)構(gòu) 命令碼2個(gè)字節(jié)
- 命令碼 01 01讀數(shù)據(jù)
- 命令碼 01 02寫(xiě)數(shù)據(jù)
- 結(jié)束碼 00 00無(wú)錯(cuò)誤
1、獲取plc節(jié)點(diǎn)地址
上位機(jī)和plc建立tcp通訊之后,可以發(fā)送以下命令來(lái)獲得plc的節(jié)點(diǎn)地址;
幀結(jié)構(gòu)見(jiàn)下表:
列表 | content(十六進(jìn)制) | description(說(shuō)明) |
---|---|---|
頭 | 46 49 4e 53 | ascii分別代表的是 f i n s |
長(zhǎng)度 | 00 00 00 0c | 從command之后的數(shù)據(jù)包的長(zhǎng)度 |
錯(cuò)誤代碼 | 00 00 00 00 | 目前暫時(shí)沒(méi)用,因?yàn)樵诜?wù)器不需要檢測(cè)內(nèi)部錯(cuò)誤 |
連接的節(jié)點(diǎn)地址 | 00000000~000000fe | 分別是0~254,當(dāng)設(shè)置為0時(shí)表示自動(dòng)獲取客戶(hù)端的fins節(jié)點(diǎn)地址 |
2、命令碼介紹
詳細(xì)內(nèi)容說(shuō)明介紹見(jiàn)下表:
命令內(nèi)容 | 命令代碼(mr sr) | 說(shuō)明 | 功能 |
---|---|---|---|
訪(fǎng)問(wèn)i/o存儲(chǔ)區(qū) | 01 01 | 讀內(nèi)存區(qū) | 讀連續(xù)i/o存儲(chǔ)區(qū)字的內(nèi)容 |
訪(fǎng)問(wèn)i/o存儲(chǔ)區(qū) | 01 02 | 寫(xiě)內(nèi)存區(qū) | 寫(xiě)連續(xù)i/o存儲(chǔ)區(qū)字的內(nèi)容 |
訪(fǎng)問(wèn)i/o存儲(chǔ)區(qū) | 01 03 | 填充內(nèi)存區(qū) | 將相同的數(shù)據(jù)寫(xiě)入指定范圍的i/o存儲(chǔ)器區(qū) |
訪(fǎng)問(wèn)i/o存儲(chǔ)區(qū) | 01 04 | 多個(gè)存儲(chǔ)區(qū)讀取 | 讀取指定的非連續(xù)i/o存儲(chǔ)區(qū)字 |
訪(fǎng)問(wèn)i/o存儲(chǔ)區(qū) | 01 05 | 存儲(chǔ)區(qū)傳輸 | 將連續(xù)存儲(chǔ)i/o存儲(chǔ)區(qū)字內(nèi)容復(fù)制到另外的i/o存儲(chǔ)區(qū) |
訪(fǎng)問(wèn)參數(shù)區(qū) | 02 01 | 讀取參數(shù)區(qū) | 讀取連續(xù)參數(shù)區(qū)字內(nèi)容 |
訪(fǎng)問(wèn)參數(shù)區(qū) | 02 02 | 寫(xiě)入?yún)?shù)區(qū) | 寫(xiě)入連續(xù)參數(shù)區(qū)字內(nèi)容 |
訪(fǎng)問(wèn)參數(shù)區(qū) | 02 03 | 填充參數(shù)區(qū) | 將相同數(shù)據(jù)寫(xiě)入到指定范圍參數(shù)區(qū)域字 |
改變操作模式 | 04 01 | 設(shè)置cpu操作模式為run | 將cpu單元的操作模式更改為run或monitor |
改變操作模式 | 04 02 | 設(shè)置cpu操作模式為stop | 將cpu單元的操作模式更改為編程 |
改變操作模式 | 06 01 | 讀取cpu單元狀態(tài) | 讀取cpu單元狀態(tài) |
錯(cuò)誤日志 | 21 01 | 錯(cuò)誤清除 | 清除錯(cuò)誤或錯(cuò)誤信息 |
錯(cuò)誤日志 | 21 02 | 讀取錯(cuò)誤日志 | 讀取錯(cuò)誤日志 |
錯(cuò)誤日志 | 21 03 | 清除錯(cuò)誤日志 | 清除錯(cuò)誤日志指針 |
3、i / o存儲(chǔ)器地址標(biāo)識(shí)
區(qū)域 | 數(shù)據(jù)類(lèi)型 | 存儲(chǔ)區(qū)代碼 | 存儲(chǔ)區(qū)地址范圍 | 存儲(chǔ)地址 | 字節(jié)長(zhǎng)度 |
---|---|---|---|---|---|
dm | bit | 02 | d0000000到d3276715 | 000000到7fff0f | 1 |
dm | word | 82 | d00000到d32767 | 000000到7fff00 | 2 |
鑒于我們?cè)诤蚿lc通訊時(shí),一般只需要進(jìn)行讀取dm區(qū)寄存器操作,因?yàn)楸疚闹唤榻B讀取和寫(xiě)入dm區(qū)寄存器。其他的有需要的童鞋進(jìn)行自己功能拓展。
舉例:
讀取dm區(qū)地址100,連續(xù)10個(gè)地址的數(shù)據(jù)
發(fā)送命令:010182006400000a
返回命令:010100000102030405060708090a
發(fā)送的命令進(jìn)行說(shuō)明:
- 1、01 01代表功能碼,讀連續(xù)i/o存儲(chǔ)區(qū)字的內(nèi)容
- 2、82代表進(jìn)行字操作
- 3、00 64轉(zhuǎn)成十進(jìn)制就是100代表的是我們要讀取的起始地址
- 4、00000a轉(zhuǎn)成十進(jìn)制就是10代表的是我們要讀取得長(zhǎng)度
響應(yīng)的命令說(shuō)明
- 1、01 01代表功能碼,讀連續(xù)i/o存儲(chǔ)區(qū)字的內(nèi)容
- 2、00 00代表結(jié)束碼,當(dāng)不是00 00的時(shí)候表明數(shù)據(jù)幀不對(duì)
- 3、01 02 03 04 05 06 07 08 09 0a分別代表要讀取的十個(gè)寄存器的數(shù)據(jù)值
具體協(xié)議可以查看百度文庫(kù):歐姆龍fins通訊協(xié)議
綜上,結(jié)合之前的博客,c#socket客戶(hù)端:c#socket客戶(hù)端我們可以整合得到一個(gè)歐姆龍fins的類(lèi),如下所示:
using system; using system.collections.generic; using system.text; using system.net; using system.net.sockets; using system.threading; namespace omrentfins { public class omronfins { /// <summary> /// 客戶(hù)端連接socket /// </summary> private socket clientsocket; /// <summary> /// 連接狀態(tài) /// </summary> public boolean connected = false; /// <summary> /// 發(fā)送數(shù)據(jù) /// </summary> private byte[] sendmess; /// <summary> /// 連接點(diǎn) /// </summary> private ipendpoint hostendpoint; /// <summary> /// 連接信號(hào)量 /// </summary> private static autoresetevent autoconnectevent = new autoresetevent(false); /// <summary> /// 接受到數(shù)據(jù)時(shí)的委托 /// </summary> /// <param name="info"></param> public delegate void receivemsghandler(byte[] info); /// <summary> /// 接收到數(shù)據(jù)時(shí)調(diào)用的事件 /// </summary> public event receivemsghandler onmsgreceived; /// <summary> /// 開(kāi)始監(jiān)聽(tīng)數(shù)據(jù)的委托 /// </summary> public delegate void startlistenhandler(); /// <summary> /// 開(kāi)始監(jiān)聽(tīng)數(shù)據(jù)的事件 /// </summary> public event startlistenhandler startlistenthread; /// <summary> /// 發(fā)送信息完成的委托 /// </summary> /// <param name="successorfalse"></param> public delegate void sendcompleted(bool successorfalse); /// <summary> /// 發(fā)送信息完成的事件 /// </summary> public event sendcompleted onsended; /// <summary> /// 監(jiān)聽(tīng)接收的socketasynceventargs /// </summary> private socketasynceventargs listenersocketasynceventargs; int plcport; public omronfins(string hostname, int32 port, int32 plcstaion) { plcport = plcstaion; ipaddress[] addresslist = dns.gethostaddresses(hostname); this.hostendpoint = new ipendpoint(addresslist[addresslist.length - 1], port); this.clientsocket = new socket(this.hostendpoint.addressfamily, sockettype.stream, protocoltype.tcp); } /// <summary> /// 連接服務(wù)端 /// </summary> private bool connect() { using (socketasynceventargs connectargs = new socketasynceventargs()) { connectargs.usertoken = this.clientsocket; connectargs.remoteendpoint = this.hostendpoint; connectargs.completed += new eventhandler<socketasynceventargs>(onconnect); clientsocket.connectasync(connectargs); //等待連接結(jié)果 bool autores = autoconnectevent.waitone(1000); if (this.connected) { listenersocketasynceventargs = new socketasynceventargs(); byte[] receivebuffer = new byte[1024];//設(shè)置接收buffer區(qū)大小 listenersocketasynceventargs.usertoken = clientsocket; listenersocketasynceventargs.setbuffer(receivebuffer, 0, receivebuffer.length); listenersocketasynceventargs.completed += new eventhandler<socketasynceventargs>(onreceive); startlistenthread(); // socketextensions.setkeepalive(clientsocket, 3000, 1000); return true; } else return false; } } /// <summary> /// 開(kāi)始監(jiān)聽(tīng)線(xiàn)程的入口函數(shù) /// </summary> private void listen() { (listenersocketasynceventargs.usertoken as socket).receiveasync(listenersocketasynceventargs); } public static list<socketasynceventargs> s_lst = new list<socketasynceventargs>(); /// <summary> /// 發(fā)送信息 /// </summary> /// <param name="message"></param> private void send(byte[] message) { if (this.connected) { byte[] sendbuffer = message; socketasynceventargs sendersocketasynceventargs = null;// new socketasynceventargs(); lock (s_lst) { if (s_lst.count > 0) { sendersocketasynceventargs = s_lst[s_lst.count - 1]; s_lst.removeat(s_lst.count - 1); } } if (sendersocketasynceventargs == null) { sendersocketasynceventargs = new socketasynceventargs(); sendersocketasynceventargs.usertoken = this.clientsocket; sendersocketasynceventargs.remoteendpoint = this.hostendpoint; sendersocketasynceventargs.completed += (object sender, socketasynceventargs _e) => { lock (s_lst) { s_lst.add(sendersocketasynceventargs); } }; } sendersocketasynceventargs.setbuffer(sendbuffer, 0, sendbuffer.length); clientsocket.sendasync(sendersocketasynceventargs); } else { this.connected = false; } sendmess = message; } /// <summary> /// 斷開(kāi)連接 /// </summary> private bool disconnect() { bool returndis = true; try { this.clientsocket.shutdown(socketshutdown.both); this.clientsocket.close(); //this.clientsocket.dispose(); //clientsocket.disconnect(true); //clientsocket.disconnect(false); } catch (exception) { returndis = false; } finally { } this.connected = false; return returndis; } /// <summary> /// 連接的完成方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void onconnect(object sender, socketasynceventargs e) { this.connected = (e.socketerror == socketerror.success); autoconnectevent.set(); } /// <summary> /// 接收的完成方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void onreceive(object sender, socketasynceventargs e) { if (e.bytestransferred == 0) { //console.writeline("socket is closed", socket.handle); if (clientsocket.connected) { try { clientsocket.shutdown(socketshutdown.both); } catch (exception) { //client already closed } finally { if (clientsocket.connected) { clientsocket.close(); } } } byte[] rs = new byte[0]; onmsgreceived(rs); this.connected = false; } else { byte[] buffer = new byte[e.bytestransferred]; for (int i = 0; i < e.bytestransferred; i++) { buffer[i] = e.buffer[i]; } this.onmsgreceived(buffer); listen(); } } /// <summary> /// 發(fā)送的完成方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void onsend(object sender, socketasynceventargs e) { if (e.socketerror == socketerror.success) { onsended(true); } else { onsended(false); this.processerror(e); } } /// <summary> /// 處理錯(cuò)誤 /// </summary> /// <param name="e"></param> private void processerror(socketasynceventargs e) { socket s = e.usertoken as socket; if (s.connected) { try { s.shutdown(socketshutdown.both); } catch (exception) { //client already closed } finally { if (s.connected) { s.close(); } } this.connected = false; } //throw new socketexception((int32)e.socketerror); } #region idisposable members public void dispose() { autoconnectevent.close(); if (this.clientsocket.connected) { this.clientsocket.close(); } } #endregion #region 歐姆龍通訊協(xié)議 /// <summary> /// 發(fā)送命令反饋 /// </summary> /// <param name="successorfalse"></param> void omronfins_onsended(bool successorfalse) { if (!successorfalse) { } else { } } byte pcs; byte plcs; int sendorrev; int sendorrev2; byte[] sendback; byte[] recvback; /// <summary> /// 接受命令反饋 /// </summary> /// <param name="info"></param> void omronfins_onmsgreceived(byte[] info) { if (sendmesshas) { if (info.length >= 24) { if (int.parse(info[23].tostring("x").trim(), system.globalization.numberstyles.hexnumber) == plcport) { pcs = info[19]; plcs = info[23]; sendmesshas = false; } } } else { if (info.length > 0)//plc連接錯(cuò)誤no { if (sendorrev2 == 1)//發(fā)送命令 { sendback = info; sendorrev2 = 0; } else if (sendorrev == 2)//接受命令 { recvback = info; sendorrev = 0; } } else { if (sendorrev2 == 1)//發(fā)送命令 { sendback = new byte[1]; sendback[0] = 0x00; sendorrev2 = 0; } else if (sendorrev == 2)//接受命令 { recvback = new byte[1]; recvback[0] = 0x00; sendorrev = 0; } } } } void omronfins_startlistenthread() { this.listen(); } bool sendmesshas = false; /// <summary> /// 打開(kāi)連接 /// </summary> /// <returns></returns> public bool openlinkplc() { bool ret = false; this.startlistenthread += new startlistenhandler(omronfins_startlistenthread); this.onmsgreceived += new receivemsghandler(omronfins_onmsgreceived); this.onsended += new sendcompleted(omronfins_onsended); ret = this.connect(); if (ret) { sendmesshas = true; this.send(getpcadress()); int addns = 0; while (sendmesshas && addns < 500) { thread.sleep(2); addns++; } if (addns < 500) { ret = true; } else { ret = false; } } return ret; } /// <summary> /// 關(guān)閉連接 /// </summary> /// <returns></returns> public bool closelinkplc() { return this.disconnect(); } /// <summary> /// 寫(xiě)入值(word) /// </summary> /// <param name="typeint">起始寄存器地址</param> /// <param name="numdata">個(gè)數(shù)</param> /// <param name="intvalue">值</param> /// <returns>true,成功;false,失敗</returns> public bool writeplcdata(string typeint, int numdata, ref int[] intvalue) { bool sendrerun = false; if (numdata > 0) { byte[] numdata = bitconverter.getbytes(numdata);//use numdata[0] and numdata[1] byte[] sendmessage = new byte[34 + numdata * 2]; if (gettype(typeint, 0) != 0x00 && address != null && address.length > 1) { byte[] getsendfunc = this.setplcvalue(plcs, pcs, gettype(typeint, 0), address[1], address[0], 0x00, numdata[1], numdata[0], numdata); for (int i = 0; i < 34 + numdata * 2; i++) { if (i < 34) { sendmessage[i] = getsendfunc[i]; } else { if ((i - 33) % 2 != 0) { byte[] buffinvalue = bitconverter.getbytes(intvalue[(i - 33) / 2]); sendmessage[i] = buffinvalue[1]; } else { byte[] buffinvalue = bitconverter.getbytes(intvalue[(i - 33) / 2 - 1]); sendmessage[i] = buffinvalue[0]; } //sendmessage[i] } } sendorrev2 = 1; this.send(sendmessage); int outtime = 0; while (sendorrev2 != 0 && this.connected && outtime < 600) { thread.sleep(2); outtime++; } if (outtime < 600 && sendback != null) { try { //if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00 && sendback[29] == 0x00) //{ if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00) { sendrerun = true; } else { sendrerun = false; } } catch (exception) { } } else { sendorrev2 = 0; } } } return sendrerun; } /// <summary> /// 讀取值(word) /// </summary> /// <param name="typeint">起始寄存器地址</param> /// <param name="numdata">個(gè)數(shù)</param> /// <param name="intvalue">值</param> /// <returns></returns> public bool readplcdata(string typeint, int numdata, out int[] intvalue) { bool getplcret = false; intvalue = new int[1]; if (numdata > 0) { intvalue = new int[numdata]; byte[] numdata = bitconverter.getbytes(numdata);//use numdata[0] and numdata[1] byte[] recivemessage = new byte[34]; if (gettype(typeint, 0) != 0x00 && address != null && address.length > 1) { byte[] getrecivefunc = this.getplcvalue(plcs, pcs, gettype(typeint, 0), address[1], address[0], 0x00, numdata[1], numdata[0]); this.send(getrecivefunc); sendorrev = 2; int outtime = 0; while (sendorrev != 0 && this.connected && outtime < 600) { thread.sleep(2); outtime++; } if (outtime < 600 && recvback != null) { try { //if (recvback.length > 1 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00 && recvback[29] == 0x00) if (recvback.length == 30 + numdata * 2 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00) { getplcret = true; for (int i = 0; i < numdata; i++) { intvalue[i] = int.parse(recvback[30 + i * 2].tostring("x").padleft(2, '0') + recvback[30 + i * 2 + 1].tostring("x").padleft(2, '0'), system.globalization.numberstyles.hexnumber); } } else { getplcret = false; } } catch (exception) { } } else { sendorrev = 0; } } } return getplcret; } /// <summary> /// 讀取值(word) /// </summary> /// <param name="typeint">起始寄存器地址</param> /// <param name="numdata">個(gè)數(shù)</param> /// <param name="intvalue">值</param> /// <returns></returns> public bool readplcdatacio(string typeint, int numdata, out int[] intvalue) { bool getplcret = false; intvalue = new int[1]; if (numdata > 0) { intvalue = new int[numdata]; byte[] numdata = bitconverter.getbytes(numdata);//use numdata[0] and numdata[1] byte[] recivemessage = new byte[34]; if (gettype(typeint, 0) != 0x00 && address != null && address.length > 1) { byte[] getrecivefunc = this.getplcvalue(plcs, pcs, gettype(typeint, 0), address[1], address[0], 0x00, numdata[1], numdata[0]); this.send(getrecivefunc); sendorrev = 2; int outtime = 0; while (sendorrev != 0 & this.connected & outtime < 800) { thread.sleep(2); outtime++; } if (outtime < 800 && recvback != null) { //try //{ //if (recvback.length > 1 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00 && recvback[29] == 0x00) if (recvback.length > 30 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00) { getplcret = true; for (int i = 0; i < numdata; i++) { intvalue[i] = int.parse(recvback[30 + i * 2].tostring("x").padleft(2, '0') + recvback[30 + i * 2 + 1].tostring("x").padleft(2, '0'), system.globalization.numberstyles.hexnumber); } } else { getplcret = false; } //} //catch (exception) //{ //} } else { sendorrev = 0; } } } return getplcret; } /// <summary> /// 讀取值(bit) /// </summary> /// <param name="typeint">起始寄存器地址</param> /// <param name="intvalue">值</param> /// <returns></returns> public bool readplcbitdata(string typeint, out int intvalue) { bool getplcret = false; intvalue = 0; byte[] recivemessage = new byte[34]; if (gettype(typeint, 1) != 0x00 && address != null && address.length > 1) { byte[] getrecivefunc = this.getplcvalue(plcs, pcs, gettype(typeint, 1), address[1], address[0], addressbit[0]); this.send(getrecivefunc); sendorrev = 2; int outtime = 0; while (sendorrev != 0 & outtime < 600) { thread.sleep(2); outtime++; } if (outtime < 600) { if (recvback.length > 1 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00 && recvback[29] == 0x00) { getplcret = true; intvalue = int.parse(recvback[30].tostring("x").padleft(2, '0'), system.globalization.numberstyles.hexnumber); } } else { sendorrev = 0; } } return getplcret; } /// <summary> /// write值(bit) /// </summary> /// <param name="typeint">寄存器地址(ciox.x)</param> /// <returns></returns> public bool writebitplcdata(string typeint, int itemvalue) { bool sendrerun = false; byte[] sendmessage = new byte[35]; if (gettype(typeint, 1) != 0x00 && address != null && address.length > 1) { byte[] getsendfunc = this.writeplcbitvalue(plcs, pcs, gettype(typeint, 1), address[1], address[0], addressbit[0]); for (int i = 0; i < 35; i++) { if (i < 32) { sendmessage[i] = getsendfunc[i]; } else if (i == 32) { sendmessage[i] = 0x00; } else if (i == 33) { sendmessage[i] = 0x01; } else { if (itemvalue == 1) sendmessage[i] = 0x01; else sendmessage[i] = 0x00; } } this.send(sendmessage); sendorrev2 = 1; int outtime = 0; while (sendorrev2 != 0 & outtime < 600) { thread.sleep(2); outtime++; } if (outtime < 600) { if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00 && sendback[29] == 0x00) { sendrerun = true; } } else { sendorrev2 = 0; } } return sendrerun; } /// <summary> /// set 值(bit) /// </summary> /// <param name="typeint">寄存器地址(ciox.x)</param> /// <returns></returns> public bool setplcdata(string typeint) { bool sendrerun = false; byte[] sendmessage = new byte[35]; if (gettype(typeint, 1) != 0x00 && address != null && address.length > 1) { byte[] getsendfunc = this.setplcbitvalue(plcs, pcs, gettype(typeint, 1), address[1], address[0], addressbit[0]); for (int i = 0; i < 35; i++) { if (i < 34) { sendmessage[i] = getsendfunc[i]; } else { sendmessage[i] = 0x00; } } this.send(sendmessage); sendorrev2 = 1; int outtime = 0; while (sendorrev2 != 0 & outtime < 600) { thread.sleep(2); outtime++; } if (outtime < 600) { if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00 && sendback[29] == 0x00) { sendrerun = true; } } } return sendrerun; } /// <summary> /// rest 值(bit) /// </summary> /// <param name="typeint">寄存器地址(ciox.x)</param> /// <returns></returns> public bool restplcdata(string typeint) { bool sendrerun = false; byte[] sendmessage = new byte[35]; if (gettype(typeint, 1) != 0x00 && address != null && address.length > 1) { byte[] getsendfunc = this.rstplcbitvalue(plcs, pcs, gettype(typeint, 1), address[1], address[0], addressbit[0]); for (int i = 0; i < 35; i++) { if (i < 34) { sendmessage[i] = getsendfunc[i]; } else { sendmessage[i] = 0x00; } } this.send(sendmessage); sendorrev2 = 1; int outtime = 0; while (sendorrev2 != 0 & outtime < 600) { thread.sleep(2); outtime++; } if (outtime < 600) { if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00 && sendback[29] == 0x00) { sendrerun = true; } } } return sendrerun; } byte[] address; byte[] addressbit; private byte gettype(string typeint, int sizeofint) { byte ms = 0x00; if (typeint.indexof("d") == 0 | typeint.indexof("d") == 0) { if (sizeofint == 0) { ms = 0x82; if (typeint.indexof(".") == -1) address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.length - 1))); else { address = new byte[1]; addressbit = new byte[1]; } } else { ms = 0x02; if (typeint.indexof(".") > 1) { address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.indexof(".") - 1))); addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1))); } else { address = new byte[1]; addressbit = new byte[1]; } } } else if (typeint.indexof("cio") == 0 | typeint.indexof("cio") == 0) { if (sizeofint == 0) { ms = 0xb0; if (typeint.indexof(".") == -1) address = bitconverter.getbytes(int.parse(typeint.substring(3, typeint.length - 3))); else { address = new byte[1]; addressbit = new byte[1]; } } else { ms = 0x30; if (typeint.indexof(".") > 3) { address = bitconverter.getbytes(int.parse(typeint.substring(3, typeint.indexof(".") - 3))); addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1))); } else { address = new byte[1]; addressbit = new byte[1]; } } } else if (typeint.indexof("w") == 0 | typeint.indexof("w") == 0) { if (sizeofint == 0) { ms = 0xb1; if (typeint.indexof(".") == -1) address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.length - 1))); else { address = new byte[1]; addressbit = new byte[1]; } } else { ms = 0x31; if (typeint.indexof(".") > 1) { address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.indexof(".") - 1))); addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1))); } else { address = new byte[1]; addressbit = new byte[1]; } } } else if (typeint.indexof("h") == 0 | typeint.indexof("h") == 0) { if (sizeofint == 0) { ms = 0xb2; if (typeint.indexof(".") == -1) address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.length - 1))); else { address = new byte[1]; addressbit = new byte[1]; } } else { ms = 0x32; if (typeint.indexof(".") > 1) { address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.indexof(".") - 1))); addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1))); } else { address = new byte[1]; addressbit = new byte[1]; } } } else if (typeint.indexof("a") == 0 | typeint.indexof("a") == 0) { if (sizeofint == 0) { ms = 0xb3; if (typeint.indexof(".") == -1) address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.length - 1))); else { address = new byte[1]; addressbit = new byte[1]; } } else { ms = 0x33; if (typeint.indexof(".") > 1) { address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.indexof(".") - 1))); addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1))); } else { address = new byte[1]; addressbit = new byte[1]; } } } return ms; } /// <summary> /// get plc da1 sna1 /// </summary> /// <returns></returns> private byte[] getpcadress() { byte[] returngetpc = new byte[20]; returngetpc[0] = 0x46;//f returngetpc[1] = 0x49;//i returngetpc[2] = 0x4e;//n returngetpc[3] = 0x53;//s returngetpc[4] = 0x00; returngetpc[5] = 0x00; returngetpc[6] = 0x00; returngetpc[7] = 0x0c; returngetpc[8] = 0x00; returngetpc[9] = 0x00; returngetpc[10] = 0x00; returngetpc[11] = 0x00; returngetpc[12] = 0x00; returngetpc[13] = 0x00; returngetpc[14] = 0x00; returngetpc[15] = 0x00; returngetpc[16] = 0x00; returngetpc[17] = 0x00; returngetpc[18] = 0x00; returngetpc[19] = 0x00; return returngetpc; } /// <summary> /// read word /// </summary> /// <param name="da1"></param> /// <param name="sa1"></param> /// <param name="datavalue"></param> /// <param name="address1"></param> /// <param name="address2"></param> /// <param name="address3"></param> /// <param name="datanum1"></param> /// <param name="datanum2"></param> /// <returns></returns> private byte[] getplcvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3, byte datanum1, byte datanum2) { byte[] sendfun = new byte[34]; sendfun[0] = 0x46; sendfun[1] = 0x49; sendfun[2] = 0x4e; sendfun[3] = 0x53; sendfun[4] = 0x00; sendfun[5] = 0x00; sendfun[6] = 0x00; sendfun[7] = 0x1a; sendfun[8] = 0x00; sendfun[9] = 0x00; sendfun[10] = 0x00; sendfun[11] = 0x02; sendfun[12] = 0x00; sendfun[13] = 0x00; sendfun[14] = 0x00; sendfun[15] = 0x00; sendfun[16] = 0x80; sendfun[17] = 0x00; sendfun[18] = 0x02; sendfun[19] = 0x00; sendfun[20] = da1; sendfun[21] = 0x00; sendfun[22] = 0x00; sendfun[23] = sa1; sendfun[24] = 0x00; sendfun[25] = 0x01; sendfun[26] = 0x01; sendfun[27] = 0x01; sendfun[28] = datavalue; sendfun[29] = address1; sendfun[30] = address2; sendfun[31] = address3; sendfun[32] = datanum1; sendfun[33] = datanum2; return sendfun; } /// <summary> /// write word /// </summary> /// <param name="da1"></param> /// <param name="sa1"></param> /// <param name="datavalue"></param> /// <param name="address1"></param> /// <param name="address2"></param> /// <param name="address3"></param> /// <param name="datanum1"></param> /// <param name="datanum2"></param> /// <returns></returns> private byte[] setplcvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3, byte datanum1, byte datanum2, int num) { byte[] sendfun = new byte[34]; sendfun[0] = 0x46; sendfun[1] = 0x49; sendfun[2] = 0x4e; sendfun[3] = 0x53; sendfun[4] = 0x00; sendfun[5] = 0x00; sendfun[6] = 0x00; sendfun[7] = (byte)(26 + 2 * num); sendfun[8] = 0x00; sendfun[9] = 0x00; sendfun[10] = 0x00; sendfun[11] = 0x02; sendfun[12] = 0x00; sendfun[13] = 0x00; sendfun[14] = 0x00; sendfun[15] = 0x00; sendfun[16] = 0x80; sendfun[17] = 0x00; sendfun[18] = 0x02; sendfun[19] = 0x00; sendfun[20] = da1; sendfun[21] = 0x00; sendfun[22] = 0x00; sendfun[23] = sa1; sendfun[24] = 0x00; sendfun[25] = 0x01; sendfun[26] = 0x01; sendfun[27] = 0x02; sendfun[28] = datavalue; sendfun[29] = address1; sendfun[30] = address2; sendfun[31] = address3; sendfun[32] = datanum1; sendfun[33] = datanum2; return sendfun; } /// <summary> /// read bit /// /// </summary> /// <param name="da1"></param> /// <param name="sa1"></param> /// <param name="datavalue"></param> /// <param name="address1"></param> /// <param name="address2"></param> /// <param name="address3"></param> /// <param name="datanum1"></param> /// <param name="datanum2"></param> /// <returns></returns> private byte[] getplcvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3) { byte[] sendfun = new byte[34]; sendfun[0] = 0x46; sendfun[1] = 0x49; sendfun[2] = 0x4e; sendfun[3] = 0x53; sendfun[4] = 0x00; sendfun[5] = 0x00; sendfun[6] = 0x00; sendfun[7] = 0x1a; sendfun[8] = 0x00; sendfun[9] = 0x00; sendfun[10] = 0x00; sendfun[11] = 0x02; sendfun[12] = 0x00; sendfun[13] = 0x00; sendfun[14] = 0x00; sendfun[15] = 0x00; sendfun[16] = 0x80; sendfun[17] = 0x00; sendfun[18] = 0x02; sendfun[19] = 0x00; sendfun[20] = da1; sendfun[21] = 0x00; sendfun[22] = 0x00; sendfun[23] = sa1; sendfun[24] = 0x00; sendfun[25] = 0x01; sendfun[26] = 0x01; sendfun[27] = 0x01; sendfun[28] = datavalue; sendfun[29] = address1; sendfun[30] = address2; sendfun[31] = address3; sendfun[32] = 0x00; sendfun[33] = 0x01; return sendfun; } /// <summary> /// write bit /// </summary> /// <param name="da1"></param> /// <param name="sa1"></param> /// <param name="datavalue"></param> /// <param name="address1"></param> /// <param name="address2"></param> /// <param name="address3"></param> /// <returns></returns> private byte[] writeplcbitvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3) { byte[] sendfun = new byte[32]; sendfun[0] = 0x46; sendfun[1] = 0x49; sendfun[2] = 0x4e; sendfun[3] = 0x53; sendfun[4] = 0x00; sendfun[5] = 0x00; sendfun[6] = 0x00; sendfun[7] = 0x1b; sendfun[8] = 0x00; sendfun[9] = 0x00; sendfun[10] = 0x00; sendfun[11] = 0x02; sendfun[12] = 0x00; sendfun[13] = 0x00; sendfun[14] = 0x00; sendfun[15] = 0x00; sendfun[16] = 0x80; sendfun[17] = 0x00; sendfun[18] = 0x02; sendfun[19] = 0x00; sendfun[20] = da1; sendfun[21] = 0x00; sendfun[22] = 0x00; sendfun[23] = sa1; sendfun[24] = 0x00; sendfun[25] = 0x01; sendfun[26] = 0x01; sendfun[27] = 0x02; sendfun[28] = datavalue; sendfun[29] = address1; sendfun[30] = address2; sendfun[31] = address3; return sendfun; } /// <summary> /// set bit /// </summary> /// <param name="da1"></param> /// <param name="sa1"></param> /// <param name="datavalue"></param> /// <param name="address1"></param> /// <param name="address2"></param> /// <param name="address3"></param> /// <returns></returns> private byte[] setplcbitvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3) { byte[] sendfun = new byte[35]; sendfun[0] = 0x46; sendfun[1] = 0x49; sendfun[2] = 0x4e; sendfun[3] = 0x53; sendfun[4] = 0x00; sendfun[5] = 0x00; sendfun[6] = 0x00; sendfun[7] = 0x1b; sendfun[8] = 0x00; sendfun[9] = 0x00; sendfun[10] = 0x00; sendfun[11] = 0x02; sendfun[12] = 0x00; sendfun[13] = 0x00; sendfun[14] = 0x00; sendfun[15] = 0x00; sendfun[16] = 0x80; sendfun[17] = 0x00; sendfun[18] = 0x02; sendfun[19] = 0x00; sendfun[20] = da1; sendfun[21] = 0x00; sendfun[22] = 0x00; sendfun[23] = sa1; sendfun[24] = 0x00; sendfun[25] = 0x01; sendfun[26] = 0x23; sendfun[27] = 0x01; sendfun[28] = 0x01; sendfun[29] = 0x00; sendfun[30] = 0x01; sendfun[31] = datavalue; sendfun[32] = address1; sendfun[33] = address2; sendfun[34] = address3; return sendfun; } /// <summary> /// rst bit /// </summary> /// <param name="da1"></param> /// <param name="sa1"></param> /// <param name="datavalue"></param> /// <param name="address1"></param> /// <param name="address2"></param> /// <param name="address3"></param> /// <returns></returns> private byte[] rstplcbitvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3) { byte[] sendfun = new byte[35]; sendfun[0] = 0x46; sendfun[1] = 0x49; sendfun[2] = 0x4e; sendfun[3] = 0x53; sendfun[4] = 0x00; sendfun[5] = 0x00; sendfun[6] = 0x00; sendfun[7] = 0x1b; sendfun[8] = 0x00; sendfun[9] = 0x00; sendfun[10] = 0x00; sendfun[11] = 0x02; sendfun[12] = 0x00; sendfun[13] = 0x00; sendfun[14] = 0x00; sendfun[15] = 0x00; sendfun[16] = 0x80; sendfun[17] = 0x00; sendfun[18] = 0x02; sendfun[19] = 0x00; sendfun[20] = da1; sendfun[21] = 0x00; sendfun[22] = 0x00; sendfun[23] = sa1; sendfun[24] = 0x00; sendfun[25] = 0x01; sendfun[26] = 0x23; sendfun[27] = 0x01; sendfun[28] = 0x01; sendfun[29] = 0x00; sendfun[30] = 0x00; sendfun[31] = datavalue; sendfun[32] = address1; sendfun[33] = address2; sendfun[34] = address3; return sendfun; } #endregion } }
至此,我們就可以用上述的類(lèi)和歐姆龍plc進(jìn)行fins通訊。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持碩編程。