Python的擴展接口[0] -> VISA儀器控制


VISA儀器控制 / VISA Instrument Control


 

1 VISA簡介 / VISA Introduction

VISA(Virtual Instrument Software Architecture,簡稱為VISA),即虛擬儀器軟件結構,是VXI plug&play聯盟制定的I/O接口軟件標准及其規范的總稱。VISA提供用於儀器編程的標准I/O函數庫,稱為VISA。VISA函數庫駐留在計算機系統內,是計算機與儀器的標准軟件通信接口,計算機通過它來控制儀器。

作為通用I/O標准,VISA提供了統一的設備資源管理、操作和使用機制,它獨立於硬件設備、接口、操作系統和編程語言,具有與硬件結構無關的特點。VISA的這一特性使之適用於各種儀器接口,無論儀器使用的串口還是其他任何一種總線,諸如GPIB、VXI、PXI和LXI等,都具有相同的操作函數,從而實現了控制操作上的統一。Visa基於自底向上的結構模型,創造了一個統一形式的I/O控制函數集。一方面,對初學者或是簡單任務的設計者來說,Visa提供了簡單易用的控制函數集,在應用形式上相當簡單;另一方面,對復雜系統的組建者來說,Visa提供了非常強大的儀器控制功能與資源管理。

2 PyVISA / PyVISA Library

PyVISA是Python的一個包,使Python能夠獨立於接口(如GPIB,RS232,USB,Ethernet)控制各種測量設備。PyVISA極大的簡化了對儀器的控制方式,僅僅需要幾行代碼即可以實現對儀器的操作。

2 PyVISA環境搭建

需要利用Python實現對儀器的控制,首先需要對環境進行相應的配置,基本在於以下幾點,

       1. 確保系統中有visa32.dll文件的存在;

       2. 安裝相應的儀器驅動軟件;

       3. 安裝pyvisa包。

其中,visa32.dll文件一般存放的位置在c:/windows/system32/visa32.dll,而儀器的驅動可到相應官網進行下載,而pyvisa包則可以使用pip進行安裝,

pip install pyvsia 

 

3 PyVISA基本用法

下面介紹一下pyvisa用於儀器控制的基本使用方式,十分簡單,詳細的使用方式可以參考官方說明

  1. 首先導入visa模塊,定義一些基本信息,包括visadll的位置,以及儀器控制方式及其信息,如TCP/IP的IP地址,GPIB的端口號信息等,按照指定格式進行填充。
  2. 接着利用visadll文件創建一個visa的實例對象,有了這個實例對象就可以連接儀器。利用創建的visa對象生成連接實例,此處以GPIB和TCPIP為例。
  3. 利用連接實例就可以開始與儀器進行通信了,通信的接口函數主要有以下3種,write() /read() /query(),具體使用哪一種需要根據每種儀器的通信協議命令集查詢命令的屬性,為寫/讀/讀寫等。有了接口函數就可以利用對應的命令集進行命令的發送。而具體的命令則可以通過相應的儀器手冊進行查詢。
 1 import visa
 2 
 3 visa_dll = 'c:/windows/system32/visa32.dll'
 4 tcp_addr = 'TCPIP::192.168.1.1::inst0::INSTR'
 5 gpib_addr = 'GPIB0::12::INSTR'
 6 
 7 # Create an object of visa_dll
 8 rm = visa.ResourceManager(visa_dll)
 9 
10 # Create an instance of certain interface(GPIB and TCPIP)
11 tcp_inst = rm.open_resource(tcp_addr)
12 gpib_inst = rm.open_resource(gpib_addr)
13 
14 # Command '*IDN?' can fetch instrument info
15 # Using write()/read()/query() function to make communication with device
16 # according to the command type
17 print(tcp_inst.query('*IDN?'))
18 print(gpib_inst.query('*IDN?'))

 

4 PyVISA應用實例

下面是一些在使用pyvisa進行儀器控制時編寫的基本使用實例,可作為使用參考。

Note: 實例中僅僅是實現了一部分需求,若需要完成更多的命令需求,可以參考手冊文件。

4.1 安捷倫E5071C (TCP/IP)

 1 import visa
 2 
 3 class E50X():
 4     def __init__(self, ip, visaDLL=None, *args):
 5         self.ip = ip
 6         self.visaDLL = 'c:/windows/system32/visa32.dll' if visaDLL is None else visaDLL
 7         self.address = 'TCPIP::%s::inst0::INSTR' % self.ip
 8         self.resourceManager = visa.ResourceManager(self.visaDLL)
 9 
10     def open(self):
11         self.instance = self.resourceManager.open_resource(self.address)
12         self.instance.write('MMEM:STOR:SNP:FORM DB')
13 
14     def close(self):
15         if self.instance is not None:
16             self.instance.close()
17             self.instance = None
18 
19     def create_dir(self, path):
20         print('MMEM:MDIR "%s"' % path)
21         self.instance.write('MMEM:MDIR "%s"' % path)
22 
23     def recall_sta(self, filename):
24         print('MMEM:LOAD "%s"' % filename)
25         self.instance.write('MMEM:LOAD "%s"' % filename)
26         # Time sleep in case of sta load uncompleted
27         time.sleep(0.5)
28 
29     def wind_act(self, wind):
30         self.instance.write('DISP:WIND%d:ACT' % wind)
31 
32     def wind_max(self, wind):
33         self.instance.write('DISP:MAX %s' % wind)
34 
35     def trigger(self, status):
36         cmdList = {'hold': 'OFF', 'continuous': 'ON'}
37         self.instance.write('INIT1:CONT %s' % cmdList[status])
38 
39     def save_snp(self, name, n=2):
40         print('MMEM:STOR:SNP "%s.s%dp"' % (name, n))
41         self.instance.write('MMEM:STOR:SNP "%s.s%dp"' % (name, n))
42 
43     def save_image(self, imagname, fmt):
44         assert fmt in ['jpg', 'png'], 'Invalid postfix of image'
45         print('MMEM:STOR:IMAG "%s.%s"' % (imagname, fmt))
46         self.instance.write('MMEM:STOR:IMAG "%s.%s"' % (imagname, fmt))
47 
48     def reset(self):
49         self.instance.write('*RST')
50 
51     def read_idn(self):
52         idn = self.instance.query('*IDN?')
53         print(idn)
54         return idn
55     
56     def read_data(self, wind=1, trac=1, axis='x'):
57         posi = {'x': 'XAX?', 'y': 'FDAT?'}
58         data = self.instance.query('CALC%d:TRAC%d:DATA:%s' % (wind, trac, posi[axis]))
59         return eval(data)
60     
61     def tran_file(self):
62         re = self.instance.query(":MMEM:TRAN? 'D:\\22.S2P'")
63         with open("x.S2P", 'w') as f:
64             f.write(re)
65         print(type(re))
66 
67 if __name__ == '__main__':
68     e50 = E50X('192.168.1.17')
69     e50.open()
70     e50.read_idn()
71     e50.tran_file()
72     e50.close()

 

4.2 安捷倫C34970A (GPIB)

 1 import visa
 2 
 3 class A34X():
 4     def __init__(self):
 5         self.address = 'GPIB0::8::INSTR'
 6         self.visaDll = 'c:/windows/system32/visa32.dll'
 7         self.resourceManager = visa.resourceManager(self.visaDll)
 8     def open(self):
 9         self.instance = resourceManager.open_resource(self.address)
10         self.idn = self.instance.query('*IDN?')
11         print(self.idn)
12 
13     def reset(self):
14         self.instance.write('*RST')
15 
16     def set_dc(self):
17         self.instance.write('CONF:CURR:DC AUTO, (@119, 120)')

 

參考鏈接

 


http://pyvisa.readthedocs.io/en/stable/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM