萬偉軍
(江蘇聯(lián)合職業(yè)技術(shù)學(xué)院 無錫機(jī)電分院,江蘇 無錫 214000)
目前,工業(yè)網(wǎng)絡(luò)通信程序多采用C#編寫,以實現(xiàn)上位機(jī)與智能模塊建立的通信。Python語言具備簡單易懂的編寫模式和功能齊全的擴(kuò)展庫,易于實現(xiàn)工業(yè)網(wǎng)絡(luò)通信程序的編寫。
智能IO模塊采用意法半導(dǎo)體公司的STM32F407為控制核心,可實現(xiàn)16位輸入信號采集和7位輸出控制。輸入/輸出電路采用EL357NC進(jìn)行信號隔離,以保證模塊工作穩(wěn)定。同時,智能IO模塊采用MAX1487芯片實現(xiàn)串口通信,通過ARM程序?qū)崿F(xiàn)主從設(shè)備間的RS485通信。該智能模塊可代替PLC的基本功能,通過內(nèi)部ARM較靈活的程序開發(fā)功能實現(xiàn)設(shè)備的智能化,并降低設(shè)備制造成本。
Python語言具有功能強(qiáng)大的第三方開發(fā)的庫文件,可實現(xiàn)網(wǎng)絡(luò)通信、界面顯示等功能。Python功能庫中可實現(xiàn)的Modbus通信協(xié)議有Modbus_tk、Pymodbus及Minimalmodbus。本文使用Modbus_tk庫實現(xiàn)上位機(jī)與智能模塊間的數(shù)據(jù)交換[1]。
Modbus_tk庫是一個全功能Modbus的Python擴(kuò)展庫,通過調(diào)用內(nèi)部函數(shù)實現(xiàn)Modbus通信。Python的Modbus_tk庫函數(shù)與Modbus協(xié)議部分功能碼之間的對應(yīng)關(guān)系,如表1所示。
通信本質(zhì)上,Modbus是一種串口通信,主從設(shè)備間進(jìn)行通信前必須建立鏈接。使用Modbus_tk庫文件建立通信關(guān)系的程序,如下:
def connect():
logger=modbus_tk.utils.create_logger( "console ")
master=modbus_rtu.RtuMaster(serial.Serial(port= "C OM3 ",baudrate=19200,bytesize=8,parity= "N ",stopbits=1,xo nxoff=0))
master.set_timeout(5.0)
表1 Modbus功能碼與Python的Modbus_tk庫函數(shù)對照表
master.set_verbose(True)
logger.info( "connected ")
此程序中,通過modbus_rtu.RtuMaster()函數(shù)設(shè)定了串口、波特率及字節(jié)長度等。執(zhí)行此程序,主從設(shè)備之間建立了通信關(guān)系,后續(xù)程序只需調(diào)用功能函數(shù)就能實現(xiàn)對應(yīng)功能[2]。
為實現(xiàn)輸入信號的顯示與輸出控制,可使用Python的tkinter進(jìn)行GUI開發(fā)。為實現(xiàn)輸入信號顯示與標(biāo)簽,可使用Label控件。程序如下:
photo_r=PhotoImage(f i le= "r.gif ")
photo_y=PhotoImage(f i le= "y.gif ") #加載顯示圖片
lab0=Label(root,text= "X0 ")
lab0.place(x=10,y=10) #創(chuàng)建X0標(biāo)簽文字
label_x0=Label(root,image=photo_y)
label_x0.place(x=10,y=30) #X0無輸入時,顯示黃色指示燈
def input_x(): #輸入檢測與顯示程序函數(shù)input_x()
connect() #使用connect()函數(shù)建立主從設(shè)備通信鏈接
logger.info(master.execute(1,cst.READ_DISCRETE_INPUTS,0,16))
in_x=master.execute(1,cst.READ_DISCRETE_INPUTS,0,16)
If in_x[0]==1: #判斷X0是否有輸入,有輸入顯示紅燈,沒輸入顯示黃燈
label_x0.conf i g(imag=photo_r) #顯示紅燈
else:
label_x0.conf i g(imag=photo_y) #顯示黃燈
在master.execute(1,cst.READ_DISCRETE_INPUTS,0,16)語句中,master.execute()函數(shù)內(nèi)部參數(shù)的具體含義,如圖1所示。
圖1 master.execute()函數(shù)內(nèi)部參數(shù)的具體含義
模塊地址由每個智能IO模塊的內(nèi)部ARM設(shè)定。本功能指令是讀取Modbus離散輸入量,讀取地址從0開始,共讀取16位數(shù)據(jù)。為保證實時讀取輸入數(shù)據(jù),程序必須間隔一定時間執(zhí)行input_x()函數(shù)。函數(shù)調(diào)用可采用多線程定時方式,也可使用Python的APScheduler定時任務(wù)框架。
為實現(xiàn)交互界面,輸出控制程序可采用tkinter的Checkbutton控件??刂瞥绦蛉缦拢?/p>
global y0
y0=IntVar() #創(chuàng)建變量y0
def y_out(): #輸處控制程序函數(shù)y_out()
connect() #使用connect()函數(shù)建立主從設(shè)備通信鏈接
logger.info(master.execute(1,cst.WRITE_SINGLE_COIL,0, output_value=y0.get())
#創(chuàng)建復(fù)選按鈕ck,并設(shè)定其屬性,y0變量存儲復(fù)選按鈕設(shè)定值,同時調(diào)用y_out函數(shù)
ck=Checkbutton(text= "y0 ",variable=y0,command=y_out)
ck.place(x=10,y=120)
在logger.info(master.execute(1,cst.WRITE_SINGLE_COIL,0,output_value=y0.get()))語 句 中,master.execute()函數(shù)內(nèi)部參數(shù)的具體含義,如圖2所示。
圖2 master.execute()函數(shù)內(nèi)部參數(shù)的具體含義圖
模塊地址由每個智能IO模塊的內(nèi)部ARM設(shè)定。本功能指令是執(zhí)行Modbus內(nèi)部單線圈狀態(tài)設(shè)定功能。單線圈地址確定了智能IO模塊的輸出口位置,即y0口。單線圈狀態(tài)值由復(fù)選按鈕設(shè)定值決定。復(fù)選按鈕被選中,設(shè)定值為1;復(fù)選按鈕未被選中,設(shè)定值為0。執(zhí)行此程序,當(dāng)Python編寫的GUI界面中的復(fù)選按鈕被選中時,智能IO模塊的y0口導(dǎo)通[3]。
本文采用Python的Modbus_tk庫實現(xiàn)智能IO模塊與上位機(jī)之間的數(shù)據(jù)通信,語言簡潔易懂,且Python擴(kuò)展庫功能強(qiáng)大,可簡單實現(xiàn)各種工業(yè)控制功能。