-
Notifications
You must be signed in to change notification settings - Fork 2
/
ar488.py
139 lines (114 loc) · 3.63 KB
/
ar488.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import serial
import sys
# notes:
# '\r', '\n', and '+' are control characters that must be escaped in binary data
#
# Prologix commands:
# ++addr [1-29]
# ++auto [0 | 1 | 2 | 3]
# ++clr
# ++eoi [0 | 1]
# ++eos [0 | 2 | 3 | 4]
# ++eot_enable [0 | 1]
# ++eot_char [<char>]
# ++help (unsupported)
# ++ifc
# ++llo [all]
# ++loc [all]
# ++lon (unsupported)
# ++mode [0 | 1]
# ++read [eoi | <char>]
# ++read_tmo_ms <time>
# ++rst
# ++savecfg
# ++spoll [<PAD> | all | <PAD1> <PAD2> <PAD3> ...]
# ++srq
# ++status [<byte>]
# ++trg [PAD1 ... PAD15]
# ++ver [real]
#
# Custom AR488 commands:
# ++allspoll
# ++dl
# ++default
# ++macro [1-9]
# ++ppoll
# ++setvstr [string]
# ++srqauto [0 | 1]
# ++repeat count delay cmdstring
# ++tmbus [value]
# ++verbose
class AR488(object):
"""Class to represent AR488 USB-GPIB adapter.
The AR488 is an Arduino-based USB-GPIB adapter.
For details see: https://github.com/Twilight-Logic/AR488
"""
def __init__(self, port="/dev/ttyUSB0", baudrate=115200, timeout=1):
try:
self.ser = serial.Serial(port=port, baudrate=baudrate, timeout=timeout)
except:
sys.exit("error opening serial port {}".format(port))
def __del__(self):
self.ser.close()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_tb):
self.ser.close()
# Raw GPIB read/write commands
def write(self, message):
"""Write message to GPIB bus."""
self.ser.write("{}\r".format(message).encode("ASCII"))
def read(self):
"""Read from GPIB bus."""
return self.ser.readline().decode("UTF-8")
def query(self, message):
"Write message to GPIB bus and read results."""
self.write(message)
return self.read()
# Prologix commands
def set_address(self, address):
"""Specify address of GPIB device with which to communicate.
When the AR488 is in device mode rather than controller mode, this
instead sets the address of the AR488.
"""
self.write("++addr {}".format(address))
def get_current_address(self):
"Return the currently specified address."""
return self.query("++addr")
if __name__ == "__main__":
# Hello World!
import time
with AR488(timeout=4) as gpib:
print("port name: {}".format(gpib.ser.name))
print("baudrate: {}".format(gpib.ser.baudrate))
print("timeout: {}".format(gpib.ser.timeout))
print("reading version from AR488:")
print(">> " + gpib.query("++ver"))
print("current GPIB address:")
print(">> " + gpib.get_current_address())
print("setting address to 1 for 34401A")
gpib.set_address(1)
print("new GPIB address:")
print(">> " + gpib.get_current_address())
print("assert IFC to make AR488 the controller-in-charge")
# this doesn't seem necessary, at least with only one controller
gpib.write("++ifc")
print("turn on auto 2 mode (auto-read after query)")
gpib.write("++auto 2")
print("verify auto mode: ")
print(">> " + gpib.query("++auto"))
print("get IDN message")
print(">> " + gpib.query("*IDN?"))
print("check SCPI version")
print(">> " + gpib.query("SYST:VERS?"))
print("turn off display")
gpib.write("DISP OFF")
time.sleep(1)
gpib.write("DISP ON")
print("display \"hello world.\" for 3 seconds")
gpib.write("DISPLAY:TEXT \"hello world.\"")
time.sleep(3)
print("reset instrument")
gpib.write("*rst")
print("restore local (front panel) control")
gpib.write("++loc")