digilent 0.17.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- digilent/__init__.py +0 -0
- digilent/cgse_explore.py +19 -0
- digilent/cgse_services.py +59 -0
- digilent/settings.yaml +23 -0
- digilent-0.17.4.dist-info/METADATA +23 -0
- digilent-0.17.4.dist-info/RECORD +16 -0
- digilent-0.17.4.dist-info/WHEEL +4 -0
- digilent-0.17.4.dist-info/entry_points.txt +15 -0
- egse/digilent/digilent.py +2809 -0
- egse/digilent/measurpoint/digilent_devif.py +278 -0
- egse/digilent/measurpoint/dt8874/__init__.py +21 -0
- egse/digilent/measurpoint/dt8874/dt8874.py +71 -0
- egse/digilent/measurpoint/dt8874/dt8874.yaml +43 -0
- egse/digilent/measurpoint/dt8874/dt8874_cs.py +335 -0
- egse/digilent/measurpoint/dt8874/dt8874_devif.py +14 -0
- egse/digilent/measurpoint/dt8874/dt8874_protocol.py +148 -0
|
@@ -0,0 +1,2809 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import logging
|
|
3
|
+
import re
|
|
4
|
+
import struct
|
|
5
|
+
|
|
6
|
+
from navdict import navdict
|
|
7
|
+
|
|
8
|
+
from egse.device import DeviceInterface
|
|
9
|
+
from egse.digilent.measurpoint.digilent_devif import DigilentEthernetInterface
|
|
10
|
+
from egse.mixin import dynamic_command, CommandType, add_lf, DynamicCommandMixin
|
|
11
|
+
from egse.setup import load_setup, Setup
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger("egse.digilent.digilent")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ScanRecord:
|
|
17
|
+
def __init__(self, timestamp_s: int, timestamp_ms: int, scan_index: int, num_values: int, values: list[float]):
|
|
18
|
+
"""Initialisation of a scan record.
|
|
19
|
+
|
|
20
|
+
Depending on the configuration of the channel(s), the values are expressed in °C, Ω, or V.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
timestamp_s (int): Timestamp of the scan records, defined as the number of seconds that have elapsed since
|
|
24
|
+
Coordinated Universal Time (UTC).
|
|
25
|
+
timestamp_ms (int): Number of milliseconds after `timestamp_s` at which the sample was acquired.
|
|
26
|
+
scan_index (int): Index of the scan record in the circular buffer.
|
|
27
|
+
num_values (int): Number of single-precision values that follow in the record.
|
|
28
|
+
values (list[float]): Variable size array with a value from each channel that was specified in the channel
|
|
29
|
+
list.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
self._timestamp_s = timestamp_s
|
|
33
|
+
self._timestamp_ms = timestamp_ms
|
|
34
|
+
self._scan_index = scan_index
|
|
35
|
+
self._num_values = num_values
|
|
36
|
+
self._values = values
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def timestamp(self) -> float:
|
|
40
|
+
"""Returns the timestamp of the scan records, defined as the number of seconds that have elapsed since UTC.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Timestamp of the scan records, defined as the number of seconds that have elapsed since UTC.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
return self._timestamp_s + self._timestamp_ms / 1000
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def timestamp_s(self) -> int:
|
|
50
|
+
"""Returns the timestamp of the scan recordsm defined as the number of seconds that have elapsed since UTC.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
Timestamp of the scan recordsm defined as the number of seconds that have elapsed since UTC.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
return self._timestamp_s
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def timestamp_ms(self) -> int:
|
|
60
|
+
"""Returns the number of milliseconds after `timestamp_s` at which the sample was acquired.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Number of milliseconds after `timestamp_s` at which the sample was acquired.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
return self._timestamp_ms
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def scan_index(self) -> int:
|
|
70
|
+
"""Returns the index of the scan record in the circular buffer.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Index of the scan record in the circular buffer.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
return self._scan_index
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def num_values(self):
|
|
80
|
+
"""Returns the number of single-precision values that follow in the record.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Number of single-precision values that follow in the record.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
return self._num_values
|
|
87
|
+
|
|
88
|
+
def get_values(self):
|
|
89
|
+
"""Returns the array with a value from each channel that was specified in the channel list.
|
|
90
|
+
|
|
91
|
+
Depending on the configuration of the channel(s), the values are expressed in °C, Ω, or V.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Variable size array with a value from each channel that was specified in the channel list.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
return self._values
|
|
98
|
+
|
|
99
|
+
def get_value(self, index: int):
|
|
100
|
+
"""Returns the value at the specified index.
|
|
101
|
+
|
|
102
|
+
Note that the index does not necessarily correspond to the channel index.
|
|
103
|
+
|
|
104
|
+
Depending on the configuration of the channel(s), the value is expressed in °C, Ω, or V.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
index (int): Index of the value to return.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
Value at the specified index.
|
|
111
|
+
"""
|
|
112
|
+
return self._values[index]
|
|
113
|
+
|
|
114
|
+
def get_datetime(self) -> tuple[datetime.datetime, str, str]:
|
|
115
|
+
"""Returns the datetime, date, and time of the scan record.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
Tuple containing the datetime of the scan record, the date (format: %Y%m%d), and the time (format: %H:%M:%S).
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
dt = datetime.datetime.fromtimestamp(self.timestamp, datetime.UTC)
|
|
122
|
+
|
|
123
|
+
return dt, dt.strftime("%Y%m%d"), dt.strftime("%H:%M:%S")
|
|
124
|
+
|
|
125
|
+
def __repr__(self) -> str:
|
|
126
|
+
"""Returns a string representation of the scan record.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
String representation of the scan record.
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
_, date, time = self.get_datetime()
|
|
133
|
+
|
|
134
|
+
response = "ScanRecord:\n"
|
|
135
|
+
response += f" Timestamp [s] (raw): {self._timestamp_s} (0x{self._timestamp_s:08x})\n"
|
|
136
|
+
response += f" Timestamp [ms]: {self._timestamp_ms} (0x{self._timestamp_ms:08x})\n"
|
|
137
|
+
response += f" Date: {date}\n"
|
|
138
|
+
response += f" Time: {time}\n"
|
|
139
|
+
response += f" Datetime: {datetime.datetime.fromtimestamp(self.timestamp, datetime.UTC)}\n"
|
|
140
|
+
response += f" Scan index: {self._scan_index}\n"
|
|
141
|
+
response += f" Number of values: {self._num_values}\n"
|
|
142
|
+
|
|
143
|
+
if self.num_values == 1:
|
|
144
|
+
response += f" Value: {self._values[0]}\n"
|
|
145
|
+
else:
|
|
146
|
+
response += f" Values: {self._values}\n"
|
|
147
|
+
|
|
148
|
+
return response
|
|
149
|
+
|
|
150
|
+
def __str__(self) -> str:
|
|
151
|
+
"""Returns a printable string representation of the scan record.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
Printable string representation of the scan record.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
return self.__repr__()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class ScanRecords:
|
|
161
|
+
def __init__(self, scan_records: list[ScanRecord]):
|
|
162
|
+
"""Initialisation of a collection of scan records.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
scan_records (list[ScanRecord]): List of scan records.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
self._scan_records = scan_records
|
|
169
|
+
|
|
170
|
+
def get_num_scan_records(self) -> int:
|
|
171
|
+
"""Returns the number of scan records in the collection."""
|
|
172
|
+
return len(self._scan_records)
|
|
173
|
+
|
|
174
|
+
def get_scan_record(self, index: int) -> ScanRecord:
|
|
175
|
+
"""Returns the scan record at the specified index.
|
|
176
|
+
|
|
177
|
+
Note that the index does not necessarily correspond to the index in the circular buffer.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
index (int): Index of the scan record to return.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
Scan record at the specified index.
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
return self._scan_records[index]
|
|
187
|
+
|
|
188
|
+
def __repr__(self):
|
|
189
|
+
"""Returns a string representation of the collection of scan records.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
String representation of the collection of scan records.
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
response = ""
|
|
196
|
+
|
|
197
|
+
for index, scan_record in enumerate(self._scan_records):
|
|
198
|
+
_, date, time = scan_record.get_datetime()
|
|
199
|
+
|
|
200
|
+
response += f"ScanRecord {index}:\n"
|
|
201
|
+
response += f" Timestamp [s] (raw): {scan_record.timestamp_s} (0x{scan_record.timestamp_s:08x})\n"
|
|
202
|
+
response += f" Timestamp [ms]: {scan_record.timestamp_ms} (0x{scan_record.timestamp_ms:08x})\n"
|
|
203
|
+
response += f" Date: {date}\n"
|
|
204
|
+
response += f" Time: {time}\n"
|
|
205
|
+
response += (
|
|
206
|
+
f" Datetime: {datetime.datetime.fromtimestamp(scan_record.timestamp, datetime.UTC)}\n"
|
|
207
|
+
)
|
|
208
|
+
response += f" Scan index: {scan_record.scan_index}\n"
|
|
209
|
+
response += f" Number of values: {scan_record.num_values}\n"
|
|
210
|
+
|
|
211
|
+
if scan_record.num_values == 1:
|
|
212
|
+
response += f" Value: {scan_record.get_value(0)}\n\n"
|
|
213
|
+
else:
|
|
214
|
+
response += f" Values: {scan_record.get_values()}\n\n"
|
|
215
|
+
|
|
216
|
+
return response
|
|
217
|
+
|
|
218
|
+
def __str__(self):
|
|
219
|
+
"""Returns a printable string representation of the collection of scan records.
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
Printable string representation of the collection of scan records.
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
return self.__repr__()
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def split_result_on_comma(response: str) -> tuple[str, ...]:
|
|
229
|
+
"""Splits the given response string on commas.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
response (str): Response string to split.
|
|
233
|
+
|
|
234
|
+
Returns:
|
|
235
|
+
Tuple of strings split on commas.
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
return tuple(response.split(","))
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def int_to_bool(response: str) -> bool:
|
|
242
|
+
"""Converts the given response string to a boolean.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
response (str): Response string to convert.
|
|
246
|
+
|
|
247
|
+
Returns:
|
|
248
|
+
bool: Boolean value converted from the response string.
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
return bool(int(response))
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def to_int(response: str) -> int:
|
|
255
|
+
"""Converts the given response string to an integer.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
response (str): Response string to convert.
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Integer value converted from the response string.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
return int(response)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def to_float(response: str) -> float:
|
|
268
|
+
"""Converts the given response string to a float.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
response (str): Response string to convert.
|
|
272
|
+
|
|
273
|
+
Returns:
|
|
274
|
+
Float value converted from the response string.
|
|
275
|
+
"""
|
|
276
|
+
|
|
277
|
+
return float(response)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def split_on_comma_to_int(response: str) -> tuple[int, ...]:
|
|
281
|
+
"""Splits the given response string on commas.
|
|
282
|
+
|
|
283
|
+
Args:
|
|
284
|
+
response (str): Response string to split.
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
Tuple of integers split on commas.
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
response = split_result_on_comma(response)
|
|
291
|
+
|
|
292
|
+
return tuple(int(x) for x in response)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def format_to_time(response: str) -> str:
|
|
296
|
+
"""Converts the given response string to time.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
response (str): Response string to convert.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Time string converted from the response string.
|
|
303
|
+
"""
|
|
304
|
+
|
|
305
|
+
hours, minutes, seconds = split_result_on_comma(response)
|
|
306
|
+
|
|
307
|
+
return f"{hours.zfill(2)}:{minutes.zfill(2)}:{seconds.zfill(2)}"
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def to_date(response: str) -> datetime.datetime:
|
|
311
|
+
"""Converts the given response string to a date.
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
response (str): Response string to convert.
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Date string converted from the response string.
|
|
318
|
+
"""
|
|
319
|
+
|
|
320
|
+
return datetime.datetime.strptime(response, "%Y,%m,%d")
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def parse_error(response: str) -> tuple[int, str]:
|
|
324
|
+
"""Converts the given response string of a tuple of an error code and the corresponding error message.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
response (str): Response string to convert
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
Tuple of an error code and the corresponding error message.
|
|
331
|
+
"""
|
|
332
|
+
code, description = split_result_on_comma(response)
|
|
333
|
+
|
|
334
|
+
return int(code), description
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def parse_single_measurement(response: bytes) -> tuple[float, ...]:
|
|
338
|
+
"""Converts the given response bytes to a float.
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
response (bytes): Response bytes to convert.
|
|
342
|
+
|
|
343
|
+
Returns:
|
|
344
|
+
Depending on the configuration of the channel(s), the values are expressed in °C, Ω, or V.
|
|
345
|
+
|
|
346
|
+
"""
|
|
347
|
+
|
|
348
|
+
endian_char = ">"
|
|
349
|
+
offset = 0
|
|
350
|
+
|
|
351
|
+
binary_data = response[3:-1]
|
|
352
|
+
|
|
353
|
+
values = []
|
|
354
|
+
|
|
355
|
+
while offset + 4 <= len(binary_data):
|
|
356
|
+
# Unpack float values
|
|
357
|
+
|
|
358
|
+
value = struct.unpack_from(f"{endian_char}f", binary_data, offset)[0]
|
|
359
|
+
offset += 4
|
|
360
|
+
|
|
361
|
+
values.append(value)
|
|
362
|
+
|
|
363
|
+
return tuple(values)
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
def parse_scan_records(response: bytes) -> ScanRecords:
|
|
367
|
+
"""Converts the given response bytes to a collection of scan records.
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
response (bytes): Response bytes to convert.
|
|
371
|
+
|
|
372
|
+
Returns:
|
|
373
|
+
Collection of scan records.
|
|
374
|
+
"""
|
|
375
|
+
|
|
376
|
+
# Skip the header
|
|
377
|
+
|
|
378
|
+
if response.startswith(b"#"):
|
|
379
|
+
header_end = 6
|
|
380
|
+
binary_data = response[header_end:-1] # -1 to skip trailing newline
|
|
381
|
+
else:
|
|
382
|
+
binary_data = response
|
|
383
|
+
|
|
384
|
+
endian_char = ">"
|
|
385
|
+
offset = 0
|
|
386
|
+
record_num = 1
|
|
387
|
+
|
|
388
|
+
scan_records = []
|
|
389
|
+
|
|
390
|
+
while offset + 16 <= len(binary_data):
|
|
391
|
+
# Unpack header (4 unsigned longs)
|
|
392
|
+
header = struct.unpack_from(f">IIII", binary_data, offset)
|
|
393
|
+
timestamp_s, timestamp_ms, scan_index, num_values = header
|
|
394
|
+
|
|
395
|
+
offset += 16
|
|
396
|
+
|
|
397
|
+
# Unpack float values
|
|
398
|
+
|
|
399
|
+
values = []
|
|
400
|
+
|
|
401
|
+
if 0 < num_values < 100: # Sanity check
|
|
402
|
+
for i in range(num_values):
|
|
403
|
+
if offset + 4 <= len(binary_data):
|
|
404
|
+
value = struct.unpack_from(f"{endian_char}f", binary_data, offset)[0]
|
|
405
|
+
offset += 4
|
|
406
|
+
|
|
407
|
+
values.append(value)
|
|
408
|
+
else:
|
|
409
|
+
break
|
|
410
|
+
|
|
411
|
+
scan_record = ScanRecord(timestamp_s, timestamp_ms, scan_index, num_values, values)
|
|
412
|
+
scan_records.append(scan_record)
|
|
413
|
+
|
|
414
|
+
record_num += 1
|
|
415
|
+
|
|
416
|
+
return ScanRecords(scan_records)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def get_channel_list(channel_list: str) -> list[str]:
|
|
420
|
+
"""Generates a list of channel names from a given channel list.
|
|
421
|
+
|
|
422
|
+
The "names" of the channels are the indices of the channels, as strings.
|
|
423
|
+
|
|
424
|
+
Args:
|
|
425
|
+
channel_list: a channel list as understood by the SCPI commands of DAQ6510.
|
|
426
|
+
|
|
427
|
+
Returns:
|
|
428
|
+
List of channel names.
|
|
429
|
+
"""
|
|
430
|
+
|
|
431
|
+
match = re.match(r"\(@(.*)\)", channel_list)
|
|
432
|
+
group = match.groups()[0]
|
|
433
|
+
|
|
434
|
+
parts = group.replace(" ", "").split(",")
|
|
435
|
+
names = []
|
|
436
|
+
for part in parts:
|
|
437
|
+
if ":" in part:
|
|
438
|
+
channels = part.split(":")
|
|
439
|
+
names.extend(str(ch) for ch in range(int(channels[0]), int(channels[1]) + 1))
|
|
440
|
+
else:
|
|
441
|
+
names.append(part)
|
|
442
|
+
|
|
443
|
+
return names
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
class DigilentInterface(DeviceInterface):
|
|
447
|
+
"""Base class for Digilent TEMPpoint, VOLTpoint, and MEASURpoint instruments."""
|
|
448
|
+
|
|
449
|
+
def __init__(self):
|
|
450
|
+
super().__init__()
|
|
451
|
+
|
|
452
|
+
self.channel_lists = navdict()
|
|
453
|
+
self.channels = navdict()
|
|
454
|
+
|
|
455
|
+
def config_channels(self, setup: Setup = None):
|
|
456
|
+
"""Reads the channel configuration from the setup + apply it to the device.
|
|
457
|
+
|
|
458
|
+
Args
|
|
459
|
+
setup (Setup): Setup from which load read the channel configuration.
|
|
460
|
+
"""
|
|
461
|
+
|
|
462
|
+
self.channel_lists = navdict()
|
|
463
|
+
self.channels = navdict()
|
|
464
|
+
|
|
465
|
+
setup = setup or load_setup()
|
|
466
|
+
|
|
467
|
+
try:
|
|
468
|
+
channel_config = setup.gse.dt8874
|
|
469
|
+
|
|
470
|
+
if "RTD" in channel_config:
|
|
471
|
+
self.channels["RTD"] = navdict()
|
|
472
|
+
self.channel_lists["RTD"] = navdict()
|
|
473
|
+
|
|
474
|
+
for rtd_type in channel_config.RTD:
|
|
475
|
+
if rtd_type != "channels":
|
|
476
|
+
channels = channel_config.RTD[rtd_type].channels
|
|
477
|
+
|
|
478
|
+
self.channels.RTD[rtd_type] = channels
|
|
479
|
+
self.channel_lists.RTD[rtd_type] = get_channel_list(channels)
|
|
480
|
+
|
|
481
|
+
self.set_rtd_temperature_channels(rtd_type=rtd_type, channels=channels)
|
|
482
|
+
|
|
483
|
+
if "THERMOCOUPLE" in channel_config:
|
|
484
|
+
self.channels["THERMOCOUPLE"] = navdict()
|
|
485
|
+
self.channel_lists["THERMOCOUPLE"] = navdict()
|
|
486
|
+
|
|
487
|
+
for tc_type in channel_config.THERMOCOUPLE:
|
|
488
|
+
if tc_type != "channels":
|
|
489
|
+
channels = channel_config.THERMOCOUPLE[tc_type].channels
|
|
490
|
+
|
|
491
|
+
self.channels.RTD[tc_type] = channels
|
|
492
|
+
self.channel_lists.RTD[tc_type] = get_channel_list(channels)
|
|
493
|
+
|
|
494
|
+
self.set_thermocouple_temperature_channels(rtd_type=tc_type, channels=channels)
|
|
495
|
+
|
|
496
|
+
if "RESISTANCE" in channel_config:
|
|
497
|
+
channels = channel_config.RESISTANCE.channels
|
|
498
|
+
|
|
499
|
+
self.channels["RESISTANCE"] = channels
|
|
500
|
+
self.channel_lists["RESISTANCE"] = get_channel_list(channels)
|
|
501
|
+
|
|
502
|
+
self.set_resistance_channels(channels=channels)
|
|
503
|
+
|
|
504
|
+
if "VOLTAGE" in channel_config:
|
|
505
|
+
channels = channel_config.VOLTAGE.channels
|
|
506
|
+
|
|
507
|
+
self.channels["VOLTAGE"] = channels
|
|
508
|
+
self.channel_lists["VOLTAGE"] = get_channel_list(channels)
|
|
509
|
+
|
|
510
|
+
self.set_voltage_channels(channels=channels)
|
|
511
|
+
|
|
512
|
+
if "VOLTAGE_RANGE" in channel_config:
|
|
513
|
+
channels = channel_config.VOLTAGE_RANGE.channels
|
|
514
|
+
|
|
515
|
+
self.channels["VOLTAGE_RANGE"] = channels
|
|
516
|
+
self.channel_lists["VOLTAGE_RANGE"] = get_channel_list(channels)
|
|
517
|
+
|
|
518
|
+
self.set_voltage_range_channels(channels=channels)
|
|
519
|
+
|
|
520
|
+
if len(self.channel_lists) == 0:
|
|
521
|
+
logger.warning("No channels configured, check the log messages.")
|
|
522
|
+
except AttributeError:
|
|
523
|
+
logger.warning(f"Couldn't configure the channels, check the log messages.")
|
|
524
|
+
|
|
525
|
+
@dynamic_command(
|
|
526
|
+
cmd_type=CommandType.WRITE,
|
|
527
|
+
cmd_string="*CLS",
|
|
528
|
+
process_cmd_string=add_lf,
|
|
529
|
+
)
|
|
530
|
+
def clear_status(self) -> None:
|
|
531
|
+
"""Clears all event registers summarised in the Status Byte (STB) register.
|
|
532
|
+
|
|
533
|
+
All queues that are summarised in the Status Byte (STB) register, except the output queue, are emptied. The
|
|
534
|
+
device is forced into the operation complete idle state.
|
|
535
|
+
"""
|
|
536
|
+
|
|
537
|
+
pass
|
|
538
|
+
|
|
539
|
+
@dynamic_command(
|
|
540
|
+
cmd_type=CommandType.WRITE,
|
|
541
|
+
cmd_string="*ESE",
|
|
542
|
+
process_cmd_string=add_lf,
|
|
543
|
+
)
|
|
544
|
+
def std_event_status_enable_register(self, bits: int) -> None:
|
|
545
|
+
"""Enables specified bits in the Standard Event Status Enable register.
|
|
546
|
+
|
|
547
|
+
The bits in the Standard Event Status Enable register are:
|
|
548
|
+
|
|
549
|
+
| Bit | Binary weight | Description |
|
|
550
|
+
| --- | --- | --- |
|
|
551
|
+
| 0 | 1 | OPC (Operation complete) |
|
|
552
|
+
| 1 | 2 | RQC (Request control) |
|
|
553
|
+
| 2 | 4 | QYE (Query error) |
|
|
554
|
+
| 3 | 8 | DDE (Device-dependent error) |
|
|
555
|
+
| 4 | 16 | E (Execution error) |
|
|
556
|
+
| 5 | 32 | CME (Command error) |
|
|
557
|
+
| 6 | 64 | NU (Not used) |
|
|
558
|
+
| 7 | 128 | PON (Power on) |
|
|
559
|
+
|
|
560
|
+
Refer to IEEE Std 488.2-1992, Sect. 11.5.1.3, for more information.
|
|
561
|
+
|
|
562
|
+
This is a password-protected command.
|
|
563
|
+
|
|
564
|
+
Args:
|
|
565
|
+
bits (int): Integer value expressed in base 2 (binary) that represents the weighted bit value of the
|
|
566
|
+
Standard Event Status Enable register and the binary-weighted decimal value for each bit.
|
|
567
|
+
|
|
568
|
+
Examples:
|
|
569
|
+
The following command enables bits 0, 2, 3, 4, 5, and 7 of the Standard Event Status Enable register:
|
|
570
|
+
> *ESE 189
|
|
571
|
+
"""
|
|
572
|
+
|
|
573
|
+
pass
|
|
574
|
+
|
|
575
|
+
@dynamic_command(
|
|
576
|
+
cmd_type=CommandType.TRANSACTION,
|
|
577
|
+
cmd_string="*ESE?",
|
|
578
|
+
process_cmd_string=add_lf,
|
|
579
|
+
process_response=to_int,
|
|
580
|
+
)
|
|
581
|
+
def get_std_event_status_enable_register(self) -> int:
|
|
582
|
+
"""Returns the current value of the Standard Event Status Enable register.
|
|
583
|
+
|
|
584
|
+
The bits in the Standard Event Status Enable register are:
|
|
585
|
+
|
|
586
|
+
| Bit | Binary weight | Description |
|
|
587
|
+
| --- | --- | --- |
|
|
588
|
+
| 0 | 1 | OPC (Operation complete) |
|
|
589
|
+
| 1 | 2 | RQC (Request control) |
|
|
590
|
+
| 2 | 4 | QYE (Query error) |
|
|
591
|
+
| 3 | 8 | DDE (Device-dependent error) |
|
|
592
|
+
| 4 | 16 | E (Execution error) |
|
|
593
|
+
| 5 | 32 | CME (Command error) |
|
|
594
|
+
| 6 | 64 | NU (Not used) |
|
|
595
|
+
| 7 | 128 | PON (Power on) |
|
|
596
|
+
|
|
597
|
+
Refer to IEEE Std 488.2-1992, Sect. 11.4.2.3.2, and IEEE Std 488.2, Sect. 8.7.1, for more information.
|
|
598
|
+
|
|
599
|
+
Returns:
|
|
600
|
+
Integer value expressed in base 2 (binary) that represents the weighted bit value of the Standard Event
|
|
601
|
+
Status Enable register and the binary-weighted decimal value for each bit. Values range from 0 to 255.
|
|
602
|
+
|
|
603
|
+
Examples:
|
|
604
|
+
The following command queries the Standard Event Status Enable register:
|
|
605
|
+
|
|
606
|
+
> *ESE?
|
|
607
|
+
< 189
|
|
608
|
+
|
|
609
|
+
This value indicates that bits 0, 2, 3, 4, 5, and 7 of the Standard Event Status Enable register are enabled.
|
|
610
|
+
"""
|
|
611
|
+
|
|
612
|
+
pass
|
|
613
|
+
|
|
614
|
+
@dynamic_command(
|
|
615
|
+
cmd_type=CommandType.TRANSACTION,
|
|
616
|
+
cmd_string="*ESR?",
|
|
617
|
+
process_cmd_string=add_lf,
|
|
618
|
+
process_response=to_int,
|
|
619
|
+
)
|
|
620
|
+
def get_std_event_status_register(self) -> int:
|
|
621
|
+
"""Returns the current value of the Standard Event Status register.
|
|
622
|
+
|
|
623
|
+
The bits in the Standard Event Status register are:
|
|
624
|
+
|
|
625
|
+
| Bit | Binary weight | Description |
|
|
626
|
+
| --- | --- | --- |
|
|
627
|
+
| 0 | 1 | OPC (Operation complete) |
|
|
628
|
+
| 1 | 2 | RQC (Request control) |
|
|
629
|
+
| 2 | 4 | QYE (Query error) |
|
|
630
|
+
| 3 | 8 | DDE (Device-dependent error) |
|
|
631
|
+
| 4 | 16 | E (Execution error) |
|
|
632
|
+
| 5 | 32 | CME (Command error) |
|
|
633
|
+
| 6 | 64 | NU (Not used) |
|
|
634
|
+
| 7 | 128 | PON (Power on) |
|
|
635
|
+
|
|
636
|
+
Bits in the Standard Event Status register should be unmasked by settings the corresponding bit in the Standard
|
|
637
|
+
Status Enable register. On power-up, the Standard Event Status Enable register is zero; therefore, all bits in
|
|
638
|
+
the Standard Event Status register are masked.
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
Returns:
|
|
642
|
+
Integer value expressed in base 2 (binary) that represents the weighted bit value of the Standard Event
|
|
643
|
+
Status register and the binary-weighted decimal value for each bit. Values range from 0 to 255.
|
|
644
|
+
|
|
645
|
+
Examples:
|
|
646
|
+
The following example unmasks all error bits in the Standard Event Status register:
|
|
647
|
+
|
|
648
|
+
> *ESE?; *ESE 255; *ESE?
|
|
649
|
+
< 0; ;255
|
|
650
|
+
|
|
651
|
+
Then, an illegal command it sent and the Standard Event Status register is queried; a value of 32 is
|
|
652
|
+
returned, indicating that bit 5 (Command error) of the Standard Event Status register was set:
|
|
653
|
+
|
|
654
|
+
> *bad
|
|
655
|
+
> *ESR?
|
|
656
|
+
< 32
|
|
657
|
+
|
|
658
|
+
In the following example, the scan rate is set to an illegal value; a value of 16 is returned, indicating
|
|
659
|
+
that bit 4 (Execution error) of the Standard Event Status register was set:
|
|
660
|
+
|
|
661
|
+
> :CONF:SCAN:RATe:HZ 50
|
|
662
|
+
> *ESR?
|
|
663
|
+
< 16
|
|
664
|
+
"""
|
|
665
|
+
|
|
666
|
+
pass
|
|
667
|
+
|
|
668
|
+
@dynamic_command(
|
|
669
|
+
cmd_type=CommandType.TRANSACTION,
|
|
670
|
+
cmd_string="*IDN?",
|
|
671
|
+
process_cmd_string=add_lf,
|
|
672
|
+
process_response=split_result_on_comma,
|
|
673
|
+
)
|
|
674
|
+
def get_id(self) -> tuple[str, str, str, str]:
|
|
675
|
+
"""Returns the unique identifier of your TEMPpoint, VOLTpoint, or MEASURpoint LXI instrument.
|
|
676
|
+
|
|
677
|
+
Refer to IEEE 488.2-1992, Sects. 6.5.7.5 snd 10.14, for more information.
|
|
678
|
+
|
|
679
|
+
Returns:
|
|
680
|
+
Manufacturer: Defines the manufacturer of the instrument (Data Translation).
|
|
681
|
+
Model: Identifies the model of the instrument.
|
|
682
|
+
Serial number: Identifies the serial number of the instrument.
|
|
683
|
+
Firmware revision: Identifies the version of the firmware that is loaded on the instrument.
|
|
684
|
+
|
|
685
|
+
Examples:
|
|
686
|
+
> *IDN?
|
|
687
|
+
< Data Translation,DT8874-08T-00R-08V,201129241,2.2.0.0
|
|
688
|
+
This response indicates that Data Translation is the manufacturer of the device, DT8874-08T-00R-08V is the
|
|
689
|
+
model of the instrument (where 08T indicates that the instrument contains 8 thermocouple channels, 00R
|
|
690
|
+
indicates that the instrument contains 0 RTD channels, and 08V indicates that the instrument contains 8
|
|
691
|
+
voltage channels), 201129241 is the serial number of the instrument, and 2.2.0.0 is the version of the
|
|
692
|
+
firmware.
|
|
693
|
+
"""
|
|
694
|
+
|
|
695
|
+
pass
|
|
696
|
+
|
|
697
|
+
@dynamic_command(
|
|
698
|
+
cmd_string="*RST",
|
|
699
|
+
cmd_type=CommandType.WRITE,
|
|
700
|
+
process_cmd_string=add_lf,
|
|
701
|
+
)
|
|
702
|
+
def reset(self) -> None:
|
|
703
|
+
"""Resets the instrument.
|
|
704
|
+
|
|
705
|
+
Clears the Standard Event Status register, message queue, error queue, and Status Byte register, and stops any scans that are in progress.
|
|
706
|
+
|
|
707
|
+
This command has no effect on the instrument's password or password enable/disable state.
|
|
708
|
+
|
|
709
|
+
Refer to IEE 388.2-1992, Sect. 10.32, for more information.
|
|
710
|
+
"""
|
|
711
|
+
|
|
712
|
+
pass
|
|
713
|
+
|
|
714
|
+
@dynamic_command(
|
|
715
|
+
cmd_type=CommandType.TRANSACTION,
|
|
716
|
+
cmd_string="*STB?",
|
|
717
|
+
process_cmd_string=add_lf,
|
|
718
|
+
process_response=to_int,
|
|
719
|
+
)
|
|
720
|
+
def get_status_byte_register(self) -> int:
|
|
721
|
+
"""Returns the current value of the Status Byte register.
|
|
722
|
+
|
|
723
|
+
The weighted sum of the bit values of hte Status Byte register is returned, ranging from 0 to 255. The
|
|
724
|
+
following bits, described in 1999 SCPI Syntax & Stype, Sect. 9, are supported:
|
|
725
|
+
|
|
726
|
+
| Bit | Binary weight | Description |
|
|
727
|
+
| --- | --- | --- |
|
|
728
|
+
| 7 | 128 | Summary of device-dependent Operation Status register |
|
|
729
|
+
| 5 | 32 | Event Status Bit Summary (ESB); "1" = ESR is non-zero, "0" otherwise |
|
|
730
|
+
| 4 | 16 | Message Available Queue Summary (MAV); "1" = message queue not empty |
|
|
731
|
+
| 2 | 4 | Error/Event Queue Summary; "1" = error queue not empty |
|
|
732
|
+
|
|
733
|
+
Refer to IEE 388.2-1992, Sect. 10.36, for more information.
|
|
734
|
+
|
|
735
|
+
Examples:
|
|
736
|
+
The following example shows a query that is correct and causes no errors:
|
|
737
|
+
|
|
738
|
+
> *IDN?;*ESR?;*STB?
|
|
739
|
+
< Data Translation,DT8874-08T-00R-08V,-1,1.2;16
|
|
740
|
+
|
|
741
|
+
This example shows an illegal command being sent, and the status of the Status Byte register and the error
|
|
742
|
+
queue:
|
|
743
|
+
|
|
744
|
+
> bad
|
|
745
|
+
> *STB?
|
|
746
|
+
< 16
|
|
747
|
+
|
|
748
|
+
A value of 36 indicates that bit 5 (Standard Event Status Bit Summary) and 2 (Error/Event Queue Summary) of
|
|
749
|
+
the Status Byte register are set.
|
|
750
|
+
|
|
751
|
+
The following example shows the status of the Event Status register:
|
|
752
|
+
|
|
753
|
+
> *ESR?
|
|
754
|
+
< 32
|
|
755
|
+
|
|
756
|
+
A value of 32 indicates that bit 5 (Command Error) of the Event Status register is set. The following
|
|
757
|
+
updates the status of the Status Byte register:
|
|
758
|
+
|
|
759
|
+
> *STB?
|
|
760
|
+
< 4
|
|
761
|
+
|
|
762
|
+
A value of 4 indicates that bit 2 (Error/Event Queue Summary) of the Status Byte register is set. The
|
|
763
|
+
following shows the error codes that are returned and updates that status of the Status Byte register:
|
|
764
|
+
|
|
765
|
+
> :SYST:ERR?
|
|
766
|
+
< -110,"Command header error;bad"
|
|
767
|
+
> :SYST:ERR?
|
|
768
|
+
< 0;"No error"
|
|
769
|
+
> *STB?
|
|
770
|
+
< 0
|
|
771
|
+
"""
|
|
772
|
+
|
|
773
|
+
pass
|
|
774
|
+
|
|
775
|
+
@dynamic_command(
|
|
776
|
+
cmd_string="STATus:OPERation:CONDition?",
|
|
777
|
+
cmd_type=CommandType.TRANSACTION,
|
|
778
|
+
process_cmd_string=add_lf,
|
|
779
|
+
process_response=to_int,
|
|
780
|
+
)
|
|
781
|
+
def get_operation_condition(self) -> int:
|
|
782
|
+
"""Returns the current value of the Operation Status register.
|
|
783
|
+
|
|
784
|
+
It is a 14-bit value, for which only the following bits can be set to "1":
|
|
785
|
+
|
|
786
|
+
- Bit 4 (binary weight: 16):
|
|
787
|
+
- If this bit is 1:
|
|
788
|
+
- Bit 5 is 1: Waiting for trigger,
|
|
789
|
+
- Bit 5 is 0: Scanning in progress,
|
|
790
|
+
- If this bit is 0:
|
|
791
|
+
- Bit 5 is 0: Scanning is stopped.
|
|
792
|
+
- Bit 5 (binary weight: 32):
|
|
793
|
+
- If this bit is 1:
|
|
794
|
+
- Bit 4 is 1: Waiting for trigger,
|
|
795
|
+
- If this bit is 0:
|
|
796
|
+
- Bit 4 is 1: Scanning in progress,
|
|
797
|
+
- Bit 4 is 0: Scanning is stopped.
|
|
798
|
+
|
|
799
|
+
Examples:
|
|
800
|
+
The following example shows the status of the Operation Status register and the Status Byte register when a
|
|
801
|
+
scan is in progress and a software trigger is used:
|
|
802
|
+
|
|
803
|
+
> :STAT:OPER:COND?
|
|
804
|
+
< 16
|
|
805
|
+
> *STB?
|
|
806
|
+
< 128
|
|
807
|
+
|
|
808
|
+
A value of 16 indicates that bit 4 (Scan status) of the Operation Status register is set to 1. A value of
|
|
809
|
+
128 indicates that bit 7 (Operation Status Register Summary) of the Status Byte register is set to 1.
|
|
810
|
+
|
|
811
|
+
The following example shows the status of the Operation Status register and the Status Byte register when
|
|
812
|
+
a scan is in progress and the instrument is waiting for an external digital trigger:
|
|
813
|
+
|
|
814
|
+
> :STAT:OPER:COND?
|
|
815
|
+
< 48
|
|
816
|
+
> *STB?
|
|
817
|
+
< 128
|
|
818
|
+
|
|
819
|
+
A value of 48 indicates that bit (Scan Status) and bit 5 (Trigger Status) of the Operation Status are set
|
|
820
|
+
to 1. A value of 128 indicates that bit 7 (Operation Status Register Summary) of the Status Byte register
|
|
821
|
+
is set to 1.
|
|
822
|
+
|
|
823
|
+
The following example shows the status of the Operation Status register and the Status Byte register when
|
|
824
|
+
the instrument is idle:
|
|
825
|
+
|
|
826
|
+
> :STAT:OPER:COND?
|
|
827
|
+
< 0
|
|
828
|
+
> *STB?
|
|
829
|
+
"""
|
|
830
|
+
pass
|
|
831
|
+
|
|
832
|
+
@dynamic_command(
|
|
833
|
+
cmd_string=":STATus:SCAn?",
|
|
834
|
+
cmd_type=CommandType.TRANSACTION,
|
|
835
|
+
process_cmd_string=add_lf,
|
|
836
|
+
process_response=split_on_comma_to_int,
|
|
837
|
+
)
|
|
838
|
+
def get_scan_record_status(self) -> tuple[int, int]:
|
|
839
|
+
"""Returns the indices of the chronologically oldest and most recent scan records in the instrument's FIFO.
|
|
840
|
+
|
|
841
|
+
If the circular buffer is empty (because a scan has not been started, or started and stopped), both indices
|
|
842
|
+
will be 0. Otherwise, the indices will be non-zero.
|
|
843
|
+
|
|
844
|
+
Returns:
|
|
845
|
+
Index of the chronologically oldest scan record in the instrument's circular buffer.
|
|
846
|
+
Index of the chronologically most recent scan record in the instrument's circular buffer.
|
|
847
|
+
|
|
848
|
+
Examples:
|
|
849
|
+
The following example shows that starting index (1001) and ending index (1050) when the circular buffer
|
|
850
|
+
consists of scan records 1001 to 1050:
|
|
851
|
+
|
|
852
|
+
> :STAT:SCAn?
|
|
853
|
+
< 1001,1050
|
|
854
|
+
"""
|
|
855
|
+
|
|
856
|
+
pass
|
|
857
|
+
|
|
858
|
+
@dynamic_command(
|
|
859
|
+
cmd_string=":SYSTem:CALibrate",
|
|
860
|
+
cmd_type=CommandType.WRITE,
|
|
861
|
+
process_cmd_string=add_lf,
|
|
862
|
+
)
|
|
863
|
+
def auto_calibrate(self) -> None:
|
|
864
|
+
"""Auto-calibrates (auto-zeroes) all analogue input channels on the instrument.
|
|
865
|
+
|
|
866
|
+
This is a password-protected command.
|
|
867
|
+
|
|
868
|
+
Examples:
|
|
869
|
+
This command auto-zeroes all analogue input channels on the instrument:
|
|
870
|
+
|
|
871
|
+
> :SYST:CAL
|
|
872
|
+
"""
|
|
873
|
+
|
|
874
|
+
pass
|
|
875
|
+
|
|
876
|
+
@dynamic_command(
|
|
877
|
+
cmd_string=":SYSTem:DATE?",
|
|
878
|
+
cmd_type=CommandType.TRANSACTION,
|
|
879
|
+
process_cmd_string=add_lf,
|
|
880
|
+
process_response=to_date,
|
|
881
|
+
)
|
|
882
|
+
def get_date(self) -> datetime.datetime:
|
|
883
|
+
"""Returns the current date of the instrument.
|
|
884
|
+
|
|
885
|
+
This date is updated automatically by an SNTP (Simple Network Time Protol) server.
|
|
886
|
+
|
|
887
|
+
Returns:
|
|
888
|
+
Year.
|
|
889
|
+
Month, in the range 1 to 12.
|
|
890
|
+
Day, in the range 1 to 31
|
|
891
|
+
|
|
892
|
+
Examples:
|
|
893
|
+
This response indicates that the data of the instrument is January 15th, 2008:
|
|
894
|
+
|
|
895
|
+
> :SYST:DATE?
|
|
896
|
+
< 2008,1,15
|
|
897
|
+
"""
|
|
898
|
+
|
|
899
|
+
pass
|
|
900
|
+
|
|
901
|
+
@dynamic_command(
|
|
902
|
+
cmd_string=":SYSTem:ERRor?",
|
|
903
|
+
cmd_type=CommandType.TRANSACTION,
|
|
904
|
+
process_cmd_string=add_lf,
|
|
905
|
+
process_response=parse_error,
|
|
906
|
+
)
|
|
907
|
+
def get_error(self) -> tuple[int, str]:
|
|
908
|
+
"""Reads an error message from the error queue and then removes it from the queue.
|
|
909
|
+
|
|
910
|
+
Potential errors are:
|
|
911
|
+
- No error (0): Normal operation; no error occurred.
|
|
912
|
+
- Command error (-100): A command is missing a parameter, or the command contains too many parameters or
|
|
913
|
+
too many dimensions.
|
|
914
|
+
- Syntax error (-110): An unrecognised command or data type was encountered (e.g. a string was received when
|
|
915
|
+
the instrument does not accept strings).
|
|
916
|
+
- Data type error (-104): A data element different from the one allowed was encountered (e.g. numeric data
|
|
917
|
+
was expected but string data was encountered).
|
|
918
|
+
- Command header error (-110): The command header is invalid.
|
|
919
|
+
- Unexpected number of parameters (-115): The number of parameters received does not correspond to the number
|
|
920
|
+
of parameters expected by the command.
|
|
921
|
+
- Numeric data error (-120): The value of a parameter overflowed, has the wrong dimensions, or contains an
|
|
922
|
+
invalid value.
|
|
923
|
+
- Invalid suffix (-131): The suffix does not follow the syntax described in IEEE 488.2, Sect. 7.7.3.2, or
|
|
924
|
+
the suffix is inappropriate for this instrument.
|
|
925
|
+
- Execution error (-200): A <PROGRAM DATA> element following a header was evaluated by the instrument as
|
|
926
|
+
outside its legal input range or is otherwise inconsistent with the instrument's
|
|
927
|
+
capabilities. A valid programme message could not be executed properly due to
|
|
928
|
+
some condition of the instrument.
|
|
929
|
+
- Command protected (-203): This is a password-protected command. Password protection is currently
|
|
930
|
+
disabled. To use this command you must enable password protection.
|
|
931
|
+
- Settings conflict (-221): The specified channels of the instrument do not support the requested operation,
|
|
932
|
+
or an invalid current password was entered. E.g. this error is returned if you
|
|
933
|
+
try to configure a thermocouple type for channels that do not support
|
|
934
|
+
temperature, or try to configure a voltage range that is not supported by the
|
|
935
|
+
channel.
|
|
936
|
+
- Data out of range (-222): A legal programme data element was parsed but could not be executed because the
|
|
937
|
+
interpreted value was outside the legal range for the instrument.
|
|
938
|
+
- Programme currently running (-284): Certain operations dealing with programmes are illegal while the
|
|
939
|
+
instrument is in the middle of executing a programme.
|
|
940
|
+
programme is running (e.g. you cannot configure/re-configure an
|
|
941
|
+
operation while a scan is in progress).
|
|
942
|
+
- Queue overflow (-350): The error queue is full; subsequent errors cannot be added to the queue. You must
|
|
943
|
+
clear the queue.
|
|
944
|
+
- Query interrupted (-410): THe query did not complete.
|
|
945
|
+
|
|
946
|
+
The error queue is a FIFO with a capacity of 32 error messages. By querying the error count before and after
|
|
947
|
+
an SCPI commands (in a single command string), you can unambiguously determine whether the command that you
|
|
948
|
+
issued caused an error.
|
|
949
|
+
|
|
950
|
+
When the queue is full, subsequent errors cannot be added to the queue.
|
|
951
|
+
|
|
952
|
+
Refer ro 1999 SCPI Command Reference, Sect. 21.8, for more information.
|
|
953
|
+
|
|
954
|
+
Returns:
|
|
955
|
+
Error/Event number: Unique integer in the range of -32 768 to 32 767. A value of 0 indicates that no
|
|
956
|
+
error or event has occurred.
|
|
957
|
+
Error/Event description: Quoted string that contains a description of the error that was read from the
|
|
958
|
+
Error/Event Queue.
|
|
959
|
+
|
|
960
|
+
Examples:
|
|
961
|
+
The following shows the responses to this query after an invalid command is sent to the instrument:
|
|
962
|
+
|
|
963
|
+
> :BADc
|
|
964
|
+
> :SYST:ERR?
|
|
965
|
+
< -110,"Command header error;:BADc"
|
|
966
|
+
> :SYST:ERR?
|
|
967
|
+
< 0,"No error"
|
|
968
|
+
"""
|
|
969
|
+
|
|
970
|
+
pass
|
|
971
|
+
|
|
972
|
+
@dynamic_command(
|
|
973
|
+
cmd_string=":SYSTem:ERRor:COUNt?",
|
|
974
|
+
cmd_type=CommandType.TRANSACTION,
|
|
975
|
+
process_cmd_string=add_lf,
|
|
976
|
+
process_response=to_int,
|
|
977
|
+
)
|
|
978
|
+
def get_num_errors(self) -> int:
|
|
979
|
+
"""Queries the error queue, returns the number of unread items and returns the count.
|
|
980
|
+
|
|
981
|
+
The error queue is a FIFO with a capacity of 32 error messages. By querying the error count before and after
|
|
982
|
+
an SCPI commands (in a single command string), you can unambiguously determine whether the command that you
|
|
983
|
+
issued caused an error.
|
|
984
|
+
|
|
985
|
+
Returns:
|
|
986
|
+
Number of unread items in the error queue. A value of 0 indicates that the queue is empty.
|
|
987
|
+
|
|
988
|
+
Examples:
|
|
989
|
+
The following shows how to query the number of error in the error queue, both before and after the
|
|
990
|
+
INITialize command:
|
|
991
|
+
|
|
992
|
+
> :SYST:ERR:COUN?;:INIT;:SYST:ERR:COUN?
|
|
993
|
+
< 0
|
|
994
|
+
"""
|
|
995
|
+
|
|
996
|
+
pass
|
|
997
|
+
|
|
998
|
+
@dynamic_command(
|
|
999
|
+
cmd_string=":SYSTem:PRESet",
|
|
1000
|
+
cmd_type=CommandType.WRITE,
|
|
1001
|
+
process_cmd_string=add_lf,
|
|
1002
|
+
)
|
|
1003
|
+
def reset_lan(self) -> None:
|
|
1004
|
+
"""Sets the LAN configuration to its default values.
|
|
1005
|
+
|
|
1006
|
+
The effect of this command is the same as pushing the LAN reset switch on the rear panel of the instrument.
|
|
1007
|
+
"""
|
|
1008
|
+
|
|
1009
|
+
pass
|
|
1010
|
+
|
|
1011
|
+
@dynamic_command(
|
|
1012
|
+
cmd_string=":SYSTem:COMMunicate:NETwork:IPADdress?",
|
|
1013
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1014
|
+
process_cmd_string=add_lf,
|
|
1015
|
+
)
|
|
1016
|
+
def get_ip_address(self) -> str:
|
|
1017
|
+
"""Returns the static IP address that is currently used by the instrument on the network.
|
|
1018
|
+
|
|
1019
|
+
Returns:
|
|
1020
|
+
Static IP address that is currently used by the instrument on the network.
|
|
1021
|
+
"""
|
|
1022
|
+
|
|
1023
|
+
# FIXME This actually returns the IP address of my laptop, rather than the instrument
|
|
1024
|
+
|
|
1025
|
+
pass
|
|
1026
|
+
|
|
1027
|
+
@dynamic_command(
|
|
1028
|
+
cmd_string=":SYSTem:COMMunicate:NETwork:MASk?",
|
|
1029
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1030
|
+
process_cmd_string=add_lf,
|
|
1031
|
+
)
|
|
1032
|
+
def get_lan_ip_subnet_mask(self) -> str:
|
|
1033
|
+
"""Returns the static IP subnet mask that is currently used by the instrument on the network.
|
|
1034
|
+
|
|
1035
|
+
Returns:
|
|
1036
|
+
Static IP subnet mask that is currently used by the instrument on the network.
|
|
1037
|
+
|
|
1038
|
+
Examples:
|
|
1039
|
+
> :SYST:COMM:NET:MAS?
|
|
1040
|
+
< 255.255.255.0
|
|
1041
|
+
"""
|
|
1042
|
+
|
|
1043
|
+
pass
|
|
1044
|
+
|
|
1045
|
+
@dynamic_command(
|
|
1046
|
+
cmd_string=":SYSTem:PASSword:CDISable ${password}",
|
|
1047
|
+
cmd_type=CommandType.WRITE,
|
|
1048
|
+
process_cmd_string=add_lf,
|
|
1049
|
+
)
|
|
1050
|
+
def disable_pwd_protected_cmds(self, password: str) -> None:
|
|
1051
|
+
"""Disables the use of commands and queries that are password-protected.
|
|
1052
|
+
|
|
1053
|
+
On power-up, all password-protected commands are disabled. If the instrument is powered down, you must enable
|
|
1054
|
+
the password-protected commands when the instrument is powered up again, if you want to configure or operate
|
|
1055
|
+
the instrument.
|
|
1056
|
+
|
|
1057
|
+
When the SCPI password-protected commands and queries are disabled, the instrument generates the following
|
|
1058
|
+
error if any of these commands is issued: –203, Command protected.
|
|
1059
|
+
|
|
1060
|
+
Args:
|
|
1061
|
+
password (str): Password that is stored in permanent memory on the instrument.
|
|
1062
|
+
"""
|
|
1063
|
+
|
|
1064
|
+
pass
|
|
1065
|
+
|
|
1066
|
+
@dynamic_command(
|
|
1067
|
+
cmd_string=":SYSTem:PASSword:CENable ${password}",
|
|
1068
|
+
cmd_type=CommandType.WRITE,
|
|
1069
|
+
process_cmd_string=add_lf,
|
|
1070
|
+
)
|
|
1071
|
+
def enable_pwd_protected_cmds(self, password: str) -> None:
|
|
1072
|
+
"""Enables the use of commands and queries that are password-protected.
|
|
1073
|
+
|
|
1074
|
+
On power-up, all password-protected commands are disabled. If the instrument is powered down, you must enable
|
|
1075
|
+
the password-protected commands when the instrument is powered up again, if you want to configure or operate
|
|
1076
|
+
the instrument.
|
|
1077
|
+
|
|
1078
|
+
When the SCPI password-protected commands and queries are disabled, the instrument generates the following
|
|
1079
|
+
error if any of these commands is issued: –203, Command protected.
|
|
1080
|
+
|
|
1081
|
+
Args:
|
|
1082
|
+
password (str): Password that is stored in permanent memory on the instrument.
|
|
1083
|
+
"""
|
|
1084
|
+
|
|
1085
|
+
pass
|
|
1086
|
+
|
|
1087
|
+
@dynamic_command(
|
|
1088
|
+
cmd_string=":SYSTem:PASSword:CENable:STATe?",
|
|
1089
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1090
|
+
process_cmd_string=add_lf,
|
|
1091
|
+
process_response=int_to_bool,
|
|
1092
|
+
)
|
|
1093
|
+
def is_pwd_protected_cmds_enabled(self) -> bool:
|
|
1094
|
+
"""Returns whether password-protected commands are enabled.
|
|
1095
|
+
|
|
1096
|
+
Returns:
|
|
1097
|
+
True if password-protected commands are enabled; False otherwise.
|
|
1098
|
+
|
|
1099
|
+
Examples:
|
|
1100
|
+
In the following example, the state is 1, indicating that password-protected commands are enabled:
|
|
1101
|
+
|
|
1102
|
+
> :SYST:PASS:CEN:STAT?
|
|
1103
|
+
< 1
|
|
1104
|
+
"""
|
|
1105
|
+
|
|
1106
|
+
pass
|
|
1107
|
+
|
|
1108
|
+
@dynamic_command(
|
|
1109
|
+
cmd_string=":SYSTem:PASSword:NEW ${old_password},${new_password}",
|
|
1110
|
+
cmd_type=CommandType.WRITE,
|
|
1111
|
+
process_cmd_string=add_lf,
|
|
1112
|
+
)
|
|
1113
|
+
def set_pwd(self, old_password: str, new_password: str) -> None:
|
|
1114
|
+
"""Changes the existing password to a new password.
|
|
1115
|
+
|
|
1116
|
+
The new password becomes effective immediately. The instrument does not need to be re-booted. The new password
|
|
1117
|
+
is reflected in the LAN configuration webpage for the instrument.
|
|
1118
|
+
|
|
1119
|
+
The new password is enforced when any attempt is made to configure the instrument using SCPI commands, the
|
|
1120
|
+
instrument's webpages, or the IVI-COM driver.
|
|
1121
|
+
|
|
1122
|
+
Args:
|
|
1123
|
+
old_password (str): Current password.
|
|
1124
|
+
new_password (str): New password that will overwrite the current password and be saved in permanent memory
|
|
1125
|
+
on the instrument.
|
|
1126
|
+
"""
|
|
1127
|
+
|
|
1128
|
+
pass
|
|
1129
|
+
|
|
1130
|
+
@dynamic_command(
|
|
1131
|
+
cmd_string=":SYSTem:VERSion?",
|
|
1132
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1133
|
+
process_cmd_string=add_lf,
|
|
1134
|
+
)
|
|
1135
|
+
def get_scpi_version(self) -> str:
|
|
1136
|
+
"""Returns the SCPI version to which the instrument complies.
|
|
1137
|
+
|
|
1138
|
+
Returns:
|
|
1139
|
+
<Year of the version.<Revision number for that year>
|
|
1140
|
+
|
|
1141
|
+
Examples:
|
|
1142
|
+
In this example, the version is year 1999 and the SCPI revision is 0:
|
|
1143
|
+
|
|
1144
|
+
> :SYST:VERS?
|
|
1145
|
+
< 1999.0
|
|
1146
|
+
"""
|
|
1147
|
+
|
|
1148
|
+
pass
|
|
1149
|
+
|
|
1150
|
+
@dynamic_command(
|
|
1151
|
+
cmd_string=":SYSTem:BOArd?",
|
|
1152
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1153
|
+
process_cmd_string=add_lf,
|
|
1154
|
+
process_response=to_int,
|
|
1155
|
+
)
|
|
1156
|
+
def get_num_boards(self) -> int:
|
|
1157
|
+
"""Returns the number of boards that are installed in the instrument.
|
|
1158
|
+
|
|
1159
|
+
Returns:
|
|
1160
|
+
Number of boards installed in the instrument. This value can range from 0 to 6.
|
|
1161
|
+
|
|
1162
|
+
Examples:
|
|
1163
|
+
In this case, 6 boards are installed:
|
|
1164
|
+
|
|
1165
|
+
> :SYST:BOA?
|
|
1166
|
+
< 6
|
|
1167
|
+
"""
|
|
1168
|
+
|
|
1169
|
+
pass
|
|
1170
|
+
|
|
1171
|
+
@dynamic_command(
|
|
1172
|
+
cmd_string=":SYSTem:BOArd:MOdel? ${board_number}",
|
|
1173
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1174
|
+
process_cmd_string=add_lf,
|
|
1175
|
+
)
|
|
1176
|
+
def get_board_model(self, board_number: int) -> int:
|
|
1177
|
+
"""Returns the model of a specific board installed in the instrument.
|
|
1178
|
+
|
|
1179
|
+
The following values are supported:
|
|
1180
|
+
|
|
1181
|
+
- 0 -> DT8871 (thermocouple board),
|
|
1182
|
+
- 1 -> DT8871U (thermocouple board),
|
|
1183
|
+
- 2 -> DT8873-100V (voltage board with a fixed range of +/- 100V) -> Replaced by DT8873-MULTI,
|
|
1184
|
+
- 3 -> DT8873-10V (voltage board with a fixed range of +/- 10V) -> Replaced by DT8873-MULTI,
|
|
1185
|
+
- 4 -> DT8873-400V (voltage board with a fixed range of +/- 400V) -> Replaced by DT8873-MULTI,
|
|
1186
|
+
- 5 -> DT8872 (RTD board),
|
|
1187
|
+
- 7 -> DT8873-MULTI (voltage board that supports programmable voltage ranges of +/-10V and +/-60V).
|
|
1188
|
+
|
|
1189
|
+
Args:
|
|
1190
|
+
board_number (int): Board number to query. This value can range from 1 to 6.
|
|
1191
|
+
|
|
1192
|
+
Returns:
|
|
1193
|
+
Model of the specified board in the instrument.
|
|
1194
|
+
|
|
1195
|
+
Examples:
|
|
1196
|
+
The following example returns the model of board number 3 in a MEASURpoint instrument. In this case, the
|
|
1197
|
+
model is 5, representing the DT8872 RTD board.
|
|
1198
|
+
|
|
1199
|
+
> :SYST:BOA:MOD? 3
|
|
1200
|
+
< 5
|
|
1201
|
+
"""
|
|
1202
|
+
|
|
1203
|
+
pass
|
|
1204
|
+
|
|
1205
|
+
@dynamic_command(
|
|
1206
|
+
cmd_string=":SYSTem:BOArd:MOdel:NAMe? ${board_number}",
|
|
1207
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1208
|
+
process_cmd_string=add_lf,
|
|
1209
|
+
)
|
|
1210
|
+
def get_board_name(self, board_number: int) -> str:
|
|
1211
|
+
"""Returns the name of a specific board that is installed in the instrument.
|
|
1212
|
+
|
|
1213
|
+
Args:
|
|
1214
|
+
board_number (int): Board number to query. This value can range from 1 to 6.
|
|
1215
|
+
|
|
1216
|
+
Returns:
|
|
1217
|
+
Name of the specified board in the instrument.
|
|
1218
|
+
|
|
1219
|
+
Examples:
|
|
1220
|
+
The following example returns the name of board number 3 in a MEASURpoint instrument. In this case, the
|
|
1221
|
+
name is "DT8872" (an RTD board).
|
|
1222
|
+
|
|
1223
|
+
> :SYST:BOA:MOD:NAM? 3
|
|
1224
|
+
< DT8872
|
|
1225
|
+
"""
|
|
1226
|
+
|
|
1227
|
+
pass
|
|
1228
|
+
|
|
1229
|
+
@dynamic_command(
|
|
1230
|
+
cmd_string=":SYSTem:BOArd:RANGe? ${board_number}",
|
|
1231
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1232
|
+
process_cmd_string=add_lf,
|
|
1233
|
+
)
|
|
1234
|
+
def get_voltage_range(self, board_number: int) -> tuple[float, float]:
|
|
1235
|
+
"""Returns the minimum and maximum voltages that are supported by a specific board in the instrument.
|
|
1236
|
+
|
|
1237
|
+
Args:
|
|
1238
|
+
board_number (int): Board number to query. This value can range from 1 to 6.
|
|
1239
|
+
|
|
1240
|
+
Returns:
|
|
1241
|
+
Tuple of the minimum and maximum voltages supported by the specified board [V].
|
|
1242
|
+
|
|
1243
|
+
Examples:
|
|
1244
|
+
The following example returns the minimum and maximum voltages that are supported by a DT8873-MULTI board
|
|
1245
|
+
(board 1 in this case):
|
|
1246
|
+
|
|
1247
|
+
> :SYST:BOA:RANG? 1
|
|
1248
|
+
< -60.000, 60.000
|
|
1249
|
+
|
|
1250
|
+
This example returns the minimum and maximum voltages that are supported by a DT8872 RTD board (board 1 in
|
|
1251
|
+
this case):
|
|
1252
|
+
|
|
1253
|
+
> :SYST:BOA:RANG? 1
|
|
1254
|
+
< -1.250, 1.250
|
|
1255
|
+
"""
|
|
1256
|
+
|
|
1257
|
+
pass
|
|
1258
|
+
|
|
1259
|
+
@dynamic_command(
|
|
1260
|
+
cmd_string=":SYSTem:CHANnel?",
|
|
1261
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1262
|
+
process_cmd_string=add_lf,
|
|
1263
|
+
)
|
|
1264
|
+
def get_input_channels(self) -> str:
|
|
1265
|
+
"""Returns a list of all analogue input channels that are supported on the instrument.
|
|
1266
|
+
|
|
1267
|
+
If no analogue input channels are supported on the instrument, an empty list (@) is returned.
|
|
1268
|
+
|
|
1269
|
+
Returns:
|
|
1270
|
+
List of all analogue input channels that are supported on the instrument.
|
|
1271
|
+
|
|
1272
|
+
Examples:
|
|
1273
|
+
The following example returns the list of supported analogue input channels on an instrument, in this case,
|
|
1274
|
+
24 channels (0 to 23):
|
|
1275
|
+
|
|
1276
|
+
> :SYST:CHAN?
|
|
1277
|
+
< @0:23
|
|
1278
|
+
"""
|
|
1279
|
+
|
|
1280
|
+
pass
|
|
1281
|
+
|
|
1282
|
+
@dynamic_command(
|
|
1283
|
+
cmd_string=":SYSTem:CHANnel:RTD?",
|
|
1284
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1285
|
+
process_cmd_string=add_lf,
|
|
1286
|
+
)
|
|
1287
|
+
def get_rtd_channels(self) -> str:
|
|
1288
|
+
"""Returns a list of all analogue input channels that support RTDs on the instrument.
|
|
1289
|
+
|
|
1290
|
+
If no channels support RTDs on the instrument, an empty list (@) is returned.
|
|
1291
|
+
|
|
1292
|
+
Returns:
|
|
1293
|
+
List of all analogue input channels that support RTDs on the instrument.
|
|
1294
|
+
|
|
1295
|
+
Examples:
|
|
1296
|
+
The following example returns the list of analogue input channels on the instrument, as well as the channels
|
|
1297
|
+
that support RTDs. In this case, all 48 channels (0 to 47) support RTDs:
|
|
1298
|
+
|
|
1299
|
+
> :SYST:CHAN?
|
|
1300
|
+
< @0:47
|
|
1301
|
+
> :SYST:CHAN:RTD?
|
|
1302
|
+
< @0:47
|
|
1303
|
+
|
|
1304
|
+
In the following example, only channels 8 to 15 of the available 48 channels support RTDs:
|
|
1305
|
+
|
|
1306
|
+
> :SYST:CHAN?
|
|
1307
|
+
< @0:47
|
|
1308
|
+
> :SYST:CHAN:RTD?
|
|
1309
|
+
< @8:15
|
|
1310
|
+
"""
|
|
1311
|
+
|
|
1312
|
+
pass
|
|
1313
|
+
|
|
1314
|
+
@dynamic_command(
|
|
1315
|
+
cmd_string=":SYSTem:CHANnel:TCouple?",
|
|
1316
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1317
|
+
process_cmd_string=add_lf,
|
|
1318
|
+
)
|
|
1319
|
+
def get_thermocouple_channels(self) -> str:
|
|
1320
|
+
"""Returns a list of all analogue input channels that support thermocouples on the instrument.
|
|
1321
|
+
|
|
1322
|
+
If no channels support thermocouples on the instrument, an empty list (@) is returned.
|
|
1323
|
+
|
|
1324
|
+
Returns:
|
|
1325
|
+
List of all analogue input channels that support thermocouples on the instrument.
|
|
1326
|
+
|
|
1327
|
+
Examples:
|
|
1328
|
+
The following example returns the list of analogue input channels on the instrument, as well as the channels
|
|
1329
|
+
that support thermocouples. In this case, all 48 channels (0 to 47) support thermocouples:
|
|
1330
|
+
|
|
1331
|
+
> :SYST:CHAN?
|
|
1332
|
+
< @0:47
|
|
1333
|
+
> :SYST:CHAN:TC?
|
|
1334
|
+
< @0:47
|
|
1335
|
+
|
|
1336
|
+
In the following example, only channels 0 to 15 of the available 48 channels support thermocouples:
|
|
1337
|
+
|
|
1338
|
+
> :SYST:CHAN?
|
|
1339
|
+
< @0:47
|
|
1340
|
+
> :SYST:CHAN:TC?
|
|
1341
|
+
< @0:15
|
|
1342
|
+
"""
|
|
1343
|
+
|
|
1344
|
+
pass
|
|
1345
|
+
|
|
1346
|
+
@dynamic_command(
|
|
1347
|
+
cmd_string=":SYSTem:CHANnel:VOLTage:RANGe?",
|
|
1348
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1349
|
+
process_cmd_string=add_lf,
|
|
1350
|
+
)
|
|
1351
|
+
def get_voltage_range_channels(self) -> str:
|
|
1352
|
+
"""Returns a list of analogue input channels that support programmable voltage ranges on the instrument.
|
|
1353
|
+
|
|
1354
|
+
If no channels support programmable voltage ranges on the instrument, an empty list (@) is returned.
|
|
1355
|
+
|
|
1356
|
+
Returns:
|
|
1357
|
+
List of all analogue input channels that support programmable voltage ranges on the instrument.
|
|
1358
|
+
|
|
1359
|
+
Examples:
|
|
1360
|
+
The following example returns which channels support programmable voltage ranges; in this case, channels 0
|
|
1361
|
+
to 7 support thermocouples, while channels 8 to 15 support RTDs, and channels 16 to 23 support programmable
|
|
1362
|
+
voltage ranges:
|
|
1363
|
+
> *IDN?
|
|
1364
|
+
< Data Translation,DT7774-08T-08R-08V,-1,1.8,0.0
|
|
1365
|
+
> :SYSTem:CHANnel?
|
|
1366
|
+
< (@0:23)
|
|
1367
|
+
>:SYSTem:CHANnel:RTD?
|
|
1368
|
+
< (@8:15)
|
|
1369
|
+
> :SYSTem:CHANnel:TC?
|
|
1370
|
+
< (@0:7)
|
|
1371
|
+
> :SYSTem:CHANnel:VOLTage:RANGe?
|
|
1372
|
+
< (@16:23)
|
|
1373
|
+
"""
|
|
1374
|
+
|
|
1375
|
+
pass
|
|
1376
|
+
|
|
1377
|
+
@dynamic_command(
|
|
1378
|
+
cmd_string=":SYSTem:DINput?",
|
|
1379
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1380
|
+
process_cmd_string=add_lf,
|
|
1381
|
+
process_response=to_int,
|
|
1382
|
+
)
|
|
1383
|
+
def get_num_digital_input_lines(self) -> int:
|
|
1384
|
+
"""Returns the number of digital input lines that are supported by the instrument.
|
|
1385
|
+
|
|
1386
|
+
Returns:
|
|
1387
|
+
Number of digital input lines that are supported by the instrument.
|
|
1388
|
+
|
|
1389
|
+
Examples:
|
|
1390
|
+
The following example returns the number of digital input lines supported by the instrument:
|
|
1391
|
+
|
|
1392
|
+
> :SYSTem:DINput?
|
|
1393
|
+
< 8
|
|
1394
|
+
"""
|
|
1395
|
+
|
|
1396
|
+
pass
|
|
1397
|
+
|
|
1398
|
+
@dynamic_command(
|
|
1399
|
+
cmd_string=":SYSTem:DINput?",
|
|
1400
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1401
|
+
process_cmd_string=add_lf,
|
|
1402
|
+
process_response=to_int,
|
|
1403
|
+
)
|
|
1404
|
+
def get_num_digital_output_lines(self) -> int:
|
|
1405
|
+
"""Returns the number of digital output lines that are supported by the instrument.
|
|
1406
|
+
|
|
1407
|
+
Returns:
|
|
1408
|
+
Number of digital output lines that are supported by the instrument.
|
|
1409
|
+
|
|
1410
|
+
Examples:
|
|
1411
|
+
The following example returns the number of digital output lines supported by the instrument:
|
|
1412
|
+
|
|
1413
|
+
> :SYSTem:DOUTput?
|
|
1414
|
+
< 8
|
|
1415
|
+
"""
|
|
1416
|
+
|
|
1417
|
+
pass
|
|
1418
|
+
|
|
1419
|
+
@dynamic_command(
|
|
1420
|
+
cmd_string=":SYSTem:SCAn:RATe:MAXimum:SEC?",
|
|
1421
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1422
|
+
process_cmd_string=add_lf,
|
|
1423
|
+
process_response=to_float,
|
|
1424
|
+
)
|
|
1425
|
+
def get_max_scan_rate(self) -> float:
|
|
1426
|
+
"""Returns the maximum scan rate in s.
|
|
1427
|
+
|
|
1428
|
+
Returns:
|
|
1429
|
+
Maximum scan rate [s].
|
|
1430
|
+
|
|
1431
|
+
Examples:
|
|
1432
|
+
The following example returns the maximum scan rate that is supported by the instrument, in seconds:
|
|
1433
|
+
|
|
1434
|
+
> :SYST:SCA:MAX:SEC?
|
|
1435
|
+
< 0.10000
|
|
1436
|
+
"""
|
|
1437
|
+
|
|
1438
|
+
pass
|
|
1439
|
+
|
|
1440
|
+
@dynamic_command(
|
|
1441
|
+
cmd_string=":SYSTem:SCAn:RATe:MAXimum:HZ?",
|
|
1442
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1443
|
+
process_cmd_string=add_lf,
|
|
1444
|
+
process_response=to_float,
|
|
1445
|
+
)
|
|
1446
|
+
def get_max_scan_frequency(self) -> float:
|
|
1447
|
+
"""Returns the maximum frequency rate in Hz.
|
|
1448
|
+
|
|
1449
|
+
Returns:
|
|
1450
|
+
Maximum frequency rate [s].
|
|
1451
|
+
|
|
1452
|
+
Examples:
|
|
1453
|
+
The following example returns the maximum scan rate that is supported by the instrument, in Hz:
|
|
1454
|
+
|
|
1455
|
+
> :SYST:SCA:MAX:HZ?
|
|
1456
|
+
< 10.00000
|
|
1457
|
+
"""
|
|
1458
|
+
|
|
1459
|
+
pass
|
|
1460
|
+
|
|
1461
|
+
@dynamic_command(
|
|
1462
|
+
cmd_string=":SYSTem:SCAn:RATe:MINimum:SEC?",
|
|
1463
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1464
|
+
process_cmd_string=add_lf,
|
|
1465
|
+
process_response=to_float,
|
|
1466
|
+
)
|
|
1467
|
+
def get_min_scan_rate(self) -> float:
|
|
1468
|
+
"""Returns the minimum scan rate in s.
|
|
1469
|
+
|
|
1470
|
+
Returns:
|
|
1471
|
+
Minimum scan rate [s].
|
|
1472
|
+
|
|
1473
|
+
Examples:
|
|
1474
|
+
The following example returns the minimum scan rate that is supported by the instrument, in seconds:
|
|
1475
|
+
|
|
1476
|
+
> :SYST:SCA:MIN:SEC?
|
|
1477
|
+
< 6553.5
|
|
1478
|
+
"""
|
|
1479
|
+
|
|
1480
|
+
pass
|
|
1481
|
+
|
|
1482
|
+
@dynamic_command(
|
|
1483
|
+
cmd_string=":SYSTem:SCAn:RATe:MINimum:HZ?",
|
|
1484
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1485
|
+
process_cmd_string=add_lf,
|
|
1486
|
+
process_response=to_float,
|
|
1487
|
+
)
|
|
1488
|
+
def get_min_scan_frequency(self) -> float:
|
|
1489
|
+
"""Returns the minimum frequency rate in Hz.
|
|
1490
|
+
|
|
1491
|
+
Returns:
|
|
1492
|
+
Minimum frequency rate [s].
|
|
1493
|
+
|
|
1494
|
+
Examples:
|
|
1495
|
+
The following example returns the minimum scan rate that is supported by the instrument, in Hz:
|
|
1496
|
+
|
|
1497
|
+
> :SYST:SCA:MIN:HZ?
|
|
1498
|
+
< 1.525e-4
|
|
1499
|
+
"""
|
|
1500
|
+
|
|
1501
|
+
pass
|
|
1502
|
+
|
|
1503
|
+
@dynamic_command(
|
|
1504
|
+
cmd_string=":SYSTem:TIME?",
|
|
1505
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1506
|
+
process_cmd_string=add_lf,
|
|
1507
|
+
process_response=format_to_time,
|
|
1508
|
+
)
|
|
1509
|
+
def get_time(self) -> tuple[int, int, int]:
|
|
1510
|
+
"""Returns the current time used by the instrument.
|
|
1511
|
+
|
|
1512
|
+
This date is updated automatically by an SNTP server.
|
|
1513
|
+
|
|
1514
|
+
Returns:
|
|
1515
|
+
Tuple of (hour, minute, second)
|
|
1516
|
+
|
|
1517
|
+
Examples:
|
|
1518
|
+
This response indicates that the current time of the instrument is 15:31:45 (15 is the hour, 31 is the
|
|
1519
|
+
number of minutes, and 45 is the number of seconds):
|
|
1520
|
+
|
|
1521
|
+
> :SYST:TIME?
|
|
1522
|
+
< 15:31:45
|
|
1523
|
+
"""
|
|
1524
|
+
|
|
1525
|
+
pass
|
|
1526
|
+
|
|
1527
|
+
@dynamic_command(
|
|
1528
|
+
cmd_string=":SYSTem:TZONe?",
|
|
1529
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1530
|
+
process_cmd_string=add_lf,
|
|
1531
|
+
)
|
|
1532
|
+
def get_timezone(self) -> tuple[int, int]:
|
|
1533
|
+
"""Returns the timezone that is currently used by the instrument, as an offset from GMT.
|
|
1534
|
+
|
|
1535
|
+
Returns:
|
|
1536
|
+
Tuple of (number of hours offset from GMT, number of minutes offset from GMT) that shows the offset of the
|
|
1537
|
+
current time relative to GMT.
|
|
1538
|
+
|
|
1539
|
+
Examples:
|
|
1540
|
+
This response indicates that the current timezone of the instrument if four hours and 30 minutes ahead of
|
|
1541
|
+
GMT:
|
|
1542
|
+
|
|
1543
|
+
> :SYST:TZON?
|
|
1544
|
+
< 4, -45
|
|
1545
|
+
"""
|
|
1546
|
+
|
|
1547
|
+
# TODO
|
|
1548
|
+
|
|
1549
|
+
pass
|
|
1550
|
+
|
|
1551
|
+
@dynamic_command(
|
|
1552
|
+
cmd_string=":SYSTem:TZONe ${hour},${minute}",
|
|
1553
|
+
cmd_type=CommandType.WRITE,
|
|
1554
|
+
process_cmd_string=add_lf,
|
|
1555
|
+
)
|
|
1556
|
+
def set_timezone(self, hour: int, minute: int = 0) -> None:
|
|
1557
|
+
"""Sets the timezone currently used by the instrument as an offset from GMT.
|
|
1558
|
+
|
|
1559
|
+
The specified hour and minute are added to the UTC time that is maintained by the instrument.
|
|
1560
|
+
|
|
1561
|
+
This is a password-protected command.
|
|
1562
|
+
|
|
1563
|
+
Args:
|
|
1564
|
+
hour (int): Current hour relative to UTC.
|
|
1565
|
+
minute (int): Current minute relative to UTC.
|
|
1566
|
+
|
|
1567
|
+
Examples:
|
|
1568
|
+
This command sets the current timezone used by the instrument to four hours and 30 minutes ahead of GMT:
|
|
1569
|
+
|
|
1570
|
+
> :SYST:TZON 4,-45
|
|
1571
|
+
"""
|
|
1572
|
+
|
|
1573
|
+
pass
|
|
1574
|
+
|
|
1575
|
+
# CONFigure Sub-System Commands
|
|
1576
|
+
|
|
1577
|
+
@dynamic_command(
|
|
1578
|
+
cmd_string=":CONFigure:RESistance ${channels}",
|
|
1579
|
+
cmd_type=CommandType.WRITE,
|
|
1580
|
+
process_cmd_string=add_lf,
|
|
1581
|
+
)
|
|
1582
|
+
def set_resistance_channels(self, channels: str = "(@0:47)"):
|
|
1583
|
+
"""Configures specified channels for resistance measurements.
|
|
1584
|
+
|
|
1585
|
+
This can only be applied to channels that support resistance measurements. This command affects the
|
|
1586
|
+
configuration of the specified channels only.
|
|
1587
|
+
|
|
1588
|
+
The number of channels that you can specify depends on the configuration of your instrument.
|
|
1589
|
+
|
|
1590
|
+
This is a password-protected command.
|
|
1591
|
+
|
|
1592
|
+
Refer to 1999 SCPI Command Reference, Sect. 3.1 and 3.7.2, and 1999 SCPI Syntax & Style, Sect. 8.3.2, for more
|
|
1593
|
+
information.
|
|
1594
|
+
|
|
1595
|
+
Args:
|
|
1596
|
+
channels (str): List of channels to configure for resistance measurements.
|
|
1597
|
+
|
|
1598
|
+
Examples:
|
|
1599
|
+
The following command configures analogue input channels 0, 3 to 7, and 47 on the instrument for resistance
|
|
1600
|
+
measurements:
|
|
1601
|
+
|
|
1602
|
+
> :CONF:RES (@0,3:7,47)
|
|
1603
|
+
|
|
1604
|
+
This command configures all analogue input channels on the instrument for resistance measurements:
|
|
1605
|
+
|
|
1606
|
+
> :CONF:RES
|
|
1607
|
+
|
|
1608
|
+
This command configures analogue input channels 1, 2, and 8 to 46 on the instrument for resistance
|
|
1609
|
+
measurements:
|
|
1610
|
+
|
|
1611
|
+
> :CONF:RES (@1,2,8:46)
|
|
1612
|
+
"""
|
|
1613
|
+
|
|
1614
|
+
pass
|
|
1615
|
+
|
|
1616
|
+
@dynamic_command(
|
|
1617
|
+
cmd_string=":CONFigure:TEMPerature:RTD ${rtd_type},${channels}",
|
|
1618
|
+
cmd_type=CommandType.WRITE,
|
|
1619
|
+
process_cmd_string=add_lf,
|
|
1620
|
+
)
|
|
1621
|
+
def set_rtd_temperature_channels(self, rtd_type: str, channels: str = "(@0:47)"):
|
|
1622
|
+
"""Configures specified channels on the instrument for RTD temperature measurements.
|
|
1623
|
+
|
|
1624
|
+
Allowed RTD types are:
|
|
1625
|
+
- For 2- or 4-wire European RTDs:
|
|
1626
|
+
- PT100
|
|
1627
|
+
- PT500
|
|
1628
|
+
- PT1000
|
|
1629
|
+
- For 2- or 4-wire American RTDs:
|
|
1630
|
+
- A_PT100
|
|
1631
|
+
- A_PT500
|
|
1632
|
+
- A_PT1000
|
|
1633
|
+
- For 3-wire European RTDs:
|
|
1634
|
+
- PT100_3
|
|
1635
|
+
- PT500_3
|
|
1636
|
+
- PT1000_3
|
|
1637
|
+
- For 3-wire American RTDs:
|
|
1638
|
+
- A_PT100_3
|
|
1639
|
+
- A_PT500_3
|
|
1640
|
+
- A_PT1000_3
|
|
1641
|
+
- DEFault
|
|
1642
|
+
|
|
1643
|
+
This commands affects the configuration of the specified channels only.
|
|
1644
|
+
|
|
1645
|
+
The number of channels that you can specify depends on the configuration of your instrument.
|
|
1646
|
+
|
|
1647
|
+
This is a password-protected command.
|
|
1648
|
+
|
|
1649
|
+
Args:
|
|
1650
|
+
rtd_type (str): RTD type to be used for the temperature measurements.
|
|
1651
|
+
channels (str): List of channels to configure for RTD temperature measurements.
|
|
1652
|
+
|
|
1653
|
+
Examples:
|
|
1654
|
+
This example configures analogue input channel 8 to use a PT1000 2- or 4-wire European RTF:
|
|
1655
|
+
|
|
1656
|
+
> :CONF:TEMP:RTD PT1000, (@8)
|
|
1657
|
+
> *STB?
|
|
1658
|
+
< 0
|
|
1659
|
+
|
|
1660
|
+
The following example tries to configure all analogue input channels on the instrument to use a PT100
|
|
1661
|
+
2- or 4-wire European RTD. However, in this example, no channels support RTD input; therefore an
|
|
1662
|
+
Execution Error occurs. If bit 4 (E) of the Standard Event Status Enable register is enable, an
|
|
1663
|
+
Execution Error sets but 4 (E) of the Standard Event Status register. This, in turn, will set bits 2 and 5
|
|
1664
|
+
of the Status Byte register:
|
|
1665
|
+
|
|
1666
|
+
> *ESE 189
|
|
1667
|
+
> ESR?
|
|
1668
|
+
< 0
|
|
1669
|
+
> :CONF:TEMP:RTP PT100
|
|
1670
|
+
> *STB?
|
|
1671
|
+
< 36
|
|
1672
|
+
> ESR?
|
|
1673
|
+
< 16
|
|
1674
|
+
> :SYST;ERR?
|
|
1675
|
+
< -200, "Execution error;CONF:TEMP:RTD invalid"
|
|
1676
|
+
> *STB?
|
|
1677
|
+
< 0
|
|
1678
|
+
"""
|
|
1679
|
+
|
|
1680
|
+
pass
|
|
1681
|
+
|
|
1682
|
+
@dynamic_command(
|
|
1683
|
+
cmd_string=":CONFigure:TEMPerature:TCouple ${tc_type}, ${channels}",
|
|
1684
|
+
cmd_type=CommandType.WRITE,
|
|
1685
|
+
process_cmd_string=add_lf,
|
|
1686
|
+
)
|
|
1687
|
+
def set_thermocouple_temperature_channels(self, tc_type: str, channels: str = "(@0:47)"):
|
|
1688
|
+
"""Configures specified channels on the instrument for thermocouple temperature measurements.
|
|
1689
|
+
|
|
1690
|
+
Allowed thermocouple types are:
|
|
1691
|
+
- J (Iron/Constantan)
|
|
1692
|
+
- K (Nickel-Chromium / Nickel-Alumel)
|
|
1693
|
+
- B (Platinum Rhodium -30% / Platinum Rhodium -6%)
|
|
1694
|
+
- E (Nickel-Chromium/Constantan)
|
|
1695
|
+
- N (Nicrosil/Nisil)
|
|
1696
|
+
- R (Platinum Rhodium -13% / Platinum)
|
|
1697
|
+
- S (Platinum Rhodium -10% / Platinum)
|
|
1698
|
+
- T (Copper/Constantan)
|
|
1699
|
+
- DEFault
|
|
1700
|
+
|
|
1701
|
+
This commands affects the configuration of the specified channels only.
|
|
1702
|
+
|
|
1703
|
+
The number of channels that you can specify depends on the configuration of your instrument.
|
|
1704
|
+
|
|
1705
|
+
This is a password-protected command.
|
|
1706
|
+
|
|
1707
|
+
Args:
|
|
1708
|
+
tc_type (str): Thermocouple type to be used for the temperature measurements.
|
|
1709
|
+
channels (str): List of channels to configure for thermocouple temperature measurements.
|
|
1710
|
+
|
|
1711
|
+
Examples:
|
|
1712
|
+
This example configures analogue input channel 3 to use a K-type thermocouple:
|
|
1713
|
+
|
|
1714
|
+
> :CONF:TEMP:TCouple K, (@3)
|
|
1715
|
+
> *STB?
|
|
1716
|
+
< 0
|
|
1717
|
+
|
|
1718
|
+
The following example tries to configure the analogue input channels to use an S-type thermocouple. In
|
|
1719
|
+
this example, the instrument does not support thermocouple channels; therefore, an Execution Error occurs.
|
|
1720
|
+
If bit 4 (E) of the Standard Event Status Enable register is enable, an Execution Error sets but 4 (E) of
|
|
1721
|
+
the Standard Event Status register. This, in turn, will set bits 2 and 5 of the Status Byte register:
|
|
1722
|
+
|
|
1723
|
+
> *ESE 189
|
|
1724
|
+
> ESR?
|
|
1725
|
+
< 0
|
|
1726
|
+
> :CONF:TEMP:TC S
|
|
1727
|
+
> *STB?
|
|
1728
|
+
< 36
|
|
1729
|
+
> ESR?
|
|
1730
|
+
< 16
|
|
1731
|
+
> :SYST;ERR?
|
|
1732
|
+
< -200, "Execution error;CONF:TEMP:TC invalid"
|
|
1733
|
+
> *STB?
|
|
1734
|
+
< 0
|
|
1735
|
+
"""
|
|
1736
|
+
|
|
1737
|
+
pass
|
|
1738
|
+
|
|
1739
|
+
@dynamic_command(
|
|
1740
|
+
cmd_string=":CONFigure:VOLTage ${channels}",
|
|
1741
|
+
cmd_type=CommandType.WRITE,
|
|
1742
|
+
process_cmd_string=add_lf,
|
|
1743
|
+
)
|
|
1744
|
+
def set_voltage_channels(self, channels: str = "(@0:47)"):
|
|
1745
|
+
"""Configures specified RTD and thermocouple channels on the instrument for voltage measurements.
|
|
1746
|
+
|
|
1747
|
+
This commands affects the configuration of the specified channels only.
|
|
1748
|
+
|
|
1749
|
+
The number of channels that you can specify depends on the configuration of your instrument.
|
|
1750
|
+
|
|
1751
|
+
This is a password-protected command.
|
|
1752
|
+
|
|
1753
|
+
Args:
|
|
1754
|
+
channels (str): List of channels to configure for voltage measurements.
|
|
1755
|
+
|
|
1756
|
+
Examples:
|
|
1757
|
+
The following example configures analogue input channels 0, 3 to 7, and 47 for voltage measurements:
|
|
1758
|
+
|
|
1759
|
+
> :CONF:VOLT (@0,3:7,47)
|
|
1760
|
+
|
|
1761
|
+
This example configures all analogue input channels on the instrument for voltage measurements:
|
|
1762
|
+
|
|
1763
|
+
> :CONF:VOLT
|
|
1764
|
+
|
|
1765
|
+
This example configures analogue input channels 1, 2, and 8 to 46 for voltage measurements:
|
|
1766
|
+
|
|
1767
|
+
> :CONF:VOLT (@1,2,8:46)
|
|
1768
|
+
"""
|
|
1769
|
+
|
|
1770
|
+
pass
|
|
1771
|
+
|
|
1772
|
+
@dynamic_command(
|
|
1773
|
+
cmd_string=":CONFigure:VOLTage:RANGe ${voltage_range},${channels}",
|
|
1774
|
+
cmd_type=CommandType.WRITE,
|
|
1775
|
+
process_cmd_string=add_lf,
|
|
1776
|
+
)
|
|
1777
|
+
def set_voltage_range_channels(self, voltage_range: str = "DEFault", channels: str = "(@0:47)"):
|
|
1778
|
+
"""Configures the voltages range for specified channels on the instrument.
|
|
1779
|
+
|
|
1780
|
+
Allowed voltage ranges are:
|
|
1781
|
+
- BIP100MV: Specifies an input voltage range of +/-0.1V,
|
|
1782
|
+
- BIP1V: Specifies an input voltage range of +/-1V,
|
|
1783
|
+
- BIP10V: Specifies an input voltage range of +/-10V,
|
|
1784
|
+
- BIP100V: Specifies an input voltage range of +/-100V,
|
|
1785
|
+
- BIP400V: Specifies an input voltage range of +/-400V,
|
|
1786
|
+
- BIP60V: Specifies an input voltage range of +/-60V,
|
|
1787
|
+
- DEFault: Selects the default voltage range of +/-10V.
|
|
1788
|
+
|
|
1789
|
+
This commands affects the configuration of the specified channels only.
|
|
1790
|
+
|
|
1791
|
+
The number of channels that you can specify depends on the configuration of your instrument.
|
|
1792
|
+
|
|
1793
|
+
This is a password-protected command.
|
|
1794
|
+
|
|
1795
|
+
Args:
|
|
1796
|
+
voltage_range (str): Voltage range to be used for the voltage measurements.
|
|
1797
|
+
channels (str): List of channels to configure for voltage measurements.
|
|
1798
|
+
|
|
1799
|
+
Examples:
|
|
1800
|
+
The following example returns the configuration of all channels on a MEASURpoint instrument; In this case,
|
|
1801
|
+
all channels on the instrument can be programmed for thermocouple measurements:
|
|
1802
|
+
|
|
1803
|
+
> :CONF:?
|
|
1804
|
+
< V,J,J,V,J,V,J,J,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V
|
|
1805
|
+
|
|
1806
|
+
This example configures all channels for a type J thermocouple, and then reconfigures channels 0, 3, and 5
|
|
1807
|
+
for voltage inputs. In the first query, the configuration of channels 0 and 7 is returned. In the second
|
|
1808
|
+
query, the configuration of channels 0 through 7 is returned:
|
|
1809
|
+
|
|
1810
|
+
> :CONF:TEMP:TC J
|
|
1811
|
+
> :CONF:VOLT (@0,3,5)
|
|
1812
|
+
> :CONF? (@0,7)
|
|
1813
|
+
< V,J
|
|
1814
|
+
> :CONFigure? (@0:7)
|
|
1815
|
+
< V,J,J,V,J,V,J,J
|
|
1816
|
+
|
|
1817
|
+
The following example returns the configuration of all channels on a MEASURpoint instrument; in this case,
|
|
1818
|
+
all channels on the instrument can be programmed for thermocouple measurements:
|
|
1819
|
+
|
|
1820
|
+
> :CONF?
|
|
1821
|
+
< V,J,J,V,J,V,J,J,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V,V
|
|
1822
|
+
|
|
1823
|
+
This example configures all channels for a type J thermocouple, and then reconfigures channels 0, 3, and 5
|
|
1824
|
+
for voltage inputs. In the first query, the configuration of channels 0 and 7 is returned. In the second
|
|
1825
|
+
query, the configuration of channels 0 through 7 is returned:
|
|
1826
|
+
|
|
1827
|
+
> :CONF:TEMP:TC J
|
|
1828
|
+
> :CONF:VOLT (@0,3,5)
|
|
1829
|
+
> :CONF? (@0,7)
|
|
1830
|
+
< V,J
|
|
1831
|
+
> :CONFigure? (@0:7)
|
|
1832
|
+
< V,J,J,V,J,V,J,J
|
|
1833
|
+
|
|
1834
|
+
In this example, the configuration of channels 0 through 7 of a MEASURpoint instrument that supports
|
|
1835
|
+
programmable voltage ranges is returned:
|
|
1836
|
+
> :CONF? (@0:7)
|
|
1837
|
+
< BIP10V,BIP10V,BIP60V,BIP60V,BIP60V,BIP60V,BIP60V,BIP60V
|
|
1838
|
+
"""
|
|
1839
|
+
|
|
1840
|
+
# TODO Only for VOLTpoint + MEASURpoint
|
|
1841
|
+
pass
|
|
1842
|
+
|
|
1843
|
+
@dynamic_command(
|
|
1844
|
+
cmd_string=":CONFigure? ${channels}",
|
|
1845
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1846
|
+
process_cmd_string=add_lf,
|
|
1847
|
+
)
|
|
1848
|
+
def get_channel_config(self, channels: str = "(@0:47)"):
|
|
1849
|
+
"""Returns the configuration of the specified channels on the instrument.
|
|
1850
|
+
|
|
1851
|
+
Returns up to 48 fields of comma-separated values. Each field contains the configuration of a channel:
|
|
1852
|
+
- For each thermocouple input, one of the following thermocouple value is returned: J, K, R, S, T, B, E, N.
|
|
1853
|
+
- For each RTD input, one of the following RTD value is returned: PT100, PT500, PT1000, A_PT100, A_PT500,
|
|
1854
|
+
A_PT1000, PT100_3, PT500_3, PT1000_3, A_PT100_3, A_PT500_3, A_PT1000_3.
|
|
1855
|
+
- For each voltage input, OHM is returned.
|
|
1856
|
+
|
|
1857
|
+
This is a password-protected command.
|
|
1858
|
+
|
|
1859
|
+
Args:
|
|
1860
|
+
channels (str): List of channels to configure for voltage measurements.
|
|
1861
|
+
|
|
1862
|
+
Returns:
|
|
1863
|
+
Up to 48 fields of comma-separated values. Each field contains the configuration of a channel.
|
|
1864
|
+
|
|
1865
|
+
Examples:
|
|
1866
|
+
The following examples set the filter type and then return the current filter configuration:
|
|
1867
|
+
|
|
1868
|
+
> :CONF:FILT AVG
|
|
1869
|
+
> :CONF:FILT?
|
|
1870
|
+
< AVG
|
|
1871
|
+
|
|
1872
|
+
>:CONF:FILT RAW
|
|
1873
|
+
> :CONF:FILT?
|
|
1874
|
+
< RAW
|
|
1875
|
+
"""
|
|
1876
|
+
|
|
1877
|
+
pass
|
|
1878
|
+
|
|
1879
|
+
@dynamic_command(
|
|
1880
|
+
cmd_string=":CONFigure:FILTer ${filter_type}",
|
|
1881
|
+
cmd_type=CommandType.WRITE,
|
|
1882
|
+
process_cmd_string=add_lf,
|
|
1883
|
+
)
|
|
1884
|
+
def set_filter_type(self, filter_type: str) -> BaseException:
|
|
1885
|
+
"""Configures the filter type used for single-value and continuous analogue input operations.
|
|
1886
|
+
|
|
1887
|
+
Allowed filter types are:
|
|
1888
|
+
- RAW: No filtering. Provides fast response times, but the data may be difficult to interpret. Use when
|
|
1889
|
+
you want to filter the data yourself.
|
|
1890
|
+
- AVG: Moving average. Provides a compromise of filter functionality and response time. Can be used in
|
|
1891
|
+
any application.
|
|
1892
|
+
|
|
1893
|
+
Args:
|
|
1894
|
+
filter_type (str): Filter type to be used for the analogue input operations.
|
|
1895
|
+
"""
|
|
1896
|
+
|
|
1897
|
+
pass
|
|
1898
|
+
|
|
1899
|
+
@dynamic_command(
|
|
1900
|
+
cmd_string=":CONFigure:FILTer?",
|
|
1901
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1902
|
+
process_cmd_string=add_lf,
|
|
1903
|
+
)
|
|
1904
|
+
def get_filter_type(self) -> str:
|
|
1905
|
+
"""Returns the currently configured filter type for the instrument.
|
|
1906
|
+
|
|
1907
|
+
Allowed filter types are:
|
|
1908
|
+
- RAW: No filtering. Provides fast response times, but the data may be difficult to interpret. Use when
|
|
1909
|
+
you want to filter the data yourself.
|
|
1910
|
+
- AVG: Moving average. Provides a compromise of filter functionality and response time. Can be used in
|
|
1911
|
+
any application.
|
|
1912
|
+
|
|
1913
|
+
This is a password-protected command.
|
|
1914
|
+
|
|
1915
|
+
Returns:
|
|
1916
|
+
Currently configured filter type.
|
|
1917
|
+
|
|
1918
|
+
Examples:
|
|
1919
|
+
The following examples set the filter type, and then return the current configuration of the filter type:
|
|
1920
|
+
|
|
1921
|
+
> :CONF:FILT AVG
|
|
1922
|
+
> :CONF:FILT?
|
|
1923
|
+
< AVG
|
|
1924
|
+
|
|
1925
|
+
> :CONF:FILT RAW
|
|
1926
|
+
> :CONF:FILT?
|
|
1927
|
+
< RAW
|
|
1928
|
+
"""
|
|
1929
|
+
|
|
1930
|
+
pass
|
|
1931
|
+
|
|
1932
|
+
@dynamic_command(
|
|
1933
|
+
cmd_string=":CONFigure:SCAn:BUFfer?",
|
|
1934
|
+
cmd_type=CommandType.TRANSACTION,
|
|
1935
|
+
process_cmd_string=add_lf,
|
|
1936
|
+
process_response=to_int,
|
|
1937
|
+
)
|
|
1938
|
+
def get_scan_circular_buffer_size(self) -> int:
|
|
1939
|
+
"""Returns the size of the circular buffer that is used to store the scan data.
|
|
1940
|
+
|
|
1941
|
+
Returns:
|
|
1942
|
+
Size of the circular buffer that is used to store the scan data [bytes].
|
|
1943
|
+
|
|
1944
|
+
Examples:
|
|
1945
|
+
The following example returns the size of the circular buffer that is used to store scan data on the
|
|
1946
|
+
instrument:
|
|
1947
|
+
|
|
1948
|
+
> :CONFigure:SCAn:BUFfer?
|
|
1949
|
+
< 1048576
|
|
1950
|
+
> :CONFigure:SCAn:BUF:LEN?
|
|
1951
|
+
< 1048576
|
|
1952
|
+
> :CONFigure:SCAn:BUFfer?
|
|
1953
|
+
< 1048576
|
|
1954
|
+
> :CONFigure:SCAn:BUF?
|
|
1955
|
+
< 1048576
|
|
1956
|
+
"""
|
|
1957
|
+
|
|
1958
|
+
pass
|
|
1959
|
+
|
|
1960
|
+
@dynamic_command(
|
|
1961
|
+
cmd_string=":CONFigure:SCAn:CJC ${cjc}",
|
|
1962
|
+
cmd_type=CommandType.WRITE,
|
|
1963
|
+
process_cmd_string=add_lf,
|
|
1964
|
+
)
|
|
1965
|
+
def set_scan_cjc(self, cjc: str | int) -> None:
|
|
1966
|
+
"""Enable the capacity of returning CJC data in the analogue input data stream.
|
|
1967
|
+
|
|
1968
|
+
Allowed values are:
|
|
1969
|
+
- ON or any non-zero numerical value: Return CJC data in the analogue input stream.
|
|
1970
|
+
- OFF, 0, or DEFault: Don't return CJC in the analogue input stream.
|
|
1971
|
+
|
|
1972
|
+
This is a password-protected command.
|
|
1973
|
+
|
|
1974
|
+
Args:
|
|
1975
|
+
cjc (str): Enable the capacity of returning CJC data in the analogue input data stream.
|
|
1976
|
+
|
|
1977
|
+
Examples:
|
|
1978
|
+
Any of the following commands disables the capability of returning CJC data in the analogue input data
|
|
1979
|
+
stream:
|
|
1980
|
+
> :CONF:SCAn:CJC;:CONF:SCAn:CJC?
|
|
1981
|
+
< 0
|
|
1982
|
+
> :CONF:SCAn:CJC OFF;:CONF:SCAn:CJC?
|
|
1983
|
+
< 0
|
|
1984
|
+
> :CONF:SCAn:CJC DEF;:CONF:SCAn:CJC?
|
|
1985
|
+
< 0
|
|
1986
|
+
> :CONF:SCAn:CJC 0;:CONF:SCAn:CJC?
|
|
1987
|
+
< 0
|
|
1988
|
+
> :CONF:SCAn:CJC ON;:CONF:SCAn:CJC?
|
|
1989
|
+
< 1
|
|
1990
|
+
> :CONF:SCAn:CJC 1;:CONF:SCAn:CJC?
|
|
1991
|
+
< 1
|
|
1992
|
+
> :CONF:SCAn:CJC 34;:CONF:SCAn:CJC?
|
|
1993
|
+
< 1
|
|
1994
|
+
"""
|
|
1995
|
+
|
|
1996
|
+
pass
|
|
1997
|
+
|
|
1998
|
+
@dynamic_command(
|
|
1999
|
+
cmd_string=":CONFigure:SCAn:CJC?",
|
|
2000
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2001
|
+
process_cmd_string=add_lf,
|
|
2002
|
+
process_response=to_int,
|
|
2003
|
+
)
|
|
2004
|
+
def get_scan_cjc(self) -> int:
|
|
2005
|
+
"""Returns the currently configured CJC data in the analogue input data stream.
|
|
2006
|
+
|
|
2007
|
+
Allowed values are:
|
|
2008
|
+
- 1: Return CJC data in the analogue input stream.
|
|
2009
|
+
- 0: Don't return CJC in the analogue input stream.
|
|
2010
|
+
|
|
2011
|
+
Refer to 1999 SCPI Syntax & Style, Sect. 7.3 for more information.
|
|
2012
|
+
|
|
2013
|
+
Returns:
|
|
2014
|
+
If the capability of returning CJC data in the analogue input data stream is enabled, a value of 1 is
|
|
2015
|
+
returned. If the capability of returning CJC data in the analogue input data stream is disabled, a value
|
|
2016
|
+
of 0 is returned.
|
|
2017
|
+
|
|
2018
|
+
Examples:
|
|
2019
|
+
Any of the following commands disables the capability of returning CJC data in the analogue input data
|
|
2020
|
+
stream:
|
|
2021
|
+
> :CONF:SCAn:CJC;:CONF:SCAn:CJC?
|
|
2022
|
+
< 0
|
|
2023
|
+
> :CONF:SCAn:CJC OFF;:CONF:SCAn:CJC?
|
|
2024
|
+
< 0
|
|
2025
|
+
> :CONF:SCAn:CJC DEF;:CONF:SCAn:CJC?
|
|
2026
|
+
< 0
|
|
2027
|
+
> :CONF:SCAn:CJC 0;:CONF:SCAn:CJC?
|
|
2028
|
+
< 0
|
|
2029
|
+
> :CONF:SCAn:CJC ON;:CONF:SCAn:CJC?
|
|
2030
|
+
< 1
|
|
2031
|
+
> :CONF:SCAn:CJC 1;:CONF:SCAn:CJC?
|
|
2032
|
+
< 1
|
|
2033
|
+
> :CONF:SCAn:CJC 34;:CONF:SCAn:CJC?
|
|
2034
|
+
< 1
|
|
2035
|
+
"""
|
|
2036
|
+
|
|
2037
|
+
pass
|
|
2038
|
+
|
|
2039
|
+
@dynamic_command(
|
|
2040
|
+
cmd_string=":CONFigure:SCAn:LISt ${channels}",
|
|
2041
|
+
cmd_type=CommandType.WRITE,
|
|
2042
|
+
process_cmd_string=add_lf,
|
|
2043
|
+
)
|
|
2044
|
+
def set_scan_list(self, channels: str = "(@0:47)") -> None:
|
|
2045
|
+
"""Enables a list of channels to scan on the instrument.
|
|
2046
|
+
|
|
2047
|
+
This is a password-protected command.
|
|
2048
|
+
|
|
2049
|
+
Refer to 1999 SCPI Syntax & Style, Sect. 8.3.2, for more information.
|
|
2050
|
+
|
|
2051
|
+
Args:
|
|
2052
|
+
channels (str): List of channels to scan on the instrument.
|
|
2053
|
+
|
|
2054
|
+
Examples:
|
|
2055
|
+
This example enables channels 0, 4, 5, and 7 and then returns the list of enabled channels; note that while
|
|
2056
|
+
this command tries to enable channel 5 twice, it is enabled only once:
|
|
2057
|
+
|
|
2058
|
+
> :CONF:SCAn:LISt (@5,4,7,0,5)
|
|
2059
|
+
> :CONF:SCAn:LISt?
|
|
2060
|
+
< (@0,4:5,7)
|
|
2061
|
+
|
|
2062
|
+
This example disables all channels; the list of enabled channels is empty:
|
|
2063
|
+
> :CONF:SCAn:LISt
|
|
2064
|
+
> :CONF:SCAn:LISt?
|
|
2065
|
+
< (@)
|
|
2066
|
+
This command enables channels 0, 4, 5, and 7 and returns the list of enabled channels:
|
|
2067
|
+
> :CONF:SCAn:LISt (@5,4,7,0)
|
|
2068
|
+
> :CONF:SCAn:LISt?
|
|
2069
|
+
< (@0,4:5,7)
|
|
2070
|
+
|
|
2071
|
+
This command enables channels 0, 4, 5, 6, and 7 and returns the list of enabled channels:
|
|
2072
|
+
> :CONF:SCAn:LISt (@5,4,7,6,0)
|
|
2073
|
+
> :CONF:SCAn:LISt?
|
|
2074
|
+
< (@0,4:7)
|
|
2075
|
+
"""
|
|
2076
|
+
|
|
2077
|
+
pass
|
|
2078
|
+
|
|
2079
|
+
@dynamic_command(
|
|
2080
|
+
cmd_string=":CONFigure:SCAn:LISt?",
|
|
2081
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2082
|
+
process_cmd_string=add_lf,
|
|
2083
|
+
)
|
|
2084
|
+
def get_scan_list(self) -> str:
|
|
2085
|
+
"""Returns the list of channels that are enabled for scanning on the instrument.
|
|
2086
|
+
|
|
2087
|
+
Returns:
|
|
2088
|
+
List of channels that are enabled for scanning on the instrument.
|
|
2089
|
+
|
|
2090
|
+
Examples:
|
|
2091
|
+
The following example enables channels 0, 4, 5, and 7 and then returns the list of enabled channels; note
|
|
2092
|
+
that while this command tries to enable channel 5 twice, it is enabled only once:
|
|
2093
|
+
> :CONF:SCAn:LISt (@5,4,7,0,5)
|
|
2094
|
+
> :CONF:SCAn:LISt?
|
|
2095
|
+
< (@0,4:5,7)
|
|
2096
|
+
|
|
2097
|
+
This example disables all channels; the list of enabled channels is empty:
|
|
2098
|
+
> :CONF:SCAn:LISt;:CONF:SCAN:LISt?
|
|
2099
|
+
< (@)
|
|
2100
|
+
|
|
2101
|
+
This example enables channels 0, 4, 5, and 7 and then returns the list of enabled channels:
|
|
2102
|
+
> :CONF:SCAn:LISt (@5,4,7,0)
|
|
2103
|
+
> :CONF:SCAn:LISt?
|
|
2104
|
+
< (@0,4:5,7)
|
|
2105
|
+
|
|
2106
|
+
This example enables channels 0, 4, 5, 6, and 7 and then returns the list of enabled channels:
|
|
2107
|
+
> :CONF:SCAn:LISt (@5,4,7,6,0)
|
|
2108
|
+
> :CONF:SCAn:LISt?
|
|
2109
|
+
< (@0,4:7)
|
|
2110
|
+
"""
|
|
2111
|
+
|
|
2112
|
+
pass
|
|
2113
|
+
|
|
2114
|
+
@dynamic_command(
|
|
2115
|
+
cmd_string=":CONFigure:SCAn:RATe:SEC ${rate}",
|
|
2116
|
+
cmd_type=CommandType.WRITE,
|
|
2117
|
+
process_cmd_string=add_lf,
|
|
2118
|
+
)
|
|
2119
|
+
def set_scan_rate(self, rate: float) -> None:
|
|
2120
|
+
"""Configures the time period of each scan.
|
|
2121
|
+
|
|
2122
|
+
This is a password-protected command.
|
|
2123
|
+
|
|
2124
|
+
Args:
|
|
2125
|
+
rate (float): Time period of each scan [s].
|
|
2126
|
+
|
|
2127
|
+
Examples:
|
|
2128
|
+
|
|
2129
|
+
"""
|
|
2130
|
+
|
|
2131
|
+
pass
|
|
2132
|
+
|
|
2133
|
+
@dynamic_command(
|
|
2134
|
+
cmd_string=":CONFigure:SCAn:RATe:HZ ${frequency}",
|
|
2135
|
+
cmd_type=CommandType.WRITE,
|
|
2136
|
+
process_cmd_string=add_lf,
|
|
2137
|
+
)
|
|
2138
|
+
def set_scan_frequency(self, frequency: float) -> None:
|
|
2139
|
+
"""Configures the time period of each scan.
|
|
2140
|
+
|
|
2141
|
+
This is a password-protected command.
|
|
2142
|
+
|
|
2143
|
+
Args:
|
|
2144
|
+
frequency (float): Scan frequency [Hz].
|
|
2145
|
+
|
|
2146
|
+
Examples:
|
|
2147
|
+
The following command tries to set the scan frequency to 3Hz, but the actual scan frequency is set to 3.3Hz,
|
|
2148
|
+
which corresponds to a scan rate of 0.3s:
|
|
2149
|
+
|
|
2150
|
+
> :CONF:SCAn:RATe:HZ 3
|
|
2151
|
+
> :CONF:SCAn:RATe:HZ?
|
|
2152
|
+
< 3.333333
|
|
2153
|
+
> :CONF:SCAN:RATe?
|
|
2154
|
+
< 0.300000
|
|
2155
|
+
|
|
2156
|
+
The following command sets the scan frequency to 2Hz, which corresponds to a scan rate of 0.5s; the actual
|
|
2157
|
+
scan frequency is set to the same value, since 2 is an exact divisor of 10.0Hz:
|
|
2158
|
+
|
|
2159
|
+
> :CONF:SCAn:RATe 0.5
|
|
2160
|
+
> :CONF:SCAn:RATe:HZ?
|
|
2161
|
+
< 2.000000
|
|
2162
|
+
> :CONF:SCAN:RATe?
|
|
2163
|
+
< 0.500000
|
|
2164
|
+
|
|
2165
|
+
In this example, an invalid scan frequency is specified, and an Execution Error occurs. If bit 4 (E) of
|
|
2166
|
+
the Standard Event Status Enable register is enabled, an Execution Error sets bit 4 (E) of the Standard
|
|
2167
|
+
Event Status register. This, in turn, sets bits 2 and 5 of the Status Byte register:
|
|
2168
|
+
|
|
2169
|
+
> :CONF:SCAn:RATe:HZ 200
|
|
2170
|
+
> *STB?
|
|
2171
|
+
< 36
|
|
2172
|
+
> *ESR?
|
|
2173
|
+
< 16
|
|
2174
|
+
> *STB?
|
|
2175
|
+
< 4
|
|
2176
|
+
> :SYST:ERR?
|
|
2177
|
+
< -222,"Data out of range; CONF:SCAn:RATe"
|
|
2178
|
+
> *STB?
|
|
2179
|
+
< 0
|
|
2180
|
+
"""
|
|
2181
|
+
|
|
2182
|
+
pass
|
|
2183
|
+
|
|
2184
|
+
@dynamic_command(
|
|
2185
|
+
cmd_string=":CONFigure:SCAn:RATe:SEC?",
|
|
2186
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2187
|
+
process_cmd_string=add_lf,
|
|
2188
|
+
process_response=to_float,
|
|
2189
|
+
)
|
|
2190
|
+
def get_scan_rate(self) -> float:
|
|
2191
|
+
"""Returns the time period of each scan [s]."""
|
|
2192
|
+
pass
|
|
2193
|
+
|
|
2194
|
+
@dynamic_command(
|
|
2195
|
+
cmd_string=":CONFigure:SCAn:RATe:HZ?",
|
|
2196
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2197
|
+
process_cmd_string=add_lf,
|
|
2198
|
+
process_response=to_float,
|
|
2199
|
+
)
|
|
2200
|
+
def get_scan_frequency(self) -> float:
|
|
2201
|
+
"""Returns the scan frequency [Hz].
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
Examples:
|
|
2205
|
+
The following command tries to set the scan frequency to 3Hz, but the actual scan frequency is set to 3.3Hz,
|
|
2206
|
+
which corresponds to a scan rate of 0.3s:
|
|
2207
|
+
|
|
2208
|
+
> :CONF:SCAn:RATe:HZ 3
|
|
2209
|
+
> :CONF:SCAn:RATe:HZ?
|
|
2210
|
+
< 3.333333
|
|
2211
|
+
> :CONF:SCAN:RATe?
|
|
2212
|
+
< 0.300000
|
|
2213
|
+
|
|
2214
|
+
The following command sets the scan frequency to 2 Hz, which corresponds to a scan rate of 0.5 s; the
|
|
2215
|
+
actual scan frequency is set to the same value, since 2 is an exact divisor of 10.0 Hz:
|
|
2216
|
+
|
|
2217
|
+
> :CONF:SCAn:RATe 0.5
|
|
2218
|
+
> :CONF:SCAn:RATe:HZ?
|
|
2219
|
+
< 2.000000
|
|
2220
|
+
> :CONF:SCAN:RATe?
|
|
2221
|
+
< 0.500000
|
|
2222
|
+
|
|
2223
|
+
In this example, an invalid scan frequency is specified and an Execution Error occurs. If bit 4 (E) of the
|
|
2224
|
+
Standard Event Status Enable register is enabled, an Execution Error sets bit 4 (E) of the Standard Event
|
|
2225
|
+
Status register. This, in turn, sets bits 2 and 5 of the Status Byte register:
|
|
2226
|
+
|
|
2227
|
+
> :CONF:SCAn:RATe:HZ 200
|
|
2228
|
+
> *STB?
|
|
2229
|
+
< 36
|
|
2230
|
+
> *ESR?
|
|
2231
|
+
< 16
|
|
2232
|
+
> *STB?
|
|
2233
|
+
< 4
|
|
2234
|
+
> :SYST:ERR?
|
|
2235
|
+
< -222,"Data out of range; CONF:SCAn:RATe"
|
|
2236
|
+
> *STB?
|
|
2237
|
+
< 0
|
|
2238
|
+
"""
|
|
2239
|
+
|
|
2240
|
+
pass
|
|
2241
|
+
|
|
2242
|
+
@dynamic_command(
|
|
2243
|
+
cmd_string=":CONFigure:TRIGger:SOURce ${source}",
|
|
2244
|
+
cmd_type=CommandType.WRITE,
|
|
2245
|
+
process_cmd_string=add_lf,
|
|
2246
|
+
)
|
|
2247
|
+
def set_trigger_source(self, source: str) -> None:
|
|
2248
|
+
"""Configures the trigger source used to start the analogue input operation.
|
|
2249
|
+
|
|
2250
|
+
This is a password-protected command.
|
|
2251
|
+
|
|
2252
|
+
Allowed sources are:
|
|
2253
|
+
- IMMediate or DEFault: Specifies a software trigger.
|
|
2254
|
+
- DIN0: Specifies an external, digital trigger on DIN0.
|
|
2255
|
+
|
|
2256
|
+
Args:
|
|
2257
|
+
source (str): Trigger used to start the analogue input operation.
|
|
2258
|
+
|
|
2259
|
+
Examples:
|
|
2260
|
+
The following command sets the trigger source to the external, digital trigger:
|
|
2261
|
+
|
|
2262
|
+
> :CONF:TRIG DIN0
|
|
2263
|
+
"""
|
|
2264
|
+
|
|
2265
|
+
pass
|
|
2266
|
+
|
|
2267
|
+
@dynamic_command(
|
|
2268
|
+
cmd_string=":CONFigure:TRIGger:SOURce?",
|
|
2269
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2270
|
+
process_cmd_string=add_lf,
|
|
2271
|
+
)
|
|
2272
|
+
def get_trigger_source(self) -> str:
|
|
2273
|
+
"""Returns the currently configured trigger source used to start the analogue input operation.
|
|
2274
|
+
|
|
2275
|
+
Allowed sources are:
|
|
2276
|
+
- IMMediate or DEFault: Specifies a software trigger.
|
|
2277
|
+
- DIN0: Specifies an external, digital trigger on DIN0.
|
|
2278
|
+
|
|
2279
|
+
Returns:
|
|
2280
|
+
Currently configured trigger source used to start the analogue input operation.
|
|
2281
|
+
|
|
2282
|
+
Examples:
|
|
2283
|
+
The following returns the currently configured trigger source of the instrument; in this case, an external
|
|
2284
|
+
digital trigger is configured:
|
|
2285
|
+
|
|
2286
|
+
> :CONF:TRIG?
|
|
2287
|
+
< DIN0
|
|
2288
|
+
"""
|
|
2289
|
+
|
|
2290
|
+
pass
|
|
2291
|
+
|
|
2292
|
+
# MEASure Sub-System Commands
|
|
2293
|
+
|
|
2294
|
+
@dynamic_command(
|
|
2295
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2296
|
+
cmd_string="MEASure:RESistance? ${channels}",
|
|
2297
|
+
process_cmd_string=add_lf,
|
|
2298
|
+
process_response=parse_single_measurement,
|
|
2299
|
+
)
|
|
2300
|
+
def get_resistance(self, channels: str = "(@0:47)") -> tuple[float, ...]:
|
|
2301
|
+
"""Configures and returns the resistance measurement values for the specified channels.
|
|
2302
|
+
|
|
2303
|
+
This is a password-protected command.
|
|
2304
|
+
|
|
2305
|
+
Examples:
|
|
2306
|
+
The following example configures analogue input channels 0 for a resistance measurement and reads the
|
|
2307
|
+
resistance value from this channel:
|
|
2308
|
+
|
|
2309
|
+
> :MEAS:RES? (@0)
|
|
2310
|
+
< 2331344488fe4f0a
|
|
2311
|
+
|
|
2312
|
+
where:
|
|
2313
|
+
- 23 = '#' denotes the start of the block response
|
|
2314
|
+
- 31 = '1' is the length of the decimal number for the block length
|
|
2315
|
+
- 34 = '4' is the block length (that is 4-bytes per channel)
|
|
2316
|
+
- 4488fe4f = 1095.947 ohms; this is the resistance measurement value from channel 0
|
|
2317
|
+
- 0a = carriage return; this is the standard ASCII terminator
|
|
2318
|
+
|
|
2319
|
+
Args:
|
|
2320
|
+
channels (str): List of channels to configure for resistance measurements.
|
|
2321
|
+
|
|
2322
|
+
Returns:
|
|
2323
|
+
Data block of up to 48 single-precision, floating point values, where each value corresponds to a channel
|
|
2324
|
+
in the given list of channels [Ohm].
|
|
2325
|
+
"""
|
|
2326
|
+
|
|
2327
|
+
pass
|
|
2328
|
+
|
|
2329
|
+
@dynamic_command(
|
|
2330
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2331
|
+
cmd_string="MEASure:TEMPerature:RTD? ${rtd_type},${channels}",
|
|
2332
|
+
process_cmd_string=add_lf,
|
|
2333
|
+
process_response=parse_single_measurement,
|
|
2334
|
+
)
|
|
2335
|
+
def get_rtd_temperature(self, rtd_type: str, channels: str = "(@0:47)") -> tuple[float, ...]:
|
|
2336
|
+
"""Configures and returns the RTD temperature measurement values for the specified channels.
|
|
2337
|
+
|
|
2338
|
+
This is a password-protected command.
|
|
2339
|
+
|
|
2340
|
+
Allowed RTD types are:
|
|
2341
|
+
- For 2- or 4-wire European RTDs:
|
|
2342
|
+
- PT100
|
|
2343
|
+
- PT500
|
|
2344
|
+
- PT1000
|
|
2345
|
+
- For 2- or 4-wire American RTDs:
|
|
2346
|
+
- A_PT100
|
|
2347
|
+
- A_PT500
|
|
2348
|
+
- A_PT1000
|
|
2349
|
+
- For 3-wire European RTDs:
|
|
2350
|
+
- PT100_3
|
|
2351
|
+
- PT500_3
|
|
2352
|
+
- PT1000_3
|
|
2353
|
+
- For 3-wire American RTDs:
|
|
2354
|
+
- A_PT100_3
|
|
2355
|
+
- A_PT500_3
|
|
2356
|
+
- A_PT1000_3
|
|
2357
|
+
- DEFault
|
|
2358
|
+
|
|
2359
|
+
Args:
|
|
2360
|
+
rtd_type (str): RTD type to be used for the temperature measurement.
|
|
2361
|
+
channels (str): List of channels to configure for RTD temperature measurement.
|
|
2362
|
+
|
|
2363
|
+
Returns:
|
|
2364
|
+
Data block of up to 48 single-precision, floating point values, where each value corresponds to a channel
|
|
2365
|
+
in the given list of channels [°C].
|
|
2366
|
+
|
|
2367
|
+
Examples:
|
|
2368
|
+
The following example configures analogue input channels 0, 1, 7 for the default sensor and transducer type
|
|
2369
|
+
for the instrument and then reads the temperature from these channels:
|
|
2370
|
+
|
|
2371
|
+
> :MEAS:TEMP:RTD? DEF,(@0,1,7)
|
|
2372
|
+
< 23323132c7ad9c0041bd99b647c34f800a
|
|
2373
|
+
|
|
2374
|
+
where:
|
|
2375
|
+
- 23 = '#' denotes the start of the block response
|
|
2376
|
+
- 32 = '2' is the length of the decimal number for the block length
|
|
2377
|
+
- 3132 = '12' is the block length (that is 4-bytes per channel times 3)
|
|
2378
|
+
- c7ad9c00 = –88888° C; this is the measurement value from channel 0, indicating that the value is too
|
|
2379
|
+
low and out of range
|
|
2380
|
+
- 41bd99b6 = 27.7° C; this is the measurement value from channel 1
|
|
2381
|
+
- 47c34f80 = 99999° C; this is the measurement value from channel 7
|
|
2382
|
+
- 0a = carriage return; this is the standard ASCII terminator
|
|
2383
|
+
"""
|
|
2384
|
+
|
|
2385
|
+
pass
|
|
2386
|
+
|
|
2387
|
+
@dynamic_command(
|
|
2388
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2389
|
+
cmd_string="MEASure:TEMPerature:TCouple?,${channels}",
|
|
2390
|
+
process_cmd_string=add_lf,
|
|
2391
|
+
process_response=parse_single_measurement,
|
|
2392
|
+
)
|
|
2393
|
+
def get_thermocouple_temperature(self, tc_type: str, channels: str = "(@0:47)") -> tuple[float, ...]:
|
|
2394
|
+
"""Configures and returns the RTD temperature measurement values for the specified channels.
|
|
2395
|
+
|
|
2396
|
+
This is a password-protected command.
|
|
2397
|
+
|
|
2398
|
+
Allowed thermocouple types are:
|
|
2399
|
+
- J (Iron/Constantan)
|
|
2400
|
+
- K (Nickel-Chromium / Nickel-Alumel)
|
|
2401
|
+
- B (Platinum Rhodium -30% / Platinum Rhodium -6%)
|
|
2402
|
+
- E (Nickel-Chromium/Constantan)
|
|
2403
|
+
- N (Nicrosil/Nisil)
|
|
2404
|
+
- R (Platinum Rhodium -13% / Platinum)
|
|
2405
|
+
- S (Platinum Rhodium -10% / Platinum)
|
|
2406
|
+
- T (Copper/Constantan)
|
|
2407
|
+
- DEFault
|
|
2408
|
+
|
|
2409
|
+
Args:
|
|
2410
|
+
tc_type (str): Thermocouple type to be used for the temperature measurements.
|
|
2411
|
+
channels (str): List of channels to configure for RTD temperature measurement.
|
|
2412
|
+
|
|
2413
|
+
Returns:
|
|
2414
|
+
Data block of up to 48 single-precision, floating point values, where each value corresponds to a channel
|
|
2415
|
+
in the given list of channels [°C].
|
|
2416
|
+
|
|
2417
|
+
Examples:
|
|
2418
|
+
The following example configures analogue input channels 0, 1, 7 for the default sensor and transducer type
|
|
2419
|
+
for the instrument and then reads the temperature from these channels:
|
|
2420
|
+
|
|
2421
|
+
> :MEAS:TEMP:TC? DEF,(@0,1,7)
|
|
2422
|
+
< 23323132c7ad9c0041bd99b647c34f800a
|
|
2423
|
+
|
|
2424
|
+
where:
|
|
2425
|
+
- 23 = '#' denotes the start of the block response
|
|
2426
|
+
- 32 = '2' is the length of the decimal number for the block length
|
|
2427
|
+
- 3132 = '12' is the block length (that is 4-bytes per channel times 3)
|
|
2428
|
+
- c7ad9c00 = –88888° C; this is the measurement value from channel 0, indicating that the value is too
|
|
2429
|
+
low and out of range
|
|
2430
|
+
- 41bd99b6 = 27.7° C; this is the measurement value from channel 1
|
|
2431
|
+
- 47c34f80 = 99999° C; this is the measurement value from channel 7, indicating that an open
|
|
2432
|
+
thermocouple exists on that channel
|
|
2433
|
+
- 0a = carriage return; this is the standard ASCII terminator
|
|
2434
|
+
"""
|
|
2435
|
+
|
|
2436
|
+
pass
|
|
2437
|
+
|
|
2438
|
+
@dynamic_command(
|
|
2439
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2440
|
+
cmd_string="MEASure:VOLTage? ${channels}",
|
|
2441
|
+
process_cmd_string=add_lf,
|
|
2442
|
+
process_response=parse_single_measurement,
|
|
2443
|
+
)
|
|
2444
|
+
def get_voltage(self, channels: str = "(@0:47)") -> tuple[float, ...]:
|
|
2445
|
+
"""Configures and returns the voltage measurement values for the specified channels.
|
|
2446
|
+
|
|
2447
|
+
This is a password-protected command.
|
|
2448
|
+
|
|
2449
|
+
Args:
|
|
2450
|
+
channels (str): List of channels to configure for RTD temperature measurement.
|
|
2451
|
+
|
|
2452
|
+
Returns:
|
|
2453
|
+
Data block of up to 48 single-precision, floating point values, where each value corresponds to a channel
|
|
2454
|
+
in the given list of channels [V].
|
|
2455
|
+
|
|
2456
|
+
Examples:
|
|
2457
|
+
The following example configures analogue input channels 0, 1, 7 for voltage measurements and then reads
|
|
2458
|
+
the values from these channels:
|
|
2459
|
+
|
|
2460
|
+
> :MEAS:VOLT? (@0,1,7)
|
|
2461
|
+
< 233231323f0f8aec3edefa51bf2844b80a
|
|
2462
|
+
|
|
2463
|
+
where:
|
|
2464
|
+
- 23 = '#' denotes the start of the block response
|
|
2465
|
+
- 32 = '2' is the length of the decimal number for the block length
|
|
2466
|
+
- 3132 = '12' is the block length (that is 4-bytes per channel times 3)
|
|
2467
|
+
- 3f0f8aec = 0.56071 V; this is the measurement value from channel 0
|
|
2468
|
+
- 3edefa51 = 0.43550 V; this is the measurement value from channel 1
|
|
2469
|
+
- bf2844b8 = –0.65729 V; this is the measurement value from channel 7
|
|
2470
|
+
- 0a = carriage return; this is the standard ASCII terminator
|
|
2471
|
+
"""
|
|
2472
|
+
|
|
2473
|
+
# INITiate Sub-System Command
|
|
2474
|
+
|
|
2475
|
+
@dynamic_command(
|
|
2476
|
+
cmd_string=":INITiate",
|
|
2477
|
+
cmd_type=CommandType.WRITE,
|
|
2478
|
+
process_cmd_string=add_lf,
|
|
2479
|
+
)
|
|
2480
|
+
def init_scan(self) -> None:
|
|
2481
|
+
"""Initiates a continuous scan operation on an instrument.
|
|
2482
|
+
|
|
2483
|
+
The continuous scan operation uses the configured channels, scan list, scan rate, and trigger source.
|
|
2484
|
+
|
|
2485
|
+
This is a password-protected command.
|
|
2486
|
+
|
|
2487
|
+
Examples:
|
|
2488
|
+
The following example configures the instrument to scan channels 0 to 5 at approximately 2Hz when an
|
|
2489
|
+
external digital trigger is detected, and queries the Operation Status register to verify that a scan
|
|
2490
|
+
operation is not in process:
|
|
2491
|
+
|
|
2492
|
+
> :CONF:SCA:LIS?
|
|
2493
|
+
< (@)
|
|
2494
|
+
>:CONF:SCA:LIS (@0:5)
|
|
2495
|
+
>:CONF:TRIG IMM
|
|
2496
|
+
> :CONF:SCA:RAT:HZ 2
|
|
2497
|
+
> :CONF:SCA:RAT:HZ?
|
|
2498
|
+
< 1.875000
|
|
2499
|
+
> :STAT:OPER:COND?
|
|
2500
|
+
< 0
|
|
2501
|
+
|
|
2502
|
+
The scan is then initiated, and bit 7 of the Status Byte register and the Operation Status register are
|
|
2503
|
+
queried to determine the status of the scan and whether the instrument has detected the trigger:
|
|
2504
|
+
|
|
2505
|
+
> :INIT
|
|
2506
|
+
> *STB?
|
|
2507
|
+
< 128
|
|
2508
|
+
> :STAT:OPER:COND?
|
|
2509
|
+
< 48
|
|
2510
|
+
|
|
2511
|
+
In this case, the scan has started, and the instrument is waiting for the trigger. The next query confirms
|
|
2512
|
+
that the trigger occurred and the instrument is scanning:
|
|
2513
|
+
|
|
2514
|
+
> *STB?
|
|
2515
|
+
< 128
|
|
2516
|
+
> :STAT:OPER:COND?
|
|
2517
|
+
< 16
|
|
2518
|
+
|
|
2519
|
+
The scan is then stopped and bit 7 of the Status Byte register and the Operation Status register are cleared:
|
|
2520
|
+
|
|
2521
|
+
> :ABOR
|
|
2522
|
+
> :STAT:OPER:COND?
|
|
2523
|
+
< 0
|
|
2524
|
+
> *STB?
|
|
2525
|
+
< 0
|
|
2526
|
+
"""
|
|
2527
|
+
|
|
2528
|
+
pass
|
|
2529
|
+
|
|
2530
|
+
# ABORt Sub-System Command
|
|
2531
|
+
|
|
2532
|
+
@dynamic_command(
|
|
2533
|
+
cmd_string=":ABORt",
|
|
2534
|
+
cmd_type=CommandType.WRITE,
|
|
2535
|
+
process_cmd_string=add_lf,
|
|
2536
|
+
)
|
|
2537
|
+
def abort_scan(self) -> None:
|
|
2538
|
+
"""Stops a scan operation on the instrument.
|
|
2539
|
+
|
|
2540
|
+
If a scan is in progress, it will be stopped, regardless of whether the specified trigger occurred.
|
|
2541
|
+
|
|
2542
|
+
This is a password-protected command.
|
|
2543
|
+
|
|
2544
|
+
Examples:
|
|
2545
|
+
The following example configures the instrument to scan channels 0 to 5 at approximately 2Hz when a
|
|
2546
|
+
software trigger is detected and queries the Operation Status register to verify that scans are stopped:
|
|
2547
|
+
|
|
2548
|
+
> :CONF:SCA:LIS?
|
|
2549
|
+
< (@)
|
|
2550
|
+
> :CONF:SCA:LIS (@0:5)
|
|
2551
|
+
> :CONF:TRIG IMM
|
|
2552
|
+
> :CONF:SCA:RAT:HZ 2
|
|
2553
|
+
> :CONF:SCA:RAT:HZ?
|
|
2554
|
+
< 1.875000
|
|
2555
|
+
> :STAT:OPER:COND?
|
|
2556
|
+
< 0
|
|
2557
|
+
|
|
2558
|
+
The scan is then started, and bit 7 of the Status Byte register the Operation Status register are queried
|
|
2559
|
+
to determine the status of the scan:
|
|
2560
|
+
|
|
2561
|
+
> :INIT
|
|
2562
|
+
> *STB?
|
|
2563
|
+
< 128
|
|
2564
|
+
> :STAT:OPER:COND?
|
|
2565
|
+
< 16
|
|
2566
|
+
|
|
2567
|
+
The scan is then stopped and bit 7 of the Status Byte register and the Operation Status register are cleared:
|
|
2568
|
+
|
|
2569
|
+
> :ABOR
|
|
2570
|
+
> :STAT:OPER:COND?
|
|
2571
|
+
< 0
|
|
2572
|
+
> *STB?
|
|
2573
|
+
< 0
|
|
2574
|
+
"""
|
|
2575
|
+
|
|
2576
|
+
pass
|
|
2577
|
+
|
|
2578
|
+
# FETCh Sub-System Command
|
|
2579
|
+
|
|
2580
|
+
@dynamic_command(
|
|
2581
|
+
cmd_string=":FETCh? ${index}, ${num_scans}",
|
|
2582
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2583
|
+
process_cmd_string=add_lf,
|
|
2584
|
+
process_response=parse_scan_records,
|
|
2585
|
+
)
|
|
2586
|
+
def fetch_data(self, index: int, num_scans: int) -> list[ScanRecord]:
|
|
2587
|
+
"""Returns time-stamped, sequenced measurements from the circular buffer on the instrument, as scan records.
|
|
2588
|
+
|
|
2589
|
+
This only applies to the scans that were started with the INITiate command (`init_scan`).
|
|
2590
|
+
|
|
2591
|
+
Args:
|
|
2592
|
+
index (int): Index of the san record (offset in the circular buffer) from which to retrieve data. To read the first scan records, specify `1`.
|
|
2593
|
+
num_scans (int): Number of scan records to retrieve from the circular buffer.
|
|
2594
|
+
|
|
2595
|
+
Returns:
|
|
2596
|
+
A list of scan records, each containing the time-stamped, sequenced measurements.
|
|
2597
|
+
|
|
2598
|
+
Examples:
|
|
2599
|
+
The following example returns scan records, starting with index 0, on an instrument that has one channel
|
|
2600
|
+
(channel 0) enabled in the scan list:
|
|
2601
|
+
|
|
2602
|
+
> :FETC? 0
|
|
2603
|
+
<
|
|
2604
|
+
23 ASCII # char that starts the IEEE block
|
|
2605
|
+
34 ASCII 4, meaning that the next 4 chars are the length of the IEEE block
|
|
2606
|
+
32303430 ASCII character 2040, representing the length of the entire IEEE block
|
|
2607
|
+
|
|
2608
|
+
4a806d65 Scan record time stamp, in seconds
|
|
2609
|
+
00000000 Scan record time stamp, in milliseconds
|
|
2610
|
+
00000001 Scan record scan number (1)
|
|
2611
|
+
00000001 Scan record number of values; 1 floating point value per scan
|
|
2612
|
+
3a86c3ff Value of chan 0 in floating-point 6.5565103e-4
|
|
2613
|
+
|
|
2614
|
+
4a806d65 Time stamp of next record, in seconds
|
|
2615
|
+
00000064 Time stamp, in milliseconds
|
|
2616
|
+
00000002 Scan number (2)
|
|
2617
|
+
00000001 Number of values (1)
|
|
2618
|
+
3a9a4bff Value of chan 0
|
|
2619
|
+
|
|
2620
|
+
4a806d65 Timestamp of next record, in seconds
|
|
2621
|
+
000000c8 Time stamp, in milliseconds
|
|
2622
|
+
00000003 Scan number (3)
|
|
2623
|
+
00000001 Number of values (1)
|
|
2624
|
+
3ac543ff Value of chan 0
|
|
2625
|
+
.
|
|
2626
|
+
.
|
|
2627
|
+
.
|
|
2628
|
+
4a806d6c Timestamp of next record, in seconds
|
|
2629
|
+
00000064 Time stamp, in milliseconds
|
|
2630
|
+
00000048 Scan number (48)
|
|
2631
|
+
00000001 Number of values (1)
|
|
2632
|
+
3a5ea800 Value of chan 0
|
|
2633
|
+
|
|
2634
|
+
This example returns two scan records (5 and 6) from an instrument that is scanning one channel:
|
|
2635
|
+
|
|
2636
|
+
> STATus:SCAn?
|
|
2637
|
+
< 1,1083
|
|
2638
|
+
> FETCh? 5, 2 (fetch records 5 and 6)
|
|
2639
|
+
23 ASCII # char that starts the IEEE block
|
|
2640
|
+
34 ASCII 4, meaning that the next 4 chars are the length of the IEEE block
|
|
2641
|
+
30303430 ASCII character 0040, the length of the entire IEEE block (10 4-byte fields)
|
|
2642
|
+
4a807ad3 Time stamp, in seconds
|
|
2643
|
+
00000190 Time stamp, in milliseconds
|
|
2644
|
+
00000005 Scan number (5)
|
|
2645
|
+
00000001 Number of values (1)
|
|
2646
|
+
3984cfff Value of channel
|
|
2647
|
+
4a807ad3 Time stamp of next record, in seconds
|
|
2648
|
+
000001f4 Time stamp, in milliseconds
|
|
2649
|
+
00000006 Scan number (6)
|
|
2650
|
+
00000001 Number of values (1)
|
|
2651
|
+
393b7fff Value of channel 6
|
|
2652
|
+
0a Carriage Return. This is the standard SCPI Terminator.
|
|
2653
|
+
"""
|
|
2654
|
+
|
|
2655
|
+
pass
|
|
2656
|
+
|
|
2657
|
+
# Digital INPut Sub-System Command
|
|
2658
|
+
|
|
2659
|
+
@dynamic_command(
|
|
2660
|
+
cmd_string=":INPut:STATe?",
|
|
2661
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2662
|
+
process_cmd_string=add_lf,
|
|
2663
|
+
process_response=to_int,
|
|
2664
|
+
)
|
|
2665
|
+
def get_digital_input_state(self) -> int:
|
|
2666
|
+
"""Returns the current state of the digital input port on the instrument.
|
|
2667
|
+
|
|
2668
|
+
Refer to the 1999 SCPI Data Exchange Format, Sect. 3.4.6, for more information on the data format.
|
|
2669
|
+
|
|
2670
|
+
Returns: Weighted bit value of the digital input port, where the value of bit 0 (digital input 0) corresponds
|
|
2671
|
+
to a decimal value of 1 (2**0) if the bit is set, and the value of bit 7 (digital input 7)
|
|
2672
|
+
corresponds to a decimal value of 128 (2**7) if the bit is set. Values range from 0 to 255.
|
|
2673
|
+
|
|
2674
|
+
Examples:
|
|
2675
|
+
This response indicates that digital input lines 1 and 7 (bits 1 and 7) of the digital input port are
|
|
2676
|
+
set:
|
|
2677
|
+
|
|
2678
|
+
> :INPut:STATe?
|
|
2679
|
+
< 130
|
|
2680
|
+
"""
|
|
2681
|
+
|
|
2682
|
+
pass
|
|
2683
|
+
|
|
2684
|
+
# Digital OUTPut Sub-System Commands
|
|
2685
|
+
|
|
2686
|
+
@dynamic_command(
|
|
2687
|
+
cmd_string=":OUTPut:STATe?",
|
|
2688
|
+
cmd_type=CommandType.TRANSACTION,
|
|
2689
|
+
process_cmd_string=add_lf,
|
|
2690
|
+
process_response=to_int,
|
|
2691
|
+
)
|
|
2692
|
+
def get_digital_output_state(self):
|
|
2693
|
+
"""Returns the current state of the digital output port on the instrument.
|
|
2694
|
+
|
|
2695
|
+
Refer to the 1999 SCPI Data Exchange Format, Sect. 3.4.6, for more information on the data format.
|
|
2696
|
+
|
|
2697
|
+
Returns: Weighted bit value of the digital output port, where the value of bit 0 (digital input 0) corresponds
|
|
2698
|
+
to a decimal value of 1 (2**0) if the bit is set, and the value of bit 7 (digital input 7)
|
|
2699
|
+
corresponds to a decimal value of 128 (2**7) if the bit is set. Values range from 0 to 255.
|
|
2700
|
+
|
|
2701
|
+
Examples:
|
|
2702
|
+
This response indicates that digital input lines 1 and 7 (bits 1 and 7) of the digital input port are
|
|
2703
|
+
set:
|
|
2704
|
+
|
|
2705
|
+
> :OUTPut:STATe?
|
|
2706
|
+
< 130
|
|
2707
|
+
"""
|
|
2708
|
+
|
|
2709
|
+
pass
|
|
2710
|
+
|
|
2711
|
+
@dynamic_command(
|
|
2712
|
+
cmd_string=":OUTPut:STATe ${state}",
|
|
2713
|
+
cmd_type=CommandType.WRITE,
|
|
2714
|
+
process_cmd_string=add_lf,
|
|
2715
|
+
)
|
|
2716
|
+
def set_digital_output_state(self, state: int):
|
|
2717
|
+
"""Sets the state of the digital output port on the instrument.
|
|
2718
|
+
|
|
2719
|
+
This is a password-protected command.
|
|
2720
|
+
|
|
2721
|
+
Refer to the 1999 SCPI Data Exchange Format, Sect. 3.4.6, for more information on the data format.
|
|
2722
|
+
|
|
2723
|
+
Args:
|
|
2724
|
+
state (int): Weighted bit value of the digital output port, where the value of bit 0 (digital input 0)
|
|
2725
|
+
corresponds to a decimal value of 1 (2**0) if the bit is set, and the value of bit 7
|
|
2726
|
+
(digital input 7) corresponds to a decimal value of 128 (2**7) if the bit is set. Values
|
|
2727
|
+
range from 0 to 255.
|
|
2728
|
+
|
|
2729
|
+
Examples:
|
|
2730
|
+
This command sets digital output lines 0 and 7 (bits 0 and 7) to 1, and all other digital output lines
|
|
2731
|
+
(bits) to 0:
|
|
2732
|
+
|
|
2733
|
+
> :OUTPut:STATe 129
|
|
2734
|
+
"""
|
|
2735
|
+
|
|
2736
|
+
pass
|
|
2737
|
+
|
|
2738
|
+
|
|
2739
|
+
class DigilentController(DigilentInterface, DynamicCommandMixin):
|
|
2740
|
+
def __init__(self):
|
|
2741
|
+
"""Initialisation of a Digilent controller."""
|
|
2742
|
+
|
|
2743
|
+
super().__init__()
|
|
2744
|
+
|
|
2745
|
+
# Define device interface in the sub-class
|
|
2746
|
+
|
|
2747
|
+
self.transport: DigilentEthernetInterface | None = None
|
|
2748
|
+
|
|
2749
|
+
# noinspection PyMethodMayBeStatic
|
|
2750
|
+
def is_simulator(self):
|
|
2751
|
+
return False
|
|
2752
|
+
|
|
2753
|
+
def is_connected(self):
|
|
2754
|
+
"""Checks whether the connection to the Digilent MEASURpoint is open.
|
|
2755
|
+
|
|
2756
|
+
Returns:
|
|
2757
|
+
True if the connection to the Digilent MEASURpoint is open; False otherwise.
|
|
2758
|
+
"""
|
|
2759
|
+
|
|
2760
|
+
return self.transport.is_connected()
|
|
2761
|
+
|
|
2762
|
+
def connect(self):
|
|
2763
|
+
"""Opens the connection to the Digilent MEASURpoint.
|
|
2764
|
+
|
|
2765
|
+
Raises:
|
|
2766
|
+
Dt8874Error: When the connection could not be opened.
|
|
2767
|
+
"""
|
|
2768
|
+
|
|
2769
|
+
self.transport.connect()
|
|
2770
|
+
|
|
2771
|
+
def disconnect(self):
|
|
2772
|
+
"""Closes the connection to the Digilent MEASURpoint.
|
|
2773
|
+
|
|
2774
|
+
Raises:
|
|
2775
|
+
Dt8874Error: When the connection could not be closed.
|
|
2776
|
+
"""
|
|
2777
|
+
|
|
2778
|
+
self.transport.disconnect()
|
|
2779
|
+
|
|
2780
|
+
def reconnect(self):
|
|
2781
|
+
"""Re-connects to the Digilent MEASURpoint."""
|
|
2782
|
+
|
|
2783
|
+
self.transport.reconnect()
|
|
2784
|
+
|
|
2785
|
+
|
|
2786
|
+
class DigilentSimulator(DigilentInterface):
|
|
2787
|
+
def __init__(self):
|
|
2788
|
+
"""Initialisation of a Digilent simulator."""
|
|
2789
|
+
|
|
2790
|
+
super().__init__()
|
|
2791
|
+
|
|
2792
|
+
self._is_connected = True
|
|
2793
|
+
|
|
2794
|
+
# noinspection PyMethodMayBeStatic
|
|
2795
|
+
def is_simulator(self):
|
|
2796
|
+
return True
|
|
2797
|
+
|
|
2798
|
+
# noinspection PyMethodMayBeStatic
|
|
2799
|
+
def is_connected(self):
|
|
2800
|
+
return self._is_connected
|
|
2801
|
+
|
|
2802
|
+
def connect(self):
|
|
2803
|
+
self._is_connected = True
|
|
2804
|
+
|
|
2805
|
+
def disconnect(self):
|
|
2806
|
+
self._is_connected = False
|
|
2807
|
+
|
|
2808
|
+
def reconnect(self):
|
|
2809
|
+
self._is_connected = True
|