Frappy driver for a HP multimeter

Change-Id: I2e9dc5131ea9a7317d69c42dd49388216e77f72f
This commit is contained in:
Oksana Shliakhtun 2024-04-23 17:20:55 +02:00 committed by Markus Zolliker
parent 5376490a7e
commit a5e698163b

View File

@ -18,7 +18,7 @@
# Module authors: Oksana Shliakhtun <oksana.shliakhtun@psi.ch> # Module authors: Oksana Shliakhtun <oksana.shliakhtun@psi.ch>
# ***************************************************************************** # *****************************************************************************
import re 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): def string_to_value(value):
@ -68,50 +68,83 @@ class HP34401A(HP_IO):
self.comm(f'{function}:resolution {resolution}') self.comm(f'{function}:resolution {resolution}')
return self.comm(f'{function}: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): class Voltage(HP34401A, Readable):
value = Parameter('voltage', datatype=FloatRange(0.1, 1000), unit='V') value = Parameter('voltage', datatype=FloatRange(0.1, 1000), unit='V')
range = Parameter('voltage sensitivity value', FloatRange(), unit='V', default=1, readonly=False) range = Parameter('voltage sensitivity value', FloatRange(), unit='V', default=1, readonly=False)
resolution = Parameter('resolution') 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 ioClass = HP_IO
MODE_NAMES = {0: 'dc', 1: 'ac'}
VOLT_RANGE = ['100mV', '1V', '10V', '100V', '1000V'] VOLT_RANGE = ['100mV', '1V', '10V', '100V', '1000V']
v_range = Parameter('voltage range', EnumType('voltage index range', v_range = Parameter('voltage range', EnumType('voltage index range',
{name: idx for idx, name in enumerate(VOLT_RANGE)}), readonly=False) {name: idx for idx, name in enumerate(VOLT_RANGE)}), readonly=False)
acdc = None
def write_mode(self, mode): def write_mode(self, mode):
if mode == 1: if mode == 1:
self.comm(f'configure:voltage:AC {self.range}, {self.resolution}') self.comm(f'configure:voltage:AC {self.range}, {self.resolution}')
else: else:
self.comm(f'configure:voltage:DC {self.range}, {self.resolution}') self.comm(f'configure:voltage:DC {self.range}, {self.resolution}')
self.acdc = self.MODE_NAMES[mode]
return self.comm(f'function?') return self.comm(f'function?')
def read_value(self): def read_value(self):
self.comm(f'measure:voltage:') self.comm(f'measure:voltage:')
def write_autorange_acdc(self, function): def write_autorange_acdc(self, function):
mode_pr = {1: f'{function}:ac', 2: f'{function}:dc'} full_function = f'{function}:{self.acdc}'
full_function = mode_pr[self.mode]
return self.write_autorange(full_function) return self.write_autorange(full_function)
def read_range_voltage(self): 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): def write_range_voltage(self, range):
type = 'ac' if self.mode == 1 else 'dc' return self.write_range(f'voltage:{self.acdc}', range)
return self.write_range(f'voltage:{type}', range)
def write_autorange_voltage(self): def write_autorange_voltage(self):
return self.write_autorange_acdc('voltage') return self.write_autorange_acdc('voltage')
def read_resolution_voltage(self): def read_resolution_voltage(self):
type = 'ac' if self.mode == 1 else 'dc' return self.read_resolution(f'voltage:{self.acdc}')
return self.read_resolution(f'voltage:{type}')
def write_resolution_voltage(self, resolution): 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): class Current(HP34401A, Readable, Voltage):
@ -121,38 +154,42 @@ class Current(HP34401A, Readable, Voltage):
CURR_RANGE_DC = ['1A', '3A'] CURR_RANGE_DC = ['1A', '3A']
def read_range_current(self): 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): def write_autrange_current(self):
return self.write_autorange_acdc('current') return self.write_autorange_acdc('current')
def write_range_current(self, range): 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): def read_resolution_current(self):
type = 'ac' if self.mode == 1 else 'dc' return self.read_resolution(f'current:{self.acdc}')
return self.read_resolution(f'current:{type}')
def write_resolution_current(self, resolution): 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): class Resistance(HP34401A, Readable):
value = Parameter('resistance') value = Parameter('resistance')
mode = Parameter('measurement mode: 2-/4-wire ohms', EnumType(two_wire=2, four_wire=4), readonly=False) 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'] RESIST_RANGE = ['100Om', '1kOm', '10kOm', '100kOm', '1MOm', '10MOm', '100MOm']
FUNCTION_MAP = {2: 'resistance', 4: 'fresistance'} FUNCTION_MAP = {2: 'resistance', 4: 'fresistance'}
def write_mode(self, mode):
pass # configure:...
def write_range_resistance(self, range): def write_range_resistance(self, range):
return self.write_range(f'{self.FUNCTION_MAP[self.mode]}', range) return self.write_range(f'{self.FUNCTION_MAP[self.mode]}', range)
def read_range_resistance(self): def read_range_resistance(self):
return self.read_range(f'{self.FUNCTION_MAP[self.mode]}') 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): def write_autorange_resistance(self):
return self.write_autorange(self.FUNCTION_MAP[self.mode]) return self.write_autorange(self.FUNCTION_MAP[self.mode])
@ -174,4 +211,3 @@ class Frequency(HP34401A, Readable):
def write_resolution_frequency(self, resolution): def write_resolution_frequency(self, resolution):
return self.write_resolution('frequency', resolution) return self.write_resolution('frequency', resolution)