aboutsummaryrefslogtreecommitdiff
path: root/qolab/hardware/multimeter/hp_34401.py
blob: 36d862ccf5f58aac407a0054a4523a444afb9874 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
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):
    r"""HP 34401 multimeter (same as Agilent 34401)

    Example
    -------

    >>> from qolab.hardware.multimeter.hp_34401 import HP_34401
    >>> rm = pyvisa.ResourceManager()
    >>> instr=rm.open_resource('ASRL/dev/ttyUSB0::INSTR')
    >>> multimeter = HP_34401(instr)
    >>> print("------ Header start -------------")
    >>> print(str.join("\n", multimeter.getHeader()))
    >>> print("------ Header ends  -------------")
    """

    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 required reading.

        But first check if the multimeter is set to do specific function/measurement.
        If the instrument set to do different function, set to the 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  -------------")