Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions gpib_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
# connections work, and should be improved.

from labrad.server import LabradServer, setting
from labrad import util
from twisted.internet.defer import inlineCallbacks
from twisted.internet import defer
from twisted.internet.reactor import callLater
from labrad.errors import DeviceNotSelectedError
import labrad.units as units
Expand Down Expand Up @@ -107,15 +109,10 @@ def refreshDevices(self):
deletions = set(self.devices.keys()) - set(addresses)
for addr in additions:
try:
if addr.startswith('GPIB'):
instName = addr
elif addr.startswith('TCPIP'):
instName = addr
elif addr.startswith('USB'):
instName = addr + '::INSTR'
else:
device_prefixes = ('GPIB', 'USB', 'TCPIP')
if not (addr.startswith(device_prefixes)):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't know you could pass a tuple to startswith. nice.

continue
instr = rm.get_instrument(instName)
instr = rm.get_instrument(addr)
instr.write_termination = ''
instr.clear()
if addr.endswith('SOCKET'):
Expand Down Expand Up @@ -176,10 +173,27 @@ def read(self, c, n_bytes=None):
Otherwise, reads until the device stops sending.
"""
instr = self.getDevice(c)
if n_bytes is None:
ans = instr.read_raw()
if instr.resource_name.startswith('USB'):
try:
if n_bytes is None:
ans = instr.read()
else:
ans = instr.read(n_bytes)
except Exception, e:
util.wakeupCall(.3)
if n_bytes is None:
ans = instr.read()
else:
ans = instr.read(n_bytes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not have this delay/retry logic here in the gpib server, since it seems like a device-specific requirement. Ideally, this would go in the device server for the devices that need it. One thing we might want to do is add a setting on the gpib server that just does a delay, so that then the device server could send a single packet that includes the required delays, e.g.:

p = cxn.gpib_bus.packet()
p.write(msg).delay(0.1).read()
result = yield p.send()
result.read

You could also do multiple writes with interleaved delays, etc, but all in one packet to the gpib bus server.

Similarly, we could add a delay parameter to the query setting, which would add a delay between the read and write in the same way.

# Handles a special use case for a device (Rigol DG1022) that
# returns an address with ,, instead of ,.
if ",," in ans:
ans = ans.replace(",,", ",") # rigol specific stupidity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's going on here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a clarifying comment in https://github.com/CampbellGroup/servers/commit/66b48359c2ac336a5ea292f17bec261f374338cc.

With this device connected we get the following with pyvisa 1.7.

>>> import visa
>>> rm = visa.ResourceManager()
>>> rigol = rm.get_instrument('USB0::0x09C4::0x0400::DG1D150900538::INSTR')
>>> rigol.write('*IDN?')
>>> rigol.read()
u'RIGOL TECHNOLOGIES,DG1022 ,DG1D150900538,,00.03.00.09.00.02.11\n'

The double commas, before 00.03 are the use case we are taking care of.

else:
ans = instr.read_raw(n_bytes)
if n_bytes is None:
ans = instr.read_raw()
else:
ans = instr.read_raw(n_bytes)
return str(ans).strip()

@setting(5, data='s', returns='s')
Expand Down