Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- vna_communication.py
- import socket
- import re
- import numpy as np
- import datetime
- from pathlib import Path
- PORT = 5001
- BUFFER_SIZE = 1048576 #maximum size of packages returned by socket.recv()
- #size is arbitrary, low size leads to slow transmittion.
- RESOLUTION = 16001 #16001 is maximum
- class VNA:
- """This class communicates with the MS46122B VNA via the Shockline
- software. It takes care of Networking and formatting of results, so
- that it can be used easily in Matlab. It contains a setup,
- run_measurement and get_results method for easy access of data but
- also passes on the low level send and receive commands, so that further
- optimization can be easily done in Matlab.
- Known Bugs:
- First Measurement might contain weird data. Be sure to run one test
- measurement before using data.
- Possible explaination: Initialization might send unexpected data.
- Possible fix: search for begin of <DataFile>.
- Will fix if needed.
- """
- def __init__(self, ip):
- self.path = str(Path(__file__).parent.absolute())
- self.logdir = self.path+"/logs/"
- Path(self.logdir).mkdir(parents=True, exist_ok=True)
- self.vna=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.vna.settimeout(120.0)
- #*OPC? command might take very long to answer
- self.vna.connect((ip, 5001))
- def setup(self,start, end):
- """Sets parameters for Measurement, like start and end Frequency
- but also resolution and sets mode to single sweep.
- """
- self.send("SENS:FREQ:STAR "+ start)
- # set start and end frequency.
- self.send("SENS:FREQ:STOP "+ end)
- self.send("SENS1:SWEEP:POINT "+str(RESOLUTION))
- # set to maximum resolution.
- self.send("INIT:MODE:SING")
- # set Measurement mode to single.
- def run_measurement(self):
- """Starts a Measurement and returns when it has finished.
- """
- self.send("TRIG:SING")
- self.send("*OPC?") # tell device to answer when finished
- self.receive() # wait till end of measurement
- def get_results(self):
- """Collects the results of a Measurement as a Python array.
- """
- self.send("CALC1:TDATA:SDATA?")
- self.receive() #throws away length of transmittion
- data = b""
- #This loop ensures data is complete, as receive behaves unpredictably
- while not data.endswith(b"</DataFile>\n"):
- data += self.receive()
- data = data.decode("ASCII")
- start_point = data.find("<!--Freq(GHz);Real; Imag-->") + 35
- #35 length of the used find marker + whitespace
- end_point = data.find(" </Values>")-1
- #-1 removes the newline
- data = data[start_point:end_point]
- raw_data_array=data.split("\r\n ")
- timestamp = datetime.datetime.now().isoformat("_", "seconds")
- Ilog = open(self.logdir+"inputlog_"+timestamp+".txt", "w")
- Olog = open(self.logdir+"outputlog_"+timestamp+".txt", "w")
- return_data_array = np.empty([RESOLUTION,3])
- for line in raw_data_array:
- Ilog.write(line+"\n")
- if(line.startswith("<Point_")):
- match = re.match(
- r"<Point_(\d+)>(.+);(.+);(.+)</Point_\d+>",line,)
- iterator = int(match.group(1))-1 #Data starts at 1
- frequency = float(match.group(2).replace(",","."))
- real = float(match.group(3).replace(",","."))
- imag = float(match.group(4).replace(",","."))
- if(not(np.isnan(iterator)
- or np.isnan(frequency)
- or np.isnan(real)
- or np.isnan(imag))):
- return_data_array[iterator,0] = frequency
- return_data_array[iterator,1] = real
- return_data_array[iterator,2] = imag
- Olog.write(str(iterator)+" "+str(frequency)+" "\
- +str(real)+" "+str(imag)+"\n")
- Ilog.close()
- Olog.close()
- return return_data_array
- def send(self,command):
- """sends a command to the VNA, Command format is found in the
- Programming guide: https://dl.cdn-anritsu.com/en-us/test-measurement/files/Manuals/Programming-Manual/10410-00746U.pdf
- """
- self.vna.send(str.encode(command+"\n"))
- def receive(self):
- try:
- return self.vna.recv(BUFFER_SIZE)
- except Exception as err:
- #Catches everything that goes wrong and writes it to file.
- #Cancels execution.
- outF = open(self.logdir+"error.txt", "a")
- outF.write(datetime.datetime.now().isoformat("_", "seconds")+"\n")
- outF.write(str(err)+"\n")
- outF.close()
- sys.exit(str(err))
- VNA_mat.m
- classdef VNA_mat
- properties
- socket
- end
- methods
- function vna = VNA_mat(IP)
- py.importlib.import_module('vna_communication');
- vna.socket = py.vna_communication.VNA(IP);
- end
- function send(vna, command)
- vna.socket.send(command);
- end
- function message = receive(vna)
- message = vna.socket.receive();
- end
- function setup(vna,start,stop)
- vna.socket.setup(start,stop);
- end
- function run_measurement(vna)
- vna.socket.run_measurement();
- end
- function result = get_results(vna)
- nparray = vna.socket.get_results();
- %found at https://de.mathworks.com/matlabcentral/answers/157347-convert-python-numpy-array-to-double
- %nparray2mat Convert an nparray from numpy to a Matlab array
- %Convert an n-dimensional nparray into an equivalent Matlab array
- data_size = cellfun(@int64,cell(nparray.shape));
- if length(data_size)==1
- % This is a simple operation
- result=double(py.array.array('d', py.numpy.nditer(nparray)));
- elseif length(data_size)==2
- % order='F' is used to get data in column-major order (as in Fortran
- % 'F' and Matlab)
- result=reshape(double(py.array.array('d', ...
- py.numpy.nditer(nparray, pyargs('order', 'F')))), ...
- data_size);
- else
- % For multidimensional arrays more manipulation is required
- % First recover in python order (C contiguous order)
- result=double(py.array.array('d', ...
- py.numpy.nditer(nparray, pyargs('order', 'C'))));
- % Switch the order of the dimensions (as Python views this in the
- % opposite order to Matlab) and reshape to the corresponding C-like
- % array
- result=reshape(result,fliplr(data_size));
- % Now transpose rows and columns of the 2D sub-arrays to arrive at the
- % correct Matlab structuring
- result=permute(result,[length(data_size):-1:1]);
- end
- end
- end
- end
- vna_test.m
- clear all
- vna = VNA_mat("134.96.22.37");
- %vna.send("*IDN?");
- %vna.receive();
- vna.setup("9.747E+009","9.754E+009");
- vna.run_measurement();
- res = vna.get_results();
- frequencies = zeros(16001,1);
- values = zeros(16001,1);
- index_ = 1;
- while index_ <= 16001
- frequency=res(index_,1);
- real=res(index_,2);
- im=res(index_,3);
- frequencies(index_) = frequency;
- val = sqrt(real^2+im^2);
- values(index_) = val;
- %sprintf("%0.4g Real %0.4g Im %0.4g res %0.4g",index_,real,im,val)
- index_ = index_ + 1;
- end
- plot(frequencies, values);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement