gpib.py

changeset 12
a04bea92c509
parent 9
3b50c46fca56
equal deleted inserted replaced
11:3ccb0023cf41 12:a04bea92c509
7 import time 7 import time
8 8
9 class ConnectionError(Exception): 9 class ConnectionError(Exception):
10 pass 10 pass
11 11
12 GPIB_CONTROLLER = 1 12 class Constants(object):
13 GPIB_DEVICE = 0 13 def __init__(self):
14 self.constants = {}
15 self.descriptions = {}
16 self.rev_constants = {}
17 for v, k, m in self._constants:
18 self.k = v
19 self.constants[v] = k
20 self.rev_constants[k] = v
21 self.descriptions[v] = m
22
23 def __getitem__(self, k):
24 if isinstance(k, basestring):
25 return self.rev_constants[k]
26 else:
27 return self.constants[k]
14 28
15 # IEEE 488.2 Status Byte constants 29 def get_description(self, k):
16 MAV = 0x10 # Message AVailable: bit 4 of the Status Byte 30 if isinstance(k, basestring):
17 ESB = 0x20 # Event Status Bit: bit 5 of the Status Byte 31 k = self.rev_constants[k]
18 MSS = 0x40 # Master Summary Status bit: bit 6 of the Status Byte (NOT 32 return self.descriptions[k]
19 # sent in response to a serial poll) 33
20 RQS = 0x40 # Request Service: bit 6 of the Status Byte (when sent in
21 # response to a serial poll)
22 34
23 # SESR constants (Standard Event Status Register) 35 class MODE(Constants):
24 PON = 0x80 # Power On: Power has been turned On since last register 36 _constants = [(1, "CONTROLLER", "Set device as Controller in Charge"),
25 # read access 37 (0, "DEVICE", "Set device as simple listener"),
26 URQ = 0x40 # User Request: the user has activated some device control 38 ]
27 # (whatever the Remote Local state is) 39 # TODO
28 CME = 0x20 # Command Error 40 # class STATUS_BYTE(Constants):
29 EXE = 0x10 # Execution Error 41 # # IEEE 488.2 Status Byte constants
30 DDE = 0x08 # Device Dependant Error 42 # MAV = 0x10 # Message AVailable: bit 4 of the Status Byte
31 QYE = 0x04 # QuerY Error (attempt to read data while Output Queue is 43 # ESB = 0x20 # Event Status Bit: bit 5 of the Status Byte
32 # empty, or data in the OQ was lost) 44 # MSS = 0x40 # Master Summary Status bit: bit 6 of the Status Byte (NOT
33 RQC = 0x02 # Request Control: tell the CiC that the device wants to 45 # # sent in response to a serial poll)
34 # become the CiC 46 # RQS = 0x40 # Request Service: bit 6 of the Status Byte (when sent in
35 OPC = 0x01 # Operation Complete: device has completed any pending 47 # # response to a serial poll)
36 # operation (ready to accept new commands). This bit is 48 # class SESR(Constants):
37 # generated in response to a OPC command. 49 # # SESR constants (Standard Event Status Register)
38 50 # PON = 0x80 # Power On: Power has been turned On since last register
39 ##################### 51 # # read access
40 # HP3562A constants 52 # URQ = 0x40 # User Request: the user has activated some device control
41 53 # # (whatever the Remote Local state is)
42 # GPIB buffer size is 3x80 characters lines 54 # CME = 0x20 # Command Error
43 55 # EXE = 0x10 # Execution Error
44 # HP3562A Status Byte 56 # DDE = 0x08 # Device Dependant Error
45 RQS = 0x40 # Request Service: when sent in response to a serial poll 57 # QYE = 0x04 # QuerY Error (attempt to read data while Output Queue is
46 ERR = 0x20 # ERRor: GPIB error 58 # # empty, or data in the OQ was lost)
47 RDY = 0x10 #ReaDY: ready to accept GPIB commands 59 # RQC = 0x02 # Request Control: tell the CiC that the device wants to
48 60 # # become the CiC
49 61 # OPC = 0x01 # Operation Complete: device has completed any pending
50 class GPIB(object): 62 # # operation (ready to accept new commands). This bit is
51 _retries = 15 63 # # generated in response to a OPC command.
52 def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1,
53 address=0, mode=1):
54 """
55 Create a new GPIB controller for the Prologix USB-GPIB device
56 located on serial device 'device'.
57 """
58 self._cnx = serial.Serial(port=device, baudrate=baudrate, timeout=timeout)
59 self._timeout = timeout
60
61 self.set_mode(mode)
62 self.set_address(address)
63
64 def set_address(self, address):
65 """
66 Set the address of the GPIB device:
67
68 - if the device is the Controller In Charge, this is the
69 address of the device commands are sent to,
70
71 - if the device is in GPIB_DEVICE mode, this is its address.
72 """
73 self._set_cmd('addr', address)
74 self._adress = address
75
76 def set_mode(self, mode):
77 """
78 Set GPIB device mode to 'mode':
79
80 - GPIB_CONTROLLER: set the device as the Controller In Charge
81 on the GPIB bus
82
83 - GPIB_DEVICE: set the device as a standard GPIB device on the
84 bus.
85 """
86 self._set_cmd('mode', mode)
87 self._mode = mode
88
89 def set_controler(self):
90 """
91 Set GPIB device the Controller In Charge on the GPIB bus.
92 """
93 self.set_mode(1)
94
95 def set_device(self):
96 """
97 Set the GPIB device as a simple device on the GPIB bus.
98 """
99 self.set_mode(0)
100
101 def send_command(self, cmd):
102 """
103 Send the specified GPIB command on the bus (must be the CIC),
104 and read the answer.
105 """
106 assert self._mode == 1
107 self._cnx.write(cmd+'\r')
108 time.sleep(self._timeout) # required?
109 ret = self._cnx.readlines()
110 return ''.join(ret)
111
112 def check_srq(self):
113 """
114 Check the SRQ line
115 """
116 assert self._mode == 1, "must be the Controller In Charge"
117 self._cnx.write('++srq\r')
118 ret = self._cnx.readline().strip()
119 if ret:
120 return bool(int(ret))
121 return None
122
123 def poll(self):
124 """
125 Poll every address, and return a dictionnary
126 {add: status, ...}
127 """
128 assert self._mode == 1, "must be the Controller In Charge"
129 dico = {}
130 for add in range(31):
131 self._cnx.write('++spoll %d\r'%i)
132 ret = self._cnx.readline().strip()
133 if ret:
134 dico[i] = int(ret)
135 return dico
136 64
137 def _read(self):
138 for i in range(self._retries):
139 rdata = self._cnx.readline()
140 if rdata.strip() != "":
141 break
142 time.sleep(self._timeout)
143 return rdata
144
145 def _set_cmd(self, cmd, value):
146 self._cnx.write('++%s %d\r'%(cmd, value))
147 self._cnx.write('++%s\r'%(cmd))
148 rval = self._read().strip()
149 if not rval.isdigit() or int(rval) != value:
150 raise ConnectionError("Can't set GPIB %s to %s [ret=%s]"%(cmd, value, repr(rval)))
151

mercurial