Commit d9ca6ca7 authored by Christian Schneider's avatar Christian Schneider
Browse files

First commit for testing spectrum analyzer

parent b0d080be
......@@ -7,26 +7,29 @@ Library used to control the R&S spectrum analyzer
v2.0.1 - OSC:
- migrated to visa
"""
import time
import numpy as np
import visa
import struct
from Instruments.Drivers import dummy
class FSV30(object):
"""Instrument Driver for RohdeSchwarz FSV30 Spectrum Analyzer"""
def __init__(self, ip, *pars):
def __init__(self, ip, test=False):
"""
Parameters
-----------
ip : str
IP of spectrum analyzer
"""
rm = visa.ResourceManager()
self._inst = rm.open_resource('TCPIP::{}::INSTR'.format(ip) )
self.__version__ = '3.0.0'
# Use dummy driver if testing
if test:
self._inst = dummy
else:
rm = visa.ResourceManager()
self._inst = rm.open_resource('TCPIP::{}::INSTR'.format(ip) )
self.__version__ = '3.0.1'
def com(self, command, arg="?", raw=False):
"""Function to communicate with the device. Gives the current status
......@@ -47,8 +50,6 @@ class FSV30(object):
n_digits = int(resp[1:2]) # digits for number of bytes
n_bytes = int(resp[2:2 + n_digits])
n_points = n_bytes / 4 # 4 bytes is a float, 8 would be
# double
# Create data (big endian float: >f
data = []
......@@ -60,9 +61,11 @@ class FSV30(object):
else:
resp = self._inst.query("{}?".format(command))
# Convert to float if possible
try:
return float(resp)
except:
except ValueError:
return resp.strip('\n')
else:
......@@ -296,7 +299,6 @@ class FSV30(object):
def read_data(self, trace=1, print_info=True):
"""Read data from device.
"""
# Read data
data = self.read_trace(trace=trace)
n_points = len(data)
......
......@@ -12,26 +12,29 @@ import struct
import time
import numpy as np
import visa
from Instruments.Drivers import dummy
class RSA5115B(object):
"""Instrument Driver for Tektronix RSA5115B Spectum analyzer"""
def __init__(self, ip):
def __init__(self, ip, test=False):
"""
Parameters
-----------
ip : str
IP of spectrum analyzer
"""
rm = visa.ResourceManager()
self._inst = rm.open_resource('TCPIP::{}::INSTR'.format(ip) )
if test:
self._inst = dummy
else:
rm = visa.ResourceManager()
self._inst = rm.open_resource('TCPIP::{}::INSTR'.format(ip) )
# Set to spectrum
self.com('display:general:measview:new', 'spectrum')
self.__version__ = '1.0.0'
self.__version__ = '2.0.0'
def com(self, command, arg="?",raw=False):
def com(self, command, arg="?", raw=False):
"""Function to communicate with the device. Gives the current status
if no arg is given
......@@ -40,12 +43,14 @@ class RSA5115B(object):
if arg == "?":
if raw:
self._inst.write('{}?'.format(command))
return self._inst.read_raw(10) #10 chunks, it seems that 1 gives problems in linux
return self._inst.read_raw(100)
else:
resp = self._inst.query("{}?".format(command))
resp = self._inst.query("{}?".format(command))
# Convert to floar
try:
return float(resp)
except:
except ValueError:
return resp.strip('\n')
else:
......
......@@ -5,9 +5,7 @@ Author: Christian Schneider <c.schneider@uibk.ac.at>
# class definition
import random
VERSION = "2.0.1"
print('GS200 v{}'.format(VERSION))
VERSION = "2.0.2"
class dummy(object):
"""Dummy instrument for testing
......@@ -17,146 +15,62 @@ class dummy(object):
self.version = VERSION
self.ip = ip
# Safety compliance values
self.output_dummy = 0
self.output_level_dummy = 0
self.output_mode_dummy = 'CURR'
def identify(self):
"""Identification of the device"""
return 'DUMMY,DUMMY,DUMMY,DUMMY'
def output(self, arg='?', channel=1):
""" Turn output 1|2 power on|off
Parameters
-----------
arg : float, string
1, 'ON', 0, 'OFF'
channel : int
Channel 1 or 2
Returns
-------
int
If arg=?: 1 if on, 0 if off
"""
if arg == '?':
return self.output_dummy
else:
self.output_dummy = arg
def output_mode(self, arg='?', channel=1):
"""Set/query current Output mode
Parameters
-----------
arg : string
Specify 'VOLT' or 'CURR'
channel : int
Channel 1 or 2
"""
if arg == '?':
return self.output_mode_dummy
else:
self.output_mode_dumyy = arg
def meas(self, channel=1):
"""Returns spot measurement of all measured variables"""
if self.output() == 0:
raise Exception("MEASURING ONLY POSSIBLE WITH OUTPUT 1")
else:
if self.output_mode() == "CURR":
label = "VOLT"
else:
label = "CURR"
return {label: float(random.random())}
def output_level(self, arg='?', channel=1, safe_mode=True):
"""Query/Set the level of output 1|2
Parameters
-----------
arg : None, float
Output level in A|V for channel 1|2
channel : int
Channel 1 or 2
safe_mode : bool
Raises an error if limits are exceeded
"""
mode = self.output_mode(channel=channel) # Query CURR or VOLT
cmd = 'SOUR:LEV'
if arg == "?":
return self.output_level_dummy
elif safe_mode:
if mode == 'CURR':
if (arg < self.min_cur[channel - 1] or
arg > self.max_cur[channel - 1]):
print('ERROR: current value too high')
raise Exception('HIGHCURR')
else:
if (arg < self.min_vol[channel - 1] or
arg > self.max_vol[channel - 1]):
print('ERROR: voltage value too high')
raise Exception('HIGHVOLT')
else:
self.output_level_dummy = arg
def meas_res(self, channel=1):
"""Turns on V/I measurement of resistance and returns resistance"""
return "Not Supported by DUMMY"
def meas(self, channel=1):
"""Returns spot measurement of all measured variables"""
if self.output() == 0:
raise Exception("MEASURING ONLY POSSIBLE WITH OUTPUT 1")
else:
if self.output_mode() == "CURR":
label = "VOLT"
else:
label = "CURR"
return {label : float(random.random())}
def set_limits(self, V=None, I=None, channel=1, output_protection=True,
print_status=True):
"""This function sets the limits of the output for the channel.
The corresponding values for the compliance are taken from the
self.max_cur and self.max_volt variables if no argument is given.
Yokogawa does only support a minimum voltage of 1 V and a minimum
current of 1 mA.
Parameters
-----------
I : None, float
Sets the maximum value for current for specified channel
V : None, float
Sets the maximum value for votlage for the specified channel
channel : int
Channel of current source. Default 1
output_protection : bool
Switch off channel power if the instrument goes into compliance
"""
# Query current mode
mode = self.output_mode(channel=channel)
# Save new value if something is given
if I:
self.max_cur[channel - 1] = I
if V:
self.max_vol[channel - 1] = V
def close(self):
return 0
def write(self):
"""Dummy write: Does nothing"""
return 0
def read_raw(self):
"""Dummy read raw: Sends random stuff"""
data_string = b'#3404\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H\xc3\x00\x00H' \
b'\xc3\x00\x00H\xc3\n '
return data_string
def query(self, c):
"""Query device parameters. Returns hard coded values"""
if 'idn' in c.lower():
return 'dummy,dummy,dummy,dummy'
elif 'freq' in c.lower() and 'start' in c.lower():
return 0
elif 'freq' in c.lower() and 'stop' in c.lower():
return 10
elif 'span' in c.lower():
return 10
elif 'cent' in c.lower():
return 5
elif 'time' or 'second' in c.lower():
return 1
elif 'band' in c.lower():
return 1
elif 'poin' in c.lower():
return 101 # Always 101 points
# Set compliance
if mode == 'CURR':
if print_status:
print(
"Compliance set to {} V".format(self.max_vol[channel - 1]))
else:
if print_status:
print(
"Compliance set to {} A".format(self.max_cur[channel - 1]))
def close(self):
return 0
\ No newline at end of file
return 'Success'
......@@ -55,10 +55,15 @@ class SA(object):
def __init__(self, id_string, cryostat, driver=None, database=True):
# Device parameters ####################################################
self.test = False # Running in test mode?
try:
# Try to find device in IPList
self.ip = IPList[id_string]
except KeyError:
# If it is a test, give IP with zeros and set test mode to true
if id_string[-4:-1].lower() == 'tes':
self.ip = '0.0.0.0'
self.test = True
# If SA is not specified by valid IPList entry. Try directly ip
if driver is not None:
self.ip = id_string
......@@ -110,7 +115,7 @@ class SA(object):
def init_driver(self):
"""Init connection to device."""
self.instr = self.driver(self.ip)
self.instr = self.driver(self.ip, test=self.test)
def close_driver(self):
"""Close connection to device"""
......
# -*- coding: utf-8 -*-
"""Test for Spectrum Analyzer.
Currently implemented:
- Rohde und Schwarz
- Tektronix
date: 21.07.2019
author: christian schneider <c.schneider@uibk.ac.at>
"""
import Instruments
def test_RohdeSchwarz():
sa = Instruments.SA('SA1_test', None)
assert sa.identify() == 'dummy,dummy,dummy,dummy'
def test_Tektronix():
sa = Instruments.SA('SA2_test', None)
assert sa.identify() == 'dummy,dummy,dummy,dummy'
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment