aboutsummaryrefslogtreecommitdiff
path: root/qolab/hardware/multimeter/bk_5491.py
blob: 0b9d788612be4d270df91f82bcc08ae38a9108fc (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
from qolab.hardware.basic import BasicInstrument
from qolab.hardware.multimeter import Multimeter
from qolab.hardware.scpi  import SCPI_PROPERTY
from pyvisa import constants as pyvisa_constants
import time

class BK_5491(Multimeter):
    """ BK 5491 multimeter """
    """
    rm = pyvisa.ResourceManager()
    instr=rm.open_resource('ASRL/dev/ttyUSB0::INSTR')
    Make sure to switch off the ECHO at the multimeter communication setup
    """
    def __init__(self, resource, *args, **kwds):
        super().__init__(*args, **kwds)
        self.resource = resource
        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.write = self.resource.write
        self.read = self.resource.read
        self.query = self.resource.query
        self.read_bytes = self.resource.read_bytes
        self.read_binary_values = self.resource.read_binary_values
        self.query_binary_values = self.resource.query_binary_values

        self.switchTime = 0.5 # switch time in seconds for Function/Measurement change 
        self.deviceProperties.update({})

    def isPrompt(self, string):
        if string[1] == '>':
            return True
        return False

    def isPromptGood(self, prompt):
        if prompt[0:2] == '=>':
            return True
        print(f'Error detected {prompt=}')
        return False

    def sendCmd(self, cmd_string, expect_reply=True, Nattemts=5):
        """
        Set command to instrument or query it readings (which is also a command)

        BK_5491 in not SCPI instrument, so we get some replies (prompts *>, =>, etc)
        even if we just send a command not a query. So we have to work around this.
        """
        self.resource.read_bytes( self.resource.bytes_in_buffer ) # clear read buffer
        # print(f"dbg: {cmd_string=}")
        self.write(cmd_string)
        if expect_reply:
            reply = self.read() # this should be result
            # print(f"dbg: {reply=}")
            if self.isPrompt(reply):
                # print(f'Error: we ask {cmd_string=} and got prompt "{reply}" instead of result')
                prompt = reply
                if prompt[0] == '@':
                    if Nattemts >= 2:
                        # print('dbg: numeric reading is not available yet, attempt one more time')
                        time.sleep(self.switchTime)
                        return self.sendCmd(cmd_string, expect_reply=expect_reply, Nattemts=Nattemts-1)
                return None
        else:
            reply = None
        prompt = self.read() # this should be prompt
        self.isPromptGood(prompt)
        # print(f"dbg: {prompt=}")
        return reply

    def getReading(self):
       """ Report current measurement """
       ret_string = self.sendCmd('R1')
       # print(f'dbg: getReading received "{ret_string}"')
       return float(ret_string)

    def setFunction(self, key_string):
        """
        BK_5491 set the measurement functions according to the front panel keys:
            K1 - Vdc
            K2 - Adc
            K3 - Vac
            K4 - Aac
            K5 - Resistance
            K6 - Diode
            K7 - Frequency (Hz)
            K8 - Auto
            K9 - Up key
            K10 - Down key
            K11 - MinMax key
            K12 - Hold key
            K13 - Local (manual does not specify, but it works this way)
            K14 - Rel key
            K15 - Shift key
            K16 - 2nd key
            K17 - Vdc and Vac keys simultaneously
            K18 - Adc and Aac keys simultaneously
            K19 - Shift then Up keys (increasing the intensity of the VFD display)
            K20 - Shift then Down keys (decreasing the intensity of the VFD display)
        """

    def getVdc(self):
        self.sendCmd('K1')
        return self.getReading()
    def getVac(self):
        self.sendCmd('K3')
        return self.getReading()
    def getAdc(self):
        self.sendCmd('K2')
        return self.getReading()
    def getAac(self):
        self.sendCmd('K4')
        return self.getReading()
    def getResistance(self):
        self.sendCmd('K5')
        return self.getReading()
    def getDiode(self):
        self.sendCmd('K6')
        return self.getReading()
    def getFreq(self):
        self.sendCmd('K7')
        return self.getReading()

    def toLocal(self):
        self.sendCmd('K13', expect_reply=False)


if __name__ == '__main__': 
    import pyvisa
    print("testing")
    rm = pyvisa.ResourceManager()
    print(rm.list_resources())    
    instr=rm.open_resource('ASRL/dev/ttyUSB0::INSTR')
    multimeter = BK_5491(instr)
    print('------ Header start -------------')
    print(str.join('\n', multimeter.getHeader()))
    print('------ Header ends  -------------')