hpib.py 6.51 KB
Newer Older
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
1
2
3
4
import serial
import time
import re
import platform
5
import sys
6
from threading import Lock
7
8


9
10
11
12
class PortDevice(object):
    def command(self, hpib_address, command):
        raise NotImplementedError

auke.klazema's avatar
auke.klazema committed
13
    def query(self, hpib_address, query, count=80):
14
15
16
17
18
19
20
        raise NotImplementedError

    def set_local(self, hpib_address):
        raise NotImplementedError


class PrologixGpibUsb(PortDevice):
21
22
    _serialPort = None
    _hpib_address = -1
23
    _devices = "Not scanned."
24

auke.klazema's avatar
auke.klazema committed
25
26
    def __init__(self, port="", timeout=1, port_format="%d", max_device_num=9, verbose=False,
                 find_devices=False):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
27
        if port == "":
auke.klazema's avatar
auke.klazema committed
28
            max_device_num, port, port_format = self._set_default_platform_values()
29

30
        self._validate_port(port)
31
        self._lock = Lock()
32

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
33
        if verbose:
34
35
            print("Looking for ports such as %s in range %d on %s" % \
                  (port, max_device_num, platform.system()))
36

auke.klazema's avatar
auke.klazema committed
37
        self._find_available_port(max_device_num, port, port_format, timeout, verbose)
38

39
40
        self._initialize_prologix_gpi()

auke.klazema's avatar
auke.klazema committed
41
        if find_devices:
42
            self._find_devices()
43

44
45
46
47
48
49
50
51
52
53
54
55
    def _set_default_platform_values(self):
        if platform.system() == "Linux":
            port = "/dev/ttyUSB0"
            port_format = "%d"
            max_device_num = 99
        elif platform.system() == "Darwin":
            port = "/dev/ttys000"
            port_format = "%03d"
            max_device_num = 999
        else:
            raise NotImplementedError("Windows is not supported")
        return max_device_num, port, port_format
56

57
58
59
60
    def _validate_port(self, port):
        self._rematch = re.search(r"(/dev/tty.*[^0-9])([0-9]+$)", port)
        if not self._rematch:
            raise ValueError(port)
61

auke.klazema's avatar
auke.klazema committed
62
63
    def _find_available_port(self, max_device_num, port, port_format, timeout, verbose):
        while int(self._rematch.group(2)) < max_device_num:
64
            if verbose:
65
                print("trying ", port)
66
67
68
69
            try:
                self._serialPort = serial.Serial(port, timeout=timeout)
                break
            except serial.SerialException:
auke.klazema's avatar
auke.klazema committed
70
                port = self._rematch.group(1) + (port_format % (int(self._rematch.group(2)) + 1))
71
72
73
74
                self._rematch = re.search("(/dev/tty.*[^0-9])([0-9]+$)", port)
        if self._serialPort is None:
            raise serial.SerialException("Cannot find port")

75
76
77
78
79
80
    def _write_serial(self, commandString):
        if sys.version_info >= (3,0):
            self._serialPort.write(bytes(commandString, 'utf-8'))
        else:
            self._serialPort.write(commandString)

81
    def _initialize_prologix_gpi(self):
82
83
84
85
86
87
88
        self._write_serial("++savecfg 0" + chr(10))
        self._write_serial("++auto 0" + chr(10))
        self._write_serial("++eoi 1" + chr(10))
        self._write_serial("++eos 2" + chr(10))
        self._write_serial("++eot_enable 0" + chr(10))
        self._write_serial("++eot_char 0" + chr(10))
        self._write_serial("++read_tmo_ms 500" + chr(10))
89

90
91
    def _find_devices(self):
        self._devices = []
92
93
        for address in range(0, 31):
            commandStr = "++addr " + str(address) + chr(10) + \
94
95
                         "*idn?" + chr(10) + \
                         "++read" + chr(10)
96
            self._write_serial(commandStr)
97
98
            returnStr = self._serialPort.readline()
            if returnStr != "":
99
                self._devices += [address, returnStr]
100

auke.klazema's avatar
auke.klazema committed
101
    def command(self, hpib_address, command):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
102
        if hpib_address != self._hpib_address:
103
            command = "++addr " + str(hpib_address) + chr(10) + command
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
104
            self._hpib_address = hpib_address
105

106
107
        with self._lock:
            self._write_serial(command + chr(10))
108

auke.klazema's avatar
auke.klazema committed
109
    def query(self, hpib_address, query, count=80):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
110
        if hpib_address != self._hpib_address:
111
            query = "++addr " + str(hpib_address) + chr(10) + query
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
112
            self._hpib_address = hpib_address
113
114

        query += chr(10) + "++read eoi" + chr(10)
115
116
117
        with self._lock:
            self._write_serial(query)
            line = self._serialPort.readline()
118
        return line[:-1]
119

120
    def set_local(self, hpib_address):
auke.klazema's avatar
auke.klazema committed
121
        # self._commandStr = "++addr "+str(hpib_address)+chr(10)+"loc "+str(hpib_address)+chr(10)
122
        # self._commandCount = self._write_serial(self._commandStr)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
123
        return
124

auke.klazema's avatar
auke.klazema committed
125
    def get_devices(self):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
126
        return self._devices
127
128


129
class GPIB_232_485CT_A(PortDevice):
130
131
132
133
    def __init__(self, port="/dev/ttyS0", baudrate=9600, bytesize=serial.EIGHTBITS,
                 parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, interCharTimeout=None,
                 pause=0, timeout=10):
        self._serialPort = serial.Serial(port, baudrate, bytesize, parity, stopbits,
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
134
135
136
                                         interCharTimeout, timeout)
        self._serialPort.flushInput()
        self._pause = pause
137

auke.klazema's avatar
auke.klazema committed
138
139
    def command(self, hpib_address, command):
        self._commandStr = "wr " + str(hpib_address) + chr(10) + command + chr(13)
140
        self._commandCount = self._write_serial(self._commandStr)
141

auke.klazema's avatar
auke.klazema committed
142
    def query(self, hpib_address, query, count=80):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
143
144
        # flushInput should not be necessary
        # self._serialPort.flushInput()
auke.klazema's avatar
auke.klazema committed
145
        self._commandStr = "wr " + str(hpib_address) + chr(10) + query + chr(13)
146
        self._commandCount = self._write_serial(self._commandStr)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
147
        self._queryStr = "rd #"+str(count)+" "+str(hpib_address)+chr(13)
148
        self._queryCount = self._write_serial(self._queryStr)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
149
150
151
        self._returnStr = self._serialPort.read(count)
        self._returnCnt = int(self._serialPort.readline())
        return self._returnStr[:self._returnCnt-1]
152

153
    def set_local(self, hpib_address):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
154
        self._commandStr = "loc "+str(hpib_address)+chr(13)
155
        self._commandCount = self._write_serial(self._commandStr)
156
157


158
class HpibDevice(object):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
159
160
161
162
163
    def __init__(self, hpib_address, port, keepLocal=False,pause=0):
        self._hpib_address = hpib_address
        self._port = port
        self._keepLocal = keepLocal
        self._pause = pause
164

auke.klazema's avatar
auke.klazema committed
165
    def keep_remote(self, keepRemote=False):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
166
        self._keepLocal = not keepRemote
167

auke.klazema's avatar
auke.klazema committed
168
    def set_local(self, set2Local=True):
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
169
        if set2Local:
170
            self._port.set_local(self._hpib_address)
171

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
172
173
    def command(self, commandStr):
        self._port.command(self._hpib_address, commandStr)
auke.klazema's avatar
auke.klazema committed
174
        self.set_local(self._keepLocal)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
175
        time.sleep(self._pause)
176

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
177
178
    def query(self, queryStr):
        self._answerStr = self._port.query(self._hpib_address, queryStr)
auke.klazema's avatar
auke.klazema committed
179
        self.set_local(self._keepLocal)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
180
181
        return self._answerStr

auke.klazema's avatar
auke.klazema committed
182
    def get_devices(self):
183
        return ["Not implemented"]