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