aboutsummaryrefslogtreecommitdiff
path: root/qolab/hardware/multimeter/hp_34401.py
blob: 2d9abddc310a4c5e152a9fe3ea84d1578bbd9294 (plain)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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'})

    rawFunction = 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 getFunction(self):
        rfunc = self.rawFunction
        if rfunc == '"VOLT"':
            return "Vdc"
        elif rfunc == '"VOLT:AC"':
            return "Vac"
        elif rfunc == '"CURR"':
            return "Adc"
        elif rfunc == '"CURR:AC"':
            return "Aac"
        elif rfunc == '"RES"':
            return "Resistance"
        elif rfunc == '"FRES"':
            return "Resistance4Wires"
        elif rfunc == '"DIOD"':
            return "Diode"
        elif rfunc == '"FREQ"':
            return "Frequency"
        elif rfunc == '"PER"':
            return "Period"
        elif rfunc == '"CONT"':
            return "Continuity"
        else:
            return "Unknown"

    def toRemote(self):
        self.write("SYSTem:REMote")

    def toLocal(self):
        self.write("SYSTem:LOCal")

    def isSensing(self, test):
        return test == self.rawFunction

    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):
            self.rawFunction=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"')
    @BasicInstrument.tsdb_append
    def getPeriod(self):
        return self.getReadingWithSettingFunction('"PERiod"', '"PER"')


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  -------------')