2018年5月30日
上文提到了Python在進行數據處理方面的便利,與LabVIEW在儀器通信方面的廣泛應用。結合兩者的優勢,可以方便實現高靈活性的功能,此時,實現兩者進程間的通信就顯得格外重要。實現Python與LabVIEW間的數據傳輸有許多種不同方法,這里將采用簡單的UDP通信來交換數據,Python與LabVIEW分別作為客戶端與服務端工作,下面以一個測量激光器實際功率的簡單程序來說明Python與LabVIEW結合的強大。
實驗背景
進行實驗分析時需要得知激光器在不同設定電流下的光功率,需要對激光器設定一系列電流值,然后記錄功率計測量得到的光功率。
功能分析
主要功能分為兩部分,一部分為設定電流值與記錄光功率,另一部分為UDP通信。
設定電流值可以簡單粗暴的使用pywinauto庫與keyboard庫來實現,步驟為1、pywinauto選擇窗口并最大化,2、keyboard輸入電流值。紀錄光功率需要連接功率計,此處通過LabVIEW的VISA資源與功率計通信,然后調用測量光功率的子VI得到功率值。這兩塊的功能通過調用Python和LabVIEW各自的庫函數可以實現,出于頁面簡潔的理由這部分代碼就省略了,僅僅展示UDP通信部分。
UDP通信部分僅需要實現簡單的數據通信功能,Python部分使用sendto()
與recvfrom()
;LabVIEW部分首先打開選定端口號的UDP服務,然后調用讀取UDP與寫入UDP的子VI。
總體的工作流程圖如下:
需求實現
本例中,Python和LabVIEW兩部分的功能都十分簡單,所以在各自UDP通信的示例上稍作修改就可以滿足要求,首先是Python部分的代碼:
import signal
import threading
import sys
import socket
# 創建Socket,SOCK_DGRAM指定了這個Socket的類型是UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口:
s.bind(('127.0.0.1', 61557))
# 設置接收超時,此時間應大于服務端完成一次采樣的時間
s.settimeout(1)
print('Bind UDP on 61557...')
# 定義按下Ctrl+C時退出的處理
def client_exit(num, frame):
print("退出數據收集")
s.close() # 關閉Socket
sys.exit(0)
signal.signal(signal.SIGINT, client_exit) # 對于KeyboardInterrupt的handlder處理
exit = threading.Event() # 創建一個event
while not exit.is_set(): # 當exit事件沒有set時,循環運行
s.sendto(b'Client ready.',('127.0.0.1', 61556)) # 向服務端發送數據
try:
data, addr = s.recvfrom(1024) # 接收服務端發送的數據
print('Received from %.4e:%s.' % (float(data),addr))
except socket.timeout:
pass
代碼相對直觀,while
循環前都是一些對象的初始化過程,while
循環中包括了客戶端發送準備信號和接收服務端數據的socket
函數,在接收到服務端發送的data
數據之后就可以進行相應處理了。像本例中就是通過while
循環遍歷包含不同設定電流的列表,然后在單次循環中從LabVIEW服務端接收得到電流對應的光功率,存儲在對應的光功率列表中,最后就實現了掃描記錄光功率的功能。
另外是LabVIEW部分的代碼,基本上也是在LabVIEW自帶的UDP通信示例上稍作修改得到的。LabVIEW服務端運行在循環中,當接收到Python客戶端發送的數據時開始采集數據,這里調用的VI是光功率計單次測量功率的VI(PM100D Measure Power.vi),也可以改成別的VI例如產生隨機數,采集完成后將得到的浮點數轉化為字符串,通過UDP發送回Python客戶端。
當客戶端沒有發送數據時,忽略超時錯誤,繼續循環。
此時先開始運行LabVIEW服務端,然后運行Python客戶端,就可以實現兩者間的進程通信,在LabVIEW端和Python端可以看到相互發送的字符串。
參考:
1、UDP編程-廖雪峰的官方網站:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432004977916a212e2168e21449981ad65cd16e71201000
2、LabVIEW示例:SimpleUDP
全文完