1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
from qolab.hardware.basic import BasicInstrument
from qolab.hardware.multimeter import MultimeterSCPI
from qolab.hardware.scpi import SCPI_PROPERTY
from pyvisa import constants as pyvisa_constants
import time
class HP_34401(MultimeterSCPI):
""" HP 34401 multimeter (same as Agilent) """
"""
rm = pyvisa.ResourceManager()
instr=rm.open_resource('ASRL/dev/ttyUSB0::INSTR')
"""
def __init__(self, resource, *args, **kwds):
super().__init__(resource, *args, **kwds)
self.config['Device model']='HP 34401'
self.resource.read_termination = '\r\n'
self.resource.baud_rate = 9600
self.resource.data_bits = 8
self.resource.parity = pyvisa_constants.Parity.none
self.resource.stop_bits = pyvisa_constants.StopBits.one
self.resource.timeout = 5000
self.switchTime = 0.5 # switch time in seconds for Function/Measurement change
self.deviceProperties.update({'Function'})
Function = SCPI_PROPERTY(scpi_prfx='SENSe:FUNCtion', ptype=str, doc="""
Current measurement function (Voltmeter DC/AC, Currentmeter DC/AC, etc.
Important! When assigning, string should be quoted, i.e. use:
Function=\'"VOLT:DC"\'
Possible values:
"VOLTage:DC", same as "VOLT"
"VOLTage:DC:RATio"
"VOLTage:AC"
"CURRent:DC", same as "CURR"
"CURRent:AC"
"RESistance" (2-wire ohms)
"FRESistance" (4-wire ohms)
"FREQuency"
"PERiod"
"CONTinuity"
"DIODe"
"""
)
def toRemote(self):
self.write("SYSTem:REMote")
def toLocal(self):
self.write("SYSTem:LOCal")
def isSensing(self, test):
return test == self.Function
Reading = SCPI_PROPERTY(scpi_prfx='SYSTem:REMote; :READ', ptype=float, doc='Report current measurement', no_setter=True)
# HP 34401 is tricky
# when reading over serial interface the value of measurement/function,
# the device need to be switched to REMOTE mode, but this leaves screen blank and unusable
# so we have to do the dance with toRemote and toLocal
def getReadingWithSettingFunction(self, desired_function_string, function_internal_name):
"""
Get the reading but first check if we are set to do specific function/measurement.
If the instrument set to do different function, set to desired one
Note: the function name should be in quotes, i.e. '"Volt"'
"""
if not self.isSensing(function_internal_name):
# print(f"function {self.Function} switching function to {desired_function_string}")
self.Function=desired_function_string
time.sleep(self.switchTime)
# self.toRemote() # this is done inside of Reading
ret = self.Reading
self.toLocal()
return ret
@BasicInstrument.tsdb_append
def getVdc(self):
return self.getReadingWithSettingFunction('"VOLTage:DC"', '"VOLT"')
@BasicInstrument.tsdb_append
def getVac(self):
return self.getReadingWithSettingFunction('"VOLTage:AC"', '"VOLT:AC"')
@BasicInstrument.tsdb_append
def getAdc(self):
return self.getReadingWithSettingFunction('"CURRent:DC"', '"CURR"')
@BasicInstrument.tsdb_append
def getAac(self):
return self.getReadingWithSettingFunction('"CURRent:AC"', '"CURR:AC"')
@BasicInstrument.tsdb_append
def getResistance(self):
return self.getReadingWithSettingFunction('"RESistance"', '"RES"')
@BasicInstrument.tsdb_append
def getResistance4Wires(self):
return self.getReadingWithSettingFunction('"FRESistance"', '"FRES"')
@BasicInstrument.tsdb_append
def getDiode(self):
return self.getReadingWithSettingFunction('"DIODe"', '"DIOD"')
@BasicInstrument.tsdb_append
def getFreq(self):
return self.getReadingWithSettingFunction('"FREQuency"', '"FREQ"')
if __name__ == '__main__':
import pyvisa
print("testing")
rm = pyvisa.ResourceManager()
print(rm.list_resources())
instr=rm.open_resource('ASRL/dev/ttyUSB0::INSTR')
multimeter = HP_34401(instr)
print('------ Header start -------------')
print(str.join('\n', multimeter.getHeader()))
print('------ Header ends -------------')
|