Frappy driver for a HP multimeter

Change-Id: I2e9dc5131ea9a7317d69c42dd49388216e77f72f
This commit is contained in:
Oksana Shliakhtun 2024-04-23 17:20:55 +02:00
parent 4f9372066a
commit 95ca85fd9c

View File

@ -18,7 +18,7 @@
# Module authors: Oksana Shliakhtun <oksana.shliakhtun@psi.ch>
# *****************************************************************************
import re
from frappy.core import HasIO, Readable, Parameter, FloatRange, EnumType, StatusType, Drivable
from frappy.core import HasIO, Readable, Parameter, FloatRange, EnumType, StatusType, IDLE, ERROR, WARN
def string_to_value(value):
@ -68,50 +68,83 @@ class HP34401A(HP_IO):
self.comm(f'{function}:resolution {resolution}')
return self.comm(f'{function}:resolution?')
def read_status(self):
stb = int(self.comm('*STB?'))
esr = int(self.comm('*ESR?'))
if esr & (1 << 3):
return ERROR, 'self-test/calibration/reading failed'
if esr & (1 << 4):
return ERROR, 'execution error'
if esr & (1 << 5):
return ERROR, 'syntax error'
if esr & (1 << 2):
return ERROR, 'query error'
if stb & (1 << 3):
return WARN, 'questionable data'
if stb & (1 << 5):
return WARN, 'standard event register is not empty'
if stb & (1 << 6):
return WARN, 'requested service'
if any(stb & (1 << i) for i in range(3) or stb & (1 << 7)):
return IDLE, ''
if esr & (1 << 6):
return IDLE, ''
if esr & (1 << 7):
return IDLE, ''
if stb & (1 << 4):
return IDLE, 'message available'
if esr & (1 << 0):
return IDLE, 'operation complete'
if esr & (1 << 1):
return IDLE, 'not used'
class Voltage(HP34401A, Readable):
value = Parameter('voltage', datatype=FloatRange(0.1, 1000), unit='V')
range = Parameter('voltage sensitivity value', FloatRange(), unit='V', default=1, readonly=False)
resolution = Parameter('resolution')
mode = Parameter('measurement mode: ac/dc', EnumType(AC=1, DC=2), readonly=False)
mode = Parameter('measurement mode: ac/dc', readonly=False)
ioClass = HP_IO
MODE_NAMES = {0: 'dc', 1: 'ac'}
VOLT_RANGE = ['100mV', '1V', '10V', '100V', '1000V']
v_range = Parameter('voltage range', EnumType('voltage index range',
{name: idx for idx, name in enumerate(VOLT_RANGE)}), readonly=False)
acdc = None
def write_mode(self, mode):
if mode == 1:
self.comm(f'configure:voltage:AC {self.range}, {self.resolution}')
else:
self.comm(f'configure:voltage:DC {self.range}, {self.resolution}')
self.acdc = self.MODE_NAMES[mode]
return self.comm(f'function?')
def read_value(self):
self.comm(f'measure:voltage:')
def write_autorange_acdc(self, function):
mode_pr = {1: f'{function}:ac', 2: f'{function}:dc'}
full_function = mode_pr[self.mode]
full_function = f'{function}:{self.acdc}'
return self.write_autorange(full_function)
def read_range_voltage(self):
return self.read_range(f'voltage:{"ac" if self.mode == 1 else "dc"}')
return self.read_range(f'voltage:{self.acdc}')
def write_range_voltage(self, range):
type = 'ac' if self.mode == 1 else 'dc'
return self.write_range(f'voltage:{type}', range)
return self.write_range(f'voltage:{self.acdc}', range)
def write_autorange_voltage(self):
return self.write_autorange_acdc('voltage')
def read_resolution_voltage(self):
type = 'ac' if self.mode == 1 else 'dc'
return self.read_resolution(f'voltage:{type}')
return self.read_resolution(f'voltage:{self.acdc}')
def write_resolution_voltage(self, resolution):
return self.write_resolution(f'voltage:{"ac" if self.mode == 1 else "dc"}', resolution)
return self.write_resolution(f'voltage:{self.acdc}', resolution)
class Current(HP34401A, Readable, Voltage):
@ -121,38 +154,42 @@ class Current(HP34401A, Readable, Voltage):
CURR_RANGE_DC = ['1A', '3A']
def read_range_current(self):
return self.read_range(f'current:{"ac" if self.mode == 1 else "dc"}')
return self.read_range(f'current:{self.acdc}')
def write_autrange_current(self):
return self.write_autorange_acdc('current')
def write_range_current(self, range):
return self.write_range(f'current:{"ac" if self.mode == 1 else "dc"}', range)
return self.write_range(f'current:{self.acdc}', range)
def read_resolution_current(self):
type = 'ac' if self.mode == 1 else 'dc'
return self.read_resolution(f'current:{type}')
return self.read_resolution(f'current:{self.acdc}')
def write_resolution_current(self, resolution):
return self.write_resolution(f'current:{"ac" if self.mode == 1 else "dc"}', resolution)
return self.write_resolution(f'current:{self.acdc}', resolution)
class Resistance(HP34401A, Readable):
value = Parameter('resistance')
mode = Parameter('measurement mode: 2-/4-wire ohms', EnumType(two_wire=2, four_wire=4), readonly=False)
resolution = Parameter('resistance resolution')
resolution = Parameter('resistance measurement resolution')
range = Parameter('resistance measurement range')
RESIST_RANGE = ['100Om', '1kOm', '10kOm', '100kOm', '1MOm', '10MOm', '100MOm']
FUNCTION_MAP = {2: 'resistance', 4: 'fresistance'}
def write_mode(self, mode):
pass # configure:...
def write_range_resistance(self, range):
return self.write_range(f'{self.FUNCTION_MAP[self.mode]}', range)
def read_range_resistance(self):
return self.read_range(f'{self.FUNCTION_MAP[self.mode]}')
def write_mode(self, mode):
if mode == 2:
self.comm(f'configure:resistance {self.range},{self.resolution}')
elif mode == 4:
self.comm(f'configure:fresistance {self.range}, {self.resolution}')
return self.comm('configure?')
def write_autorange_resistance(self):
return self.write_autorange(self.FUNCTION_MAP[self.mode])
@ -174,4 +211,3 @@ class Frequency(HP34401A, Readable):
def write_resolution_frequency(self, resolution):
return self.write_resolution('frequency', resolution)