天天看點

上位機使用python/matlab通過網線VISA/SCPI程式設計遠端控制舊版A.06.04.32的安捷倫agilent矢量網絡分析儀(VNA)采集S21參數

       近日需要通過上位機連接配接矢網采數,但是可用的矢網隻有一個零幾年的矢網安捷倫 agilent e8363b。一開始想使用labview,但是使用NI MAX控制不成功(問題在instrument VISA Address),隻好自己從底層控制(如果你的NI MAX能成功,可以直接使用labview控制呢)。本來想通過GPIB來控制,但是實驗室沒有GPIB轉USB的線。一看矢網上有網口,故準備通過網絡來控制矢網。經過一番摸索,成功地使用matlab和python通過SCIP協定來用網線控制矢網采數。(如果你熟悉VB的話,請參考VB的例子。VB的資料明顯更多。)

下面對控制過程進行記錄以留待後續查閱。

  • 檢視自己矢網固件版本!在矢網應用中是可以看到的。
  • 檢視矢網設定,注意看是否一直有SCPI支援,注意看設定的内網IP。
  • 安裝 Keysight IO library suite。
  • 安裝Keysight Command Expert 用于檢測矢網連接配接是否成功。
  • 使用python的話安裝pyvisa(pip install 即可)。
  • 使用matlab要安裝對應驅動和庫。自行下載下傳安裝。
    • matlab的例子參看Two Port S-Parameter Measurement(matlab file exchange)或者Characterizing a low-noise amplifier by measuring its S-parameters。文中注釋寫得非常詳細。請注意一段話。
      • This MATLAB example connects to and configures a Keysight (Agilent) PNA (N5222A) to measure the S-parameters of a low noise amplifier (LNA). The instrument used in this example is running firmware version A.09.90.02. The Standard Commands for Programmable Instruments (SCPI) for the PNA in this example may need to be modified if you are using a different instrument or firmware. The SCPI command set for most instruments is available in the instrument programmer's manual from your instrument vendor.
      • 固件版本非常重要。例程中的版本是A09.90.02的(我的是06年的一個版本A.06.04.32)。不同的版本支援的SCPI文法是有差異的。具體可以看各個公司的程式設計手冊——這個網上都可以搜尋得到。
  • 連接配接網線,設定上位機IP使之與矢網處于同一個子網,使用ping指令檢測聯通性。
  • 使用command expert 檢測是否能夠識别。注意建立instrument連接配接的時候如果不能自動識别裝置,需要手動添加其名字,比如我這台的格式是這樣的
    • instrumentVISAAddress = 'TCPIP0::192.168.1.10::hpib7,16::INSTR'
    • 注意中間有個hpib7,16 。可以使用手動輸入的方式來連接配接這台裝置。IP是你矢網的IP。
    • matlab官方 網站上的例子的格式是這樣的 instrumentVISAAddress = 'TCPIP0::127.0.0.1::inst0::INSTR'。注意二者的差別
  • 在command expert 能檢測到你的裝置之後,你就可以自行程式設計了。此時你可以使用NI MAX+LABVIEW(如果能成功識别的話),否則就隻有自己用VB VC PYTHON MATLAB等按照VISA/SCPI來程式設計了(就是我所走的路)。
  • 下面是個matlab控制采數的例子。
    • %% 在官方的matlab例程上安裝對應固件版本的程式設計手冊修改的
      instrumentVISAAddress = 'TCPIP0::192.168.1.10::hpib7,16::INSTR';
      % Define frequency range  
      frequencyRange = [f1 f2];% 起始頻率
      % Number of points in measurement
      numPoints = NN; 
      
      
      
      instrObj = visa('agilent',instrumentVISAAddress); % 創立連結。
      instrObj.InputBufferSize = 10e6;% set buffer
      instrObj.ByteOrder = 'littleEndian';
      fopen(instrObj);
      clrdevice(instrObj); % clear 
      % Display information about instrument
      IDNString = query(instrObj,'*IDN?');%資訊查詢
      fprintf('Connected to: %s\n',IDNString); 
      %fprintf(instrObj,'SYSTem:PREset');
      %fprintf(instrObj,'SYSTem:FPReset');
      fprintf(instrObj,'*CLS;*wai');
      
      
      % Define a measurement name and parameter
      fprintf(instrObj,'CALCulate:PARameter:DEFine ''MySMeaS21'',S21'); % s21
      % Create a new display window and turn it on
      fprintf(instrObj,'DISPlay:WINDow1:STATE ON');
      % Associate the measurements to WINDow1
      fprintf(instrObj,'DISPlay:WINDow1:TRACe1:FEED ''MySMeaS21''');
      % Turn ON the Title, Frequency, and Trace Annotation to allow for
      % visualization of the measurements on the instrument display
      fprintf(instrObj,'DISPlay:WINDow1:TITLe:STATe ON');
      fprintf(instrObj,'DISPlay:ANNotation:FREQuency ON');
      fprintf(instrObj,'DISPlay:WINDow1:TRACe1:STATe ON');
      
      % Set the number of points
      fprintf(instrObj, sprintf('SENSe:SWEep:POINts %s',num2str(numPoints)));
      % Set the frequency ranges
      fprintf(instrObj, sprintf('SENSe:FREQuency:STARt %sHz',num2str(frequencyRange(1))));
      fprintf(instrObj, sprintf('SENSe:FREQuency:STOP %sHz',num2str(frequencyRange(2))));
      fprintf(instrObj,'TRIG:SOUR MANual'); %手動觸發
      fprintf(instrObj,'TRIG:SCOPe ALL');
      fprintf(instrObj,'SENSe:SWEep:MODE CONTinuous');
      % Set instrument to return the data back using binblock format
      %fprintf(instrObj, 'FORMat:DATA REAL,64'); % 64位 浮點數
      fprintf(instrObj, 'FORMat:DATA ASCII'); % 編碼方式
      fprintf(instrObj,'CALCulate:PARameter:SELect ''MySMeaS21''');
      % i=0;
      % while(i<2) % 多次讀取的話使用循環即可
      fprintf(instrObj,'INITiate:IMMediate;*wai');
      fprintf(instrObj, 'Display:WINDow1:TRACe1:Y:Scale:AUTO');
      fprintf(instrObj,'CALCulate:DATA? SDATA');
      %rawDataDB = binblockread(instrObj, 'double');
      data=fread(instrObj);% 讀取資料
      fid=fopen('test.txt','wb');
      data=fwrite(fid,data,'char');% 儲存下來
      %read terminating character
      %d=fread(instrObj,1,'char');
      % i=i+1;
      % end
       
      % Close, delete, and clear instrument connections.
      fclose(instrObj);
      delete(instrObj);
      clear instrObj;
                 
  • 下面是個python的例子
    • python 中把 query 改成 instrObj.write 即可。請參看pyvisa的說明。SCPI文法和matlab中的是一緻的。

劃重點:

  • 一定要檢視對應版本的固件。固件版本不同,支援的SCIP語句是不同的。網上有matlab控制矢網的例子,但是直接用會報錯——比如undefined header。
  • VISA address 注意其格式。使用NI MAX的時候它的預設格式和實際的格式不一樣,需要手動添加。
  • 讀取資料儲存的時候選擇格式時需要注意。嘗試過許多方法後,發現使用ascii碼的方式是最簡單直接的,儲存的資料格式是使用的科學記數法。讀取的資料直接用matlab導入即可。