董云龍
(遼寧省廣播電視錦州中波站,遼寧 錦州 121000)
配電柜上的數(shù)顯式智能電表通過(guò)對(duì)配電柜內(nèi)部三相電壓、三相電流進(jìn)行采樣分析,可以在面板上顯示每相的電壓、電流、有功功率、無(wú)功功率、視在功率、功率因數(shù)、交流頻率、消耗的正負(fù)有功電能以及消耗的正負(fù)無(wú)功電能等信息。市面上的電表雖然型號(hào)不同,但是大都遵循行業(yè)標(biāo)準(zhǔn),均采用RS485接口和Modbus協(xié)議,輸出的監(jiān)測(cè)數(shù)據(jù)大同小異。
在數(shù)據(jù)通信、計(jì)算機(jī)網(wǎng)絡(luò)以及分布式工業(yè)控制系統(tǒng)中,經(jīng)常采用串行通信來(lái)達(dá)到信息交換的目的,常見(jiàn)的串行接口標(biāo)準(zhǔn)有RS232、RS422以及RS485等[1]。RS422接口使用A+、A-、B+、B-兩兩差分的4根線,收發(fā)具備獨(dú)立的信道,支持全雙工通信,適用于星型網(wǎng)、環(huán)形網(wǎng)。RS485接口只有A、B收發(fā)共用的兩根差分信號(hào)線,只能支持半雙工通信,便于在多設(shè)備連接的場(chǎng)合使用,可以省掉許多信號(hào)線。
Modbus協(xié)議是Modicon公司推出的一種開(kāi)放式現(xiàn)場(chǎng)總線通信協(xié)議,目前已經(jīng)成為工業(yè)自動(dòng)化網(wǎng)絡(luò)協(xié)議規(guī)范[2]。通過(guò)Modbus協(xié)議,不同廠商生產(chǎn)的監(jiān)測(cè)設(shè)備和控制設(shè)備可以與工業(yè)網(wǎng)絡(luò)互聯(lián),實(shí)現(xiàn)集中監(jiān)控。Modbus協(xié)議描述的是控制器如何請(qǐng)求訪問(wèn)其他設(shè)備,其他設(shè)備如何回應(yīng)來(lái)自控制器的請(qǐng)求、檢測(cè)錯(cuò)誤等。Modbus協(xié)議定義了消息結(jié)構(gòu),而未定義物理層,不限定經(jīng)過(guò)何種網(wǎng)絡(luò)進(jìn)行通信。Modbus可以在雙絞線、光纖、無(wú)線等多種介質(zhì)上傳輸,支持RS232、RS485等多種電氣接口,目前最常見(jiàn)的是RS485接口[3]。
系統(tǒng)選用了全功能三合一隔離型以太網(wǎng)串口轉(zhuǎn)換設(shè)備NETCOM-100IE,通過(guò)后臺(tái)設(shè)置可選擇工作在TCP-Server、TCP-Client或者組播模式,通過(guò)撥碼選擇可以將RS232、RS422、RS485標(biāo)準(zhǔn)的DB-9串行接口轉(zhuǎn)為RJ45網(wǎng)絡(luò)接口,并接入交換機(jī)或路由器,利用以太網(wǎng)的特性擴(kuò)大了數(shù)據(jù)的傳輸和接收范圍。通過(guò)查詢智能電表的說(shuō)明書(shū)或用戶手冊(cè),獲取智能電表的設(shè)置方法。系統(tǒng)采用三相四線連接方式,RS485接口的硬件地址為0001,波特率為9 600 Baud/s,傳輸幀結(jié)構(gòu)為8個(gè)數(shù)據(jù)位、1個(gè)停止位、0個(gè)校驗(yàn)位。首先在串行數(shù)據(jù)接口-以太網(wǎng)接口轉(zhuǎn)換器(以下簡(jiǎn)稱串以轉(zhuǎn)換器)的網(wǎng)頁(yè)設(shè)置界面,設(shè)定IP地址、子網(wǎng)掩碼、端口號(hào)。其次在計(jì)算機(jī)的網(wǎng)卡屬性界面,設(shè)定控制計(jì)算機(jī)的IP地址與串以轉(zhuǎn)換器在同一個(gè)子網(wǎng)段。最后用網(wǎng)線將串以轉(zhuǎn)換器的RJ45接口與控制計(jì)算機(jī)相連,即可通過(guò)“IP:port”方式與智能電表建立通信連接[4]。
Python是當(dāng)下流行的開(kāi)源腳本編程語(yǔ)言,支持Windows、Unix、Linux、Android等多種操作系統(tǒng)平臺(tái),網(wǎng)絡(luò)編程友好,操作套接字語(yǔ)法簡(jiǎn)潔、易讀易用。Python內(nèi)置Socket套接字模塊,可以實(shí)現(xiàn)與串以轉(zhuǎn)換器的數(shù)據(jù)交換。其Print函數(shù)可以實(shí)現(xiàn)數(shù)據(jù)處理、進(jìn)制轉(zhuǎn)換以及格式化輸出,Tkinter模塊可以制作圖形界面。
Modbus協(xié)議有兩種通信模式,即美國(guó)信息交換標(biāo)準(zhǔn)編碼(American Standard Code for Information Interchange,ASCII)模式和遠(yuǎn)程終端設(shè)備(Remote Terminal Unit,RTU)模式。ASCII模式是將一個(gè)字節(jié)分為兩個(gè)ASCII字符發(fā)送,而RTU模式以十六進(jìn)制傳送數(shù)據(jù),其數(shù)據(jù)傳送效率高于ASCII模式[5]。本系統(tǒng)選用RTU模式,其幀結(jié)構(gòu)為8 bit地址碼+8 bit功能碼+N×8 bit數(shù)據(jù)段+16 bit校驗(yàn)碼。地址碼是用戶設(shè)定的設(shè)備地址,每個(gè)設(shè)備地址唯一,計(jì)算機(jī)通過(guò)地址碼與智能電表建立通信連接。當(dāng)智能電表收到的地址碼與自身的設(shè)定相同時(shí)才能返回響應(yīng)數(shù)據(jù),返回的地址碼為智能電表硬件地址。本系統(tǒng)智能電表硬件地址設(shè)定為0001,地址碼為0x01。功能碼表示計(jì)算機(jī)要求智能電表執(zhí)行何種操作,如0x01為讀開(kāi)關(guān)量輸出狀態(tài)、0x02為讀開(kāi)關(guān)量輸入狀態(tài)、0x03為讀寄存器、0x05為寫(xiě)開(kāi)關(guān)量輸出(遙控)、0x06為寫(xiě)單路寄存器以及0x10為寫(xiě)多路寄存器等。不同廠家的產(chǎn)品對(duì)功能碼的定義有差別,使用之前需要查詢說(shuō)明書(shū)或用戶手冊(cè)確認(rèn)。目前最常用的功能碼為0x03,即當(dāng)計(jì)算機(jī)查詢儀表和設(shè)備狀態(tài)時(shí)就向Modbus-RTU總線上發(fā)出0x03功能碼。
數(shù)據(jù)段是請(qǐng)求或響應(yīng)的數(shù)據(jù),計(jì)算機(jī)向智能電表發(fā)送指令的數(shù)據(jù)段包括讀取寄存器的硬件起始地址和讀取寄存器的數(shù)量,智能電表收到指令并向計(jì)算機(jī)返回響應(yīng)的數(shù)據(jù)段包括數(shù)據(jù)長(zhǎng)度和實(shí)際采集的數(shù)據(jù)。寄存器是電表采集和存放數(shù)據(jù)的地方,通常內(nèi)部寄存器存儲(chǔ)的信息依次為儀表參數(shù)、三相相電壓采樣、三相線電壓采樣、三相電流采樣、三相有功功率、總有功功率、三相無(wú)功功率、總無(wú)功功率、三相視在功率、總視在功率、三相功率因數(shù)、總功率因數(shù)、總有功電能、正有功電能、負(fù)有功電能、總無(wú)功電能、正無(wú)功(感性)電能、負(fù)無(wú)功(容性)電能以及開(kāi)關(guān)量狀態(tài)等[6]。
通過(guò)加載Python語(yǔ)言的Socket模塊,建立計(jì)算機(jī)與串以轉(zhuǎn)換器(192.168.1.140:4001)的連接,通過(guò)串以轉(zhuǎn)換器的RJ45接口與智能電表的RS485接口上的Modbus協(xié)議進(jìn)行通信。具體程序?yàn)椋?/p>
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #構(gòu)造TCP套接字s
s.connect(("192.168.1.140", 4001)) #套接字s連接串以轉(zhuǎn)換器IP和端口
r = s.recv(1024) #接收串以轉(zhuǎn)換器發(fā)送的連接成功建立的握手信息
print(r) #以16進(jìn)制方式顯示2進(jìn)制數(shù)據(jù)流,1個(gè)字節(jié)用兩個(gè)16進(jìn)制符號(hào)輸出顯示
系統(tǒng)連接正確時(shí),運(yùn)行以上程序,可以在計(jì)算機(jī)接收到串以轉(zhuǎn)換器輸出的握手信息。為了加快數(shù)據(jù)讀取、處理以及顯示,本系統(tǒng)一次性讀取智能電表的所有寄存器,并提取其中有用的部分?jǐn)?shù)據(jù)段。設(shè)定儀表的硬件通信地址為0001,則程序中儀表的地址碼為0x01,讀取儀表的操作指令碼為0x03,儀表內(nèi)部寄存器的起始地址為0x00,則讀取電表地址0x01起始寄存器0x00數(shù)據(jù)長(zhǎng)度0x00 0x63(99)的指令為0x01 0x03 0x01 0x00 0x00 0x63。
計(jì) 算(010300000063)16的 CRC-16/Modbus為(E305)16(高位在前),根據(jù)Modbus通信協(xié)議,循環(huán)冗余校驗(yàn)碼(Cyclic Redundancy Check,CRC)為低8位寫(xiě)在前,即0x05 0xE3,則使用Python讀取電表的指令為:
s.send(b'x01x03x00x00x00x63x05xe3') #讀寄存器指令
r = s.recv(1024) #接收電表響應(yīng)數(shù)據(jù)
經(jīng)過(guò)查閱,某品牌智能電表返回?cái)?shù)據(jù)中第19~22字節(jié)為B相電壓值,第31~34字節(jié)為C相電流值,第39~42字節(jié)為A相的有功功率值,第59~62字節(jié)為B相的無(wú)功功率值,第79~82字節(jié)為C相的視在功率值,第99~102字節(jié)為總功率因數(shù)值,第103~106字節(jié)為交流電頻率。利用Python提取、處理、顯示的程序?yàn)椋?/p>
ub = int.from_bytes(r[19:23], byteorder='big')/1000 #無(wú)電壓互感器直接采樣
ic =int.from_bytes(r[31:35],byteorder='big')*80/1000 #400/5A電流互感
pa = int.from_bytes(r[39:43], byteorder='big',signed=True) #帶符號(hào)數(shù)
qb = int.from_bytes(r[59:63], byteorder='big',signed=True) #帶符號(hào)數(shù)
sc = int.from_bytes(r[79:83], byteorder='big') #無(wú)符號(hào)數(shù)
cos D =int.from_bytes(r[99:103],byteorder='big')/1000 #無(wú)符號(hào),修正為小數(shù)
f = int.from_bytes(r[103:107], byteorder='big')/1000#無(wú)符號(hào),修正為小數(shù)
其中:r[59:63]是提取接收數(shù)據(jù)r的第59、60、61、62字節(jié)的16進(jìn)制數(shù)據(jù);byteorder='big'是指定以高位在前的數(shù)據(jù)讀取方式將16進(jìn)制數(shù)據(jù)默認(rèn)轉(zhuǎn)換為不帶符號(hào)的10進(jìn)制數(shù)據(jù);signed=True是指定轉(zhuǎn)換為10進(jìn)制帶符號(hào)的數(shù)據(jù),避免數(shù)據(jù)中以補(bǔ)碼方式表示的負(fù)數(shù)出現(xiàn)轉(zhuǎn)換錯(cuò)誤。利用Python語(yǔ)法print('%.2f' %ia)四舍五入并保留兩位小數(shù)格式化輸出數(shù)據(jù),作為全局變量供給程序其他部分使用。
在Python語(yǔ)法中使用While True結(jié)構(gòu)讓程序持續(xù)運(yùn)行,通過(guò)try except結(jié)構(gòu)抓取并處理程序運(yùn)行中的錯(cuò)誤信息,使用time模塊和time.sleep(n)函數(shù)控制控制程序讀取電表數(shù)據(jù)的時(shí)間間隔為n秒。
通過(guò)Python語(yǔ)言中的tkinter模塊制作同時(shí)兼容Windows、Linux、Unix和Android等操作系統(tǒng)的可視化界面,顯示從電表獲取的各項(xiàng)數(shù)據(jù)。與此同時(shí),采用if邏輯結(jié)構(gòu)監(jiān)測(cè)并判斷數(shù)據(jù)的變化范圍,從而實(shí)現(xiàn)對(duì)配電柜的實(shí)時(shí)監(jiān)測(cè)。當(dāng)數(shù)據(jù)變化超過(guò)設(shè)定的允許范圍時(shí),程序輸出用于報(bào)警的開(kāi)關(guān)量信號(hào),控制報(bào)警系統(tǒng)本地計(jì)算機(jī)進(jìn)行聲像報(bào)警。通過(guò)結(jié)合全球移動(dòng)通信系統(tǒng)(Global System for Mobile Communication,GSM)模塊或者微信云服務(wù),還可以實(shí)現(xiàn)遠(yuǎn)程監(jiān)測(cè)和報(bào)警功能。
由于Modbus協(xié)議被眾多儀表廠家支持,并且RS485接口支持單總線上連接多個(gè)設(shè)備,因此結(jié)合Python這種跨平臺(tái)的腳本語(yǔ)言開(kāi)發(fā)支持多平臺(tái)、多設(shè)備的遠(yuǎn)程電力監(jiān)測(cè)和報(bào)警系統(tǒng),不但可以豐富技術(shù)人員的知識(shí)結(jié)構(gòu),而且有利于節(jié)約企事業(yè)單位的運(yùn)營(yíng)成本。