NI-VISA這是一種美國的一家公司的協議,主要用來和儀器通信,當然這只是一種通信的格式,具體的操作我們還是要參照示波器的說明書。
我們直接采用Python里面自帶的NI—VISA庫文件。pip install pyvisa,然后安裝好NI-VISA的驅動,百度到官網即可下載安裝。
通過VISA發送相應命令(示波器編程文檔有命令集)即可完成對示波器的控制,並且通過VISA可以接收返回值,比如波形數據等。
這里是通過USB來與示波器通信
1 rm = visa.ResourceManager() 2 # res = rm.list_resources() 3 # print(rm) 4 # print(res) 5 self.inst = rm.open_resource('USB0::0x0699::0x0528::C019161::INSTR')
第一行是得到visa資源管理器,第二行的res會是返回當前與電腦連接的端口地址,采用print()將其打印出來即可看到你的示波器地址。然后就可以注釋掉了,然后使用第五行的代碼即可打開示波器通信通道。
源碼如下:
1 import matplotlib.pyplot as plt 2 import visa 3 import time 4 from datetime import datetime # std library 5 6 class Tektronix_MSO64: 7 def __init__(self): 8 visa_dll = 'c:/windows/system32/visa32.dll' 9 self.rm = visa.ResourceManager() 10 # res = rm.list_resources() 11 # print(rm) 12 # print(res) 13 self.inst = self.rm.open_resource('USB0::0x0699::0x0528::C019161::INSTR') 14 ############################################## 15 self.inst.write("*IDN?") 16 print(self.inst.read()) 17 self.inst.write('CLEAR') 18 self.inst.write('ACQuire:MODe?') 19 print(self.inst.read()) 20 self.inst.timeout = 25000 21 self.inst.write('ACQUIRE:STOPAFTER RUNSTOP') 22 self.inst.write('ACQuire:STATE RUN') 23 24 25 def set_HORIZONTAL(self,POSITION,SCALE):#HORIZONTAL position,HORIZONTAL scale /us 26 self.inst.write('HORIZONTAL:POSITION %s'%POSITION) 27 self.inst.write('HORIZONTAL:SCALE %se-6'%SCALE) 28 29 def open_ch(self,ch):#關閉相應通道 30 self.inst.write('DISplay:GLObal:CH%s:STATE ON'%ch) 31 32 def close_ch(self,ch):#打開相應通道 33 self.inst.write('DISplay:GLObal:CH%s:STATE OFF'%ch) 34 35 def vertical_ch(self,ch,scale,position):#通道,ch scale/mv,ch POSition, 36 self.inst.write('CH%s:BANDWIDTH FULl'%ch)#at its maximum bandwidth 37 self.inst.write('CH%s:SCAle %sE-3'%(ch,scale)) 38 self.inst.write('CH%s:POSition %s'%(ch,position)) 39 self.inst.write('CH%s:COUPLING DC'%ch)#直流 40 self.inst.write('CH%s:TERMINATION 10.0E+5'%ch)#1兆歐 41 42 def trigger_set(self,ch,level):#通道,觸發電壓 43 self.inst.write('TRIGGER:A:EDGE:COUPLING DC')#邊沿觸發 44 self.inst.write('TRIGGER:A:EDGE:SOURCE CH%s'%ch) 45 self.inst.write('TRIGGER:A:EDGE:SLOPE RISE')#上升沿觸發 46 self.inst.write('TRIGGER:A:LEVEL:CH4 %s'%level) 47 48 def begin_trigger(self):#開啟一次觸發 49 self.inst.write('ACQuire:STOPAfter SEQuence') 50 while 1:#等觸發了才借宿 51 time.sleep(1) 52 self.inst.write('TRIGGER:STATE?') 53 TRIGGER_STATE =self.inst.read() 54 if TRIGGER_STATE[0] == "S": 55 print('have triggered') 56 break 57 58 def data_caul(self,ch):#通道 59 self.inst.write('DATA:SOURCE CH%s'%ch) 60 self.inst.write('DATa:ENCdg ASCIi') 61 self.inst.write('WFMOUTPRE:BYT_NR 4') 62 self.inst.write('DATA:START 1') 63 self.inst.write('DATA:STOP 250e6') 64 self.inst.write('WFMOUTPRE?') 65 preamble= self.inst.read() 66 #獲取HORIZONTAL:POSITION 67 self.inst.write('HORIZONTAL:POSITION?') 68 HORIZONTAL_p=self.inst.read() 69 HORIZONTAL_pfloat=float(HORIZONTAL_p) 70 #獲取HORIZONTAL:SCALE 71 self.inst.write('HORIZONTAL:SCALE?') 72 HORIZONTAL_S=self.inst.read() 73 HORIZONTAL_Sfloat=float(HORIZONTAL_S) 74 #獲取ch POSition 75 self.inst.write('CH%s:POSition?'%ch) 76 divus_str = self.inst.read() 77 divus_float = float(divus_str) 78 #獲取ch SCAle 79 self.inst.write('CH%s:SCAle?'%ch) 80 div_str = self.inst.read() 81 div_float = float(div_str) 82 #########################################################獲取采樣點數目 83 j=0 84 point_str=' ' 85 for i in range(0,len(preamble)): 86 if preamble[i]==',': 87 j+=1 88 elif j==4: 89 point_str=point_str+preamble[i] 90 elif j==5: 91 point_len=len(point_str) 92 point_str=point_str[2:(point_len-6)] 93 break 94 point_int=int(point_str) 95 print('point_num:%d'%point_int) 96 ######################################################數據處理 97 data = self.inst.query('CURVE?') 98 x = [] 99 dat = [' '] 100 dat1 = [] 101 j = 0 102 for i in range(0, len(data)): 103 if data[i] == ',': 104 dat1.append(float(dat[j])/32000*div_float*5-div_float*divus_float) 105 x.append((int(j)/point_int*HORIZONTAL_Sfloat*10-HORIZONTAL_Sfloat*10*HORIZONTAL_pfloat/100)) 106 j += 1 107 dat.append(' ') 108 else: 109 dat[j] = dat[j] + data[i] 110 plt.plot(x, dat1) 111 112 def close(self): 113 self.inst.close() 114 self.rm.close() 115 116 def get_screen(self): 117 self.inst.write('SAVE:IMAGE "E:/waveform_screen.bmp"') 118 time.sleep(1) 119 self.inst.write('FILESYSTEM:READFILE "E:/waveform_screen.bmp"') 120 img = self.inst.read_raw() 121 dt = datetime.now() 122 fileName = dt.strftime("%Y%m%d_%H%M%S.bmp") # 以當前時間建立文件名 123 imgFile = open('./waveform/' + fileName, "wb") # 打開圖片文件,如果沒有就會新建一個 124 imgFile.write(img) 125 imgFile.close() 126 self.inst.write('FILESYSTEM:DELETE "E:/waveform_screen.bmp"') 127 128 129 130 131 132 if __name__ == "__main__": 133 fig = plt.figure() 134 my=Tektronix_MSO64() 135 my.set_HORIZONTAL(10,200) 136 my.open_ch(4) 137 my.open_ch(3) 138 my.open_ch(2) 139 my.open_ch(1) 140 my.vertical_ch(4,2000,1) 141 my.vertical_ch(3,2000,2) 142 my.vertical_ch(2,2000,2) 143 my.vertical_ch(1,2000,2) 144 my.trigger_set(4,2) 145 my.begin_trigger() 146 my.data_caul(4) 147 my.data_caul(3) 148 my.data_caul(2) 149 my.data_caul(1) 150 my.get_screen() 151 plt.show() 152 my.close()
根據示波器編程文檔,通過visa發送相應命令,接收相應返回值即可完成對示波器的控制,獲取數據等,具體命令可以參考相應的編程文檔。
此代碼具有以下功能:
設置水平軸相關設置;
設置通道相關設置;
打開,關閉相應通道;
設置觸發;
開啟一次觸發;
獲取波形數據,並處理數據,然后通過plot()顯示出來;
獲取截屏圖片,保存到pc本地;