Giter VIP home page Giter VIP logo

python-vxi11's Introduction

Python IVI Readme

For more information and updates: http://alexforencich.com/wiki/en/python-ivi/start

GitHub repository: https://github.com/python-ivi/python-ivi

Google group: https://groups.google.com/d/forum/python-ivi

Introduction

Python IVI is a Python-based interpretation of the Interchangeable Virtual Instrument standard from the IVI foundation.

Included drivers

  • Oscilloscopes (scope):
    • Agilent InfiniiVision 2000A X-series
    • Agilent InfiniiVision 3000A X-series
    • Agilent InfiniiVision 4000A X-series
    • Agilent InfiniiVision 6000A series
    • Agilent InfiniiVision 7000A/B series
    • Agilent Infiniium 90000A/90000X series
    • LeCroy WaveRunner Xi-A series
    • Tektronix MDO3000 series
    • Tektronix DPO4000 series
    • Tektronix MDO4000 series
    • Tektronix MSO4000 series
  • Digital Multimeters (dmm):
    • Agilent 34401A
    • Agilent 34410A
  • Function Generators (fgen):
    • Agilent InfiniiVision 2000A X-series (Wavegen option)
    • Agilent InfiniiVision 3000A X-series (Wavegen option)
    • Agilent InfiniiVision 4000A X-series (Wavegen option)
    • Tektronix MDO3000 series (AFG option)
    • Tektronix AWG2000 series
  • DC Power Supplies (dcpwr):
    • Agilent E3600A series
    • Agilent 603xA series
    • Chroma 62000P series
    • Rigol DP800 series
    • Rigol DP1000 series
    • Tektronix PS2520G/PS2521G
  • RF Power Meters (pwrmeter):
    • Agilent 436A
    • Agilent 437B
    • Agilent U2000 series
  • Spectrum Analyzers (specan):
    • Agilent 859xA/B series
    • Agilent 859xE/EM/C/L series
  • RF Signal Generators (rfsiggen):
    • Agilent 8340/1 A/B
    • Agilent 8642 A/B
    • Agilent ESG E4400B series
  • Other
    • Agilent 8156A optical attenuator
    • Agilent 85644/5A tracking source
    • Agilent 86140B series optical spectrum analyzer
    • Colby Instruments PDL10A Programmable Delay Line
    • DiCon Fiberoptics GP700 Programmable Fiberoptic Instrument
    • JDS Uniphase TB9 Series Optical Grating Filter
    • Tektronix AM5030 programmable current probe amplifier
    • Tektronix OA5000 series optical attenuator

Instrument communication

Python IVI can use Python VXI-11, Python USBTMC, PyVISA, pySerial and linux-gpib to connect to instruments. The implementation of the initialize method takes a VISA resource string and attempts to connect to an instrument. If the resource string starts with TCPIP, then Python IVI will attempt to use Python VXI-11. If it starts with USB, it attempts to use Python USBTMC. If it starts with GPIB, it will attempt to use linux-gpib's python interface. If it starts with ASRL, it attemps to use pySerial. Python IVI will fall back on PyVISA if it is detected. It is also possible to configure IVI to prefer PyVISA over the other supported interfaces.

A note on standards compliance

As the IVI standard only specifies the API for C, COM, and .NET, a Python implementation is inherently not compliant and hence this is not an implementation of the standard, but an interpretation that tries to remain as faithful as possibe while presenting a uniform, easy-to-use, sensible, python-style interface.

The Python IVI library is a Pythonized version of the .NET and COM IVI API specifications, with the CamelCase for everything but the class names replaced with lowercase_with_underscores. The library most closely follows the .NET standard, with the calls that would require the .NET helper classes follwing the corresponding COM specifications. There are some major deviations from the specification in order to be consistent with the spirit of the other IVI specifications. The fgen class is the most obvious example of this, using properties instead of the getters and setters as required by the IVI specification.

Requirements

  • Python 2 or Python 3
  • NumPy
  • One or more communication extensions

Installation

Extract and run

# python setup.py install

Instrument Communication Extensions

Python IVI does not contain any IO drivers itself. In order to communicate with an instrument, you must install one or more of the following drivers:

Python VXI11

Python VXI11 provides a pure python TCP/IP driver for LAN based instruments that support the VXI11 protocol. This includes most LXI instruments and also devices like the Agilent E2050 GPIB to LAN converter.

Home page: http://www.alexforencich.com/wiki/en/python-vxi11/start

GitHub repository: https://github.com/python-ivi/python-vxi11

Python USBTMC

Python USBTMC provides a pure python USBTMC driver for instruments that support the USB Test and Measurement Class. Python USBTMC uses PyUSB to connect to the instrument in a platform-independent manner.

Home page: http://alexforencich.com/wiki/en/python-usbtmc/start

GitHub repository: https://github.com/python-ivi/python-usbtmc

PyVISA

A Python package for support of the Virtual Instrument Software Architecture (VISA), in order to control measurement devices and test equipment via GPIB, RS232, or USB.

Home page: http://pyvisa.readthedocs.org/

Python IVI will use PyVISA as a fallback for all connections, if it is detected. If a connection with PyVISA is preferred, then there are two ways of changing this. First, the prefer_pyvisa option can be set when initalizing an instrument:

mso = ivi.agilent.agilentMSO7104A("TCPIP0::192.168.1.104::INSTR", prefer_pyvisa = True)

or equivalently:

mso = ivi.agilent.agilentMSO7104A()
mso.initialize("TCPIP0::192.168.1.104::INSTR", prefer_pyvisa = True)

Second, the prefer_pyvisa option can be set globally:

ivi.set_prefer_pyvisa(True)
mso = ivi.agilent.agilentMSO7104A("TCPIP0::192.168.1.104::INSTR")

Linux GPIB

Python IVI provides an interface wrapper for the Linux GPIB driver. If the Linux GPIB driver and its included Python interface available, Python IVI can use it to communicate with instruments via any GPIB interface supported by Linux GPIB.

Home page: http://linux-gpib.sourceforge.net/

pySerial

Python IVI provides an interface wrapper for the pySerial library. If pySerial is installed, Python IVI can use it to communicate with instruments via the serial port.

Home page: http://pyserial.sourceforge.net/

Built-in Help

Python IVI has a built-in help feature. This can be used in three ways:

Call the help method with no parameters:

import ivi
instr = ivi.Driver()
instr.help()

This will print a list of all of the available methods and properties, like this:

close
initialized
initialize
identity.get_supported_instrument_models
identity.get_group_capabilities
identity.specification_major_version
...

The higher level groups can also be passed to the help method:

import ivi
instr = ivi.Driver()
instr.help(instr.identity)

This will output everything inside of the sub group:

get_supported_instrument_models
get_group_capabilities
specification_major_version
...

Finally, individual methods and properties can be passed as strings:

import ivi
instr = ivi.Driver()
instr.help("identity.supported_instrument_models")

This will result in the complete documentation:

Returns a comma-separated list of names of instrument models with which
the IVI specific driver is compatible. The string has no white space
...

Usage examples

This sample Python code will use Python IVI to connect to an oscilloscope (either an Agilent MSO7104A or a Tektronix MDO4104) over LXI (VXI-11) or USBTMC, configure the timebase, trigger, and channel 1, capture a waveform, and read it out of the instrument.

# import Python IVI
import ivi
# connect to scope
scope = ivi.agilent.agilentMSO7104A("TCPIP0::192.168.1.104::INSTR")
#scope = ivi.tektronix.tektronixMDO4104("TCPIP0::192.168.1.108::INSTR")
#scope = ivi.agilent.agilentMSO7104A("USB0::2391::5973::MY********::INSTR")
#scope = ivi.tektronix.tektronixMDO4104("USB0::1689::1036::C******::INSTR")
# configure timebase
scope.acquisition.time_per_record = 1e-3
# configure triggering
scope.trigger.type = 'edge'
scope.trigger.source = scope.channels[0]
scope.trigger.coupling = 'dc'
scope.trigger.edge.slope = 'positive'
scope.trigger.level = 0
# configure channels
for ch in scope.channels[0:1]:
    ch.enabled = True
    ch.offset = 0
    ch.range = 4
    ch.coupling = 'dc'
# initiate measurement
scope.measurement.initiate()
# read out channel 1 waveform data
waveform = scope.channels[0].measurement.fetch_waveform()
# measure peak-to-peak voltage
vpp = scope.channels[0].measurement.fetch_waveform_measurement("voltage_peak_to_peak")
# measure phase
phase = scope.channels[0].measurement.fetch_waveform_measurement("phase", scope.channels[1])
# save screenshot to file
png = scope.display.fetch_screenshot()
with open('screenshot.png', 'wb') as f:
    f.write(png)
# save setup to file
setup = scope.system.fetch_setup()
with open('setup.dat', 'wb') as f:
    f.write(setup)
# restore setup from file
with open('setup.dat', 'rb') as f:
    setup = f.read()
scope.system.load_setup(setup)

This sample Python code will use Python IVI to connect to a Tektronix AWG2021, generate a sinewave with numpy, and transfer it to channel 1.

# import Python IVI
import ivi
# import numpy
from numpy import *
# connect to AWG2021 via GPIB
#awg = ivi.tektronix.tektronixAWG2021("GPIB0::25::INSTR")
# connect to AWG2021 via E2050A GPIB to VXI11 bridge
awg = ivi.tektronix.tektronixAWG2021("TCPIP0::192.168.1.105::gpib,25::INSTR")
# connect to AWG2021 via serial
#awg = ivi.tektronix.tektronixAWG2021("ASRL::/dev/ttyUSB0,9600::INSTR")
# create a waveform
n = 128
f = 1
a = 1
wfm = a*sin(2*pi/n*f*arange(0,n))
# transfer to AWG2021
awg.outputs[0].arbitrary.create_waveform(wfm)
# 2 volts peak to peak
awg.outputs[0].arbitrary.gain = 2.0
# zero offset
awg.outputs[0].arbitrary.offset = 0.0
# sample rate 128 MHz
arb.arbitrary.sample_rate = 128e6
# enable ouput
awg.outputs[0].enabled = True

This sample Python code will use Python IVI to connect to an Agilent E3649A and configure an output.

# import Python IVI
import ivi
# connect to E3649A via GPIB
#psu = ivi.agilent.agilentE3649A("GPIB0::5::INSTR")
# connect to E3649A via E2050A GPIB to VXI11 bridge
psu = ivi.agilent.agilentE3649A("TCPIP0::192.168.1.105::gpib,5::INSTR")
# connect to E3649A via serial
#psu = ivi.agilent.agilentE3649A("ASRL::/dev/ttyUSB0,9600::INSTR")
# configure output
psu.outputs[0].configure_range('voltage', 12)
psu.outputs[0].voltage_level = 12.0
psu.outputs[0].current_limit = 1.0
psu.outputs[0].ovp_limit = 14.0
psu.outputs[0].ovp_enabled = True
psu.outputs[0].enabled = True

It is also possible to control multiple instruments. This example configures an Agilent ESG E4433B vector signal generator to output an IQ modulated multitone waveform which is then received on an Agilent 8593E spectrum analyzer.

# import Python IVI
import ivi
# import numpy
import numpy as np
# connect to E4433B via E2050A
esg = ivi.agilent.agilentE4433B("TCPIP::192.168.1.110::gpib,19::INSTR")
# connect to 8593E via E2050A
sa = ivi.agilent.agilent8593E("TCPIP::192.168.1.110::gpib,18::INSTR")
# create multitone IQ waveform
n = 2000
f1 = 1
a1 = 0.5
f2 = 3
a2 = 0.5
t = np.arange(0,n)
yi = a1*np.sin(2*np.pi/n*f1*t)+a2*np.sin(2*np.pi/n*f2*t)
yq = np.zeros(n)
# configure ESG
esg.rf.frequency = 4e9
esg.rf.level = -10
esg.digital_modulation.arb.write_waveform('wfm', yi, yq)
esg.digital_modulation.arb.selected_waveform = 'wfm'
esg.digital_modulation.arb.clock_frequency = 10e6
esg.iq.source = 'arb_generator'
esg.iq.enabled = True
esg.rf.output_enabled = True
# configure SA
sa.frequency.configure_center_span(4e9, 100e3)

python-vxi11's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-vxi11's Issues

Write/Ask commands need newline added to end

Fantastic library!
Following the provided examples I was unable to get any response from my machine, however adding a \n to the end of each command put things in gear. I'm running Linux (Debian 7) and wondered if it was a platform thing? In vxi11.py I inserted the following line:

message += '\n'

after line 396 and now everything runs as intended.

Rigol LXI - via NAT

Hello,

I have my Rigol instrument connected to router in local network with forwarding port 5555 to external address (f.eg. 8000).
Can I use contructior of vxi11.Instrument class with host:port?

vxi11.Instrument("192.168.1.104:8000")

Becase I have 5 Rigols I need to forward each of them to separate port (8000, 8001,...)

TCP Retransmissions happens in Linux connecting to older VXI-11 devices

I don't think it is really an issue, but I think it will make the application better than before.
I was working with an old device (I think it was created around nineties) that has an VXI-11 TCP server on it. I was trying to communicate with this device using both a Linux(Ubuntu 14,04) and a Windows machine. In the Windows machine, the communication was successful but on the Linux side it was not. In the Linux client, there was a lot of re-transmission and the calls started to become even more delayed because the way Linux deal with TCP protocol. I figured out it using Wireshark and analyzing the packets. After a while breaking my head on it, I figured out a solution.
In Linux we have a TCP feature called TCP_QUICKACK that is used to send out acknowledgements as early as possible than delayed under some protocol level exchanging, and it's not stable/permanent, subsequent TCP transactions. This feature was causing a lot of double ACK in the TCP communication because the device I was using can not deal with this quick ack packets. What I did to temporally fix the problem was disabling the socket TCP_QUICKACK in the socket properties in my application, but I think it would be more elegant and correct if we could add this option in the python-vxi11 library. I am running out of time so I forked the project and I will make a commit with this new option as soon as I get some time. If you guys have some better ideas than mine, I would be very grateful to listen from you. Thank you a lot.

Following is what I did to make my application work without changing anything on the python-vxi11 library. It is important to say that TCP_QUICKACK is restarted every socket send and recv command, so it has to be changed every time we send a command:

#!/usr/bin/python

import socket
import vxi11

def generateSocketSendAllWithoutTcpQuickAck(oldSocketSendAll, *args, **kwargs):
    def newSocketSendAll(*args, **kwargs):
        args[0].setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 0)
        oldSocketSendAll(*args, **kwargs)
    return newSocketSendAll

socket.socket.sendall = generateSocketSendAllWithoutTcpQuickAck(socket.socket.sendall)

oldDevice = vxi11.Instrument("192.168.170.33")

oldDevice.open()

answer = oldDevice.ask("*IDN?\n\r")

print "Version of Device: " + answer

oldDevice.close()

FINDLSTN via E5810a

How do I issue the command FINDLSTN to the ethernet<->gpib converter (Agilent E5810a) to list all active listeners?

I've read the source code and it isn't apparent how to accomplish this.

An attempt produces this:

import vxi11
i=vxi11.Instrument("*************","gpib0")
i.ask("FINDLSTN")
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 664, in ask
return self.read(num, encoding)
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 652, in read
return self.read_raw(num).decode(encoding).rstrip('\r\n')
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 622, in read_raw
raise Vxi11Exception(error, 'read')
vxi11.vxi11.Vxi11Exception: 17: IO error [read]

or

import vxi11
i=vxi11.Instrument("*************") # No gpib0 (in hopes to enumerate com port as well
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 663, in ask
self.write(message, encoding)
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 648, in write
self.write_raw(str(message).encode(encoding))
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 560, in write_raw
self.open()
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 530, in open
raise Vxi11Exception(error, 'open')
vxi11.vxi11.Vxi11Exception: 3: Device not accessible [open]

Rigol DM3068 workaround Device locked by another link [write]

Hello,

Got a new DM3068 yesterday and have been trying to connect to it without success. After a lot of searching it turns out that it require the lock_timeout to be set to 0 ( http://optics.eee.nottingham.ac.uk/vxi11/ ). Could be a useful example, it would have saved me hours.

import vxi11
instr = vxi11.Instrument("192.168.1.171")
print(instr.ask("*IDN?"))
Traceback (most recent call last):
File "", line 1, in
File "vxi11/vxi11.py", line 495, in ask
File "vxi11/vxi11.py", line 480, in write
File "vxi11/vxi11.py", line 423, in write_raw
vxi11.vxi11.Vxi11Exception: 11: Device locked by another link [write]
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 67, in apport_excepthook
binary = os.path.realpath(os.path.join(os.getcwd(), sys.argv[0]))
OSError: [Errno 2] No such file or directory

Original exception was:
Traceback (most recent call last):
File "", line 1, in
File "vxi11/vxi11.py", line 495, in ask
File "vxi11/vxi11.py", line 480, in write
File "vxi11/vxi11.py", line 423, in write_raw
vxi11.vxi11.Vxi11Exception: 11: Device locked by another link [write]

instr.lock_timeout = 0
print(instr.ask("IDN?"))
Rigol Technologies,DM3068,DM3O
********,01.01.00.01.08.00

ask_for_values

the pyvisa project used to have a function called ask_for_values , which believe has recently been renamed and re-written to query_values. essentially it was an ask, with delimiter splitting and casting, that was ideal for reading arrays.

in either case, this function is very useful, and was wondering if a similar thing could implemented in python-vxi11 or python-ivi (which ever is more appropriate). id be happy to do this

Support list_devices()

I have some proprietary (closed source) super slow C library for working with vxi11 and that one provides a function that returns all vxi11 devices at the network (and that's fast). This is the only function I miss in this python library.

Is there any chance to provide a search function in this library as well?

advice for vxi11-gpib bridge

not to request a product endorsement, but could give some links products that will allow me to control GPIB instruments with python-vxi11?

i have been goggling and i am confused as to what does what. do you have experience with a specifc product, that is still purchasable?

Tx/ Rx annotations

This is not really an issue but could not see anyplace to request a feature as below. So added it here.

So for the the ask function and write function using IDN as an example, would the output be able to show.
Tx> *IDN
Rx< device ID

Currently the command requested is not shown on the output, so if there was a complementary write or ask function that printed what command was sent that would be useful in a log.
Also the TX> and RX < with the <> brackets can be useful to show what was transmitted and what was received.

Obviously this functionality can be achieved, by printing the command and then sending it via ask or write, but if we can have a new combined function it will make a testers role much efficient in just writing single line instead of 2.

bytes/str problem with LeCroy scope

Hi I am trying to use the vxi11 interface to retrieve data from a Lecroy scope, unfortunately I am running into a bytes/string problem


In [2]: vxi11.version.__version__
Out[2]: '0.9'

In [3]: i=vxi11.Instrument("129.20.84.103")

In [4]: i.ask("*IDN?")
Out[4]: '*IDN LECROY,HDO4054A,THZSCOPE,8.5.1'

In [5]: i.ask_raw("C1:WF? DESC")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-b118bed726b3> in <module>()
----> 1 i.ask_raw("C1:WF? DESC")

/home/marco/.local/lib/python3.7/site-packages/vxi11/vxi11.py in ask_raw(self, data, num)
    714     def ask_raw(self, data, num=-1):
    715         "Write then read binary data"
--> 716         self.write_raw(data)
    717         return self.read_raw(num)
    718 

/home/marco/.local/lib/python3.7/site-packages/vxi11/vxi11.py in write_raw(self, data)
    657                 self._lock_timeout_ms,
    658                 flags,
--> 659                 block
    660             )
    661 

/home/marco/.local/lib/python3.7/site-packages/vxi11/vxi11.py in device_write(self, link, timeout, lock_timeout, flags, data)
    409         return self.make_call(DEVICE_WRITE, params,
    410                 self.packer.pack_device_write_parms,
--> 411                 self.unpacker.unpack_device_write_resp)
    412 
    413     def device_read(self, link, request_size, timeout, lock_timeout, flags, term_char):

/home/marco/.local/lib/python3.7/site-packages/vxi11/rpc.py in make_call(self, proc, args, pack_func, unpack_func)
    175         self.start_call(proc)
    176         if pack_func:
--> 177             pack_func(args)
    178         self.do_call()
    179         if unpack_func:

/home/marco/.local/lib/python3.7/site-packages/vxi11/vxi11.py in pack_device_write_parms(self, params)
    201         self.pack_uint(lock_timeout)
    202         self.pack_int(flags)
--> 203         self.pack_opaque(data)
    204 
    205     def pack_device_read_parms(self, params):

/usr/lib/python3.7/xdrlib.py in pack_string(self, s)
    106         n = len(s)
    107         self.pack_uint(n)
--> 108         self.pack_fstring(n, s)
    109 
    110     pack_opaque = pack_string

/usr/lib/python3.7/xdrlib.py in pack_fstring(self, n, s)
     98         data = s[:n]
     99         n = ((n+3)//4)*4
--> 100         data = data + (n - len(data)) * b'\0'
    101         self.__buf.write(data)
    102 

TypeError: can only concatenate str (not "bytes") to str

Thanks a lot,
marco

close() hanging if a Ctrl+C presseed ie. KeyboardInterrupt was raised

The Instrument.close() method hanging (or throws a timeout exception) if ctrl+c was pressed during a read operation.
Some instrument commands consume time (eg.: saving/fetching screenshot of the oscilloscope). If I press Ctrl+C during an ask() or read(), the close()method cannot finish properly: it throws timeout error after the timeout time has been elapsed, which timeout must be big in some cases (because of the time consuming commands.)

Problems connecting to GW Instek MFG-2230-M

I think this is an implementation issue at GWI, but wondered if anyone had any ideas or previous experience? I suspect this is all due to me not understanding the difference between VISA, VXI, LXI etc., but I have been working happily with PyMeasure in a way that seems to work OK, until I hit this problem.

I have several instruments that all seem to work quite happily, but not this one (GW Instek MFG-2230-M). I think it will only accept VISA connections, so a connection string something like:

“TCPIP :: 172.16.28.144 :: 1026 :: SOCKET”

.. which is rejected by the vxi11 library as a malformed string, and presumably it would need to parse the socket number as well, rather than performing the vxi protocol (or whatever it is) to establish a socket.

If I try a connection string like: “TCPIP :: 172.16.28.144 :: INSTR”, this is accepted by the vx11 library, but I just get a "connection refused" error when I try to send a message.

Timeout when sending a *IDN? command to a Siglent SDS2000 scope

I'm trying to get python-vxi11 working with all of my test equipment, and most of my instruments work great with it except for my Siglent SDS2000 scope. When sending the *IDN? command the ask command hangs, and then times out. I've included the wireshark file if it helps.

Tracing through the code, it seems to attempt to open a second connection to the instrument, and hangs up there.

This is what gets returned after a while:

File "/home/srodgers/projects/python/PycharmProjects/dp832/instrument.py", line 60, in identify
return self.s.ask("*IDN?")
File "/usr/local/lib/python3.4/dist-packages/python_vxi11-0.8-py3.4.egg/vxi11/vxi11.py", line 717, in ask
File "/usr/local/lib/python3.4/dist-packages/python_vxi11-0.8-py3.4.egg/vxi11/vxi11.py", line 702, in write
File "/usr/local/lib/python3.4/dist-packages/python_vxi11-0.8-py3.4.egg/vxi11/vxi11.py", line 610, in write_raw
File "/usr/local/lib/python3.4/dist-packages/python_vxi11-0.8-py3.4.egg/vxi11/vxi11.py", line 580, in open
File "/usr/local/lib/python3.4/dist-packages/python_vxi11-0.8-py3.4.egg/vxi11/vxi11.py", line 493, in init
File "/usr/local/lib/python3.4/dist-packages/python_vxi11-0.8-py3.4.egg/vxi11/rpc.py", line 522, in init
File "/usr/local/lib/python3.4/dist-packages/python_vxi11-0.8-py3.4.egg/vxi11/rpc.py", line 257, in init
File "/usr/local/lib/python3.4/dist-packages/python_vxi11-0.8-py3.4.egg/vxi11/rpc.py", line 261, in connect
TimeoutError: [Errno 110] Connection timed out

wireshark.zip

Benchmarks?

Hi,

I'm trying to pull waveform data off a R&S RTO 1014 via gigabit ethernet. At the moment, it is receiving data rather slowly (10Mbit), whereas if I connect an agilent scope with USB and usbtmc, I can push close to the limit of 480MBit (I estimate something like 350MBit). Unfortunately this R&S one doesn't have USB, so I am stuck with ethernet.

Are there any benchmarks on what sort of data rate I can expect using python-vxi11? For me right now, 15MB of waveform data takes about 6 seconds on a point-to-point gigabit ethernet connection (no router or switches in between) which is far too slow. I have checked and the interface is definitely running at 1000MBit.

I'm running Ubuntu 15.04 x64 on a Core i3 box, using the intel gigabit adapter on the motherboard.

Hang sending large payloads to Keysight scopes

On Mac OS X, sending data larger than ~128K to a Keysight scope results in a timeout in recvfrag. This is caused by a bug in sendfrag where the code should have used sock.sendall instead of sock.send:

def sendfrag(sock, last, frag):
    x = len(frag)
    if last: x = x | 0x80000000
    header = struct.pack(">I", x)
    sock.sendall(header + frag)

bytes -> bytearrays in read procedures

I had to transmit a lot of 128MB waveforms from my scope to the computer, which was extremely slow. After changing all the "bytes +=" parts in the read procedures to "bytearray.append", I was able to speed the process up by a factor of 10.

So I suggest applying these changes here too.

Interface timeout / hangs on *RST for Rigol DP832

Trying this simple sequence of commands sometimes hangs the LAN interface of the Rigol DP832(A) with firmware version 00.01.14.00.03 and resets the connection:

Python 2.7.6 (default, Nov 23 2017, 15:49:48) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import vxi11
>>> inst = vxi11.Instrument("192.168.1.15")
>>> inst.ask("*IDN?")
u'RIGOL TECHNOLOGIES,DP832,DP8C194205678,00.01.14'
>>> inst.ask("*RST")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/vxi11/vxi11.py", line 743, in ask
    return self.read(num, encoding)
  File "/usr/lib/python2.7/dist-packages/vxi11/vxi11.py", line 731, in read
    return self.read_raw(num).decode(encoding).rstrip('\r\n')
  File "/usr/lib/python2.7/dist-packages/vxi11/vxi11.py", line 701, in read_raw
    raise Vxi11Exception(error, 'read')
vxi11.vxi11.Vxi11Exception: 15: IO timeout [read]
>>>
$ cat /usr/lib/python2.7/dist-packages/vxi11/version.py
__version__ = '0.9'

Sometimes the connection seems to be only half closed so that further commands or a reconnection to the device fails until the DP832 is power-cycled. In this state the web interface does not work as well.

Doing the same directly via telnet 192.168.1.15 5555 does not cause any problems.

Problem with max_recv_size

There seems to be a problem with the max_recv_size value that is returned by the CoreClient.create_link() method. The code that's calling it is in vxi11/vxi11.py.

In particular, the line that I believe is causing the issues is this:
error, link, abort_port, max_recv_size = self.client.create_link(self.client_id, 0, self.lock_timeout, self.name.encode("utf-8"))

The problem is the following:

I'm connecting to an Agilent DSO 9000 series via Ethernet. The max_recv_size returned is 4294967295. However, after trying to read something with this default setting I get an error:

import vxi11
instr = vxi11.Instrument("192.168.1.104")
print(instr.ask("*IDN?"))
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/python_vxi11-0.5-py2.7.egg/vxi11/vxi11.py", line 418, in ask
return self.read(num, encoding)
File "/usr/local/lib/python2.7/dist-packages/python_vxi11-0.5-py2.7.egg/vxi11/vxi11.py", line 413, in read
return self.read_raw(num).decode(encoding).rstrip('\r\n')
File "/usr/local/lib/python2.7/dist-packages/python_vxi11-0.5-py2.7.egg/vxi11/vxi11.py", line 383, in read_raw
raise Vxi11Error("error reading data: %d" % error)
vxi11.vxi11.Vxi11Error: error reading data: 5

By using a manual receive size it works fine:

instr = vxi11.Instrument( ... hidden)
instr.write("*IDN?")
print instr.read(10000)
Agilent Technologies,DSO9054H,MY53060106,04.60.0005

I suspect that the returned max_recv_size is invalid, so I'm not sure how it would be best to fix this. Also I'm unsure if this is a problem of the create_link method or of the Agilent oscilloscope, since with a Lecroy oscilloscope this seems to work fine. Nevertheless it is annoying and it took me a while to realize what was the issue since it was not clear from the error message.

Maybe a fix would be to restrict the max_recv_size to something like 10^8 or 10^9 after the self.client.create_link call.

Specifying term_char is broken

I get this traceback when specifying term_char on python 3.8:

File "/usr/lib/python3.8/site-packages/vxi11/vxi11.py", line 727, in write
self.write_raw(str(message).encode(encoding))
File "/usr/lib/python3.8/site-packages/vxi11/vxi11.py", line 640, in write_raw
data += term_char
TypeError: can't concat int to bytes

It seems this can be fixed by changing line 639 from:
term_char = str(self.term_char).encode('utf-8')[0]
to:
term_char = str(self.term_char).encode('utf-8')[:1]

Vxi11Exception: 15 IOTimeout with Keysight E5810B connected devices only

When my instruments are connected directly to my PC, either by USB or by GPIB-USB converter, I can communicate with them without issue. However, when I connect to them through the Keysight E5810B bridge via GPIB, I get the IO timeout in the subject line.

The IO timeout occurs for roughly 75% of all commands -- at times, the very same commands are successful.

I can see that the E5810B gateway has the LAN and GPIB LEDs flash green during communication, indicating that it is receiving the command. But, alas, the timeout error usually plagues communication.

Is there a particular set of configuration commands that need to be sent for using the gateway?

Steps to debug:

  • increase timeout
  • Preset E5810B gateway and reconfigure
  • secured HW connections
  • verified issue does not occur with direct connection to PC. only connection to gateway

Here are specific details of the setup:

  • Keysight E5810B fresh out of the box, configured with a static IP on a corporate LAN FW B.01.07 (latest)
  • Keysight N7752A Power Meter + VOA connected to the E5810B via GPIB (also used Tektronix TDS744, Agilent 86142 OSA, etc.)
  • Windows 10 host OS
  • using VXI11 version 0.9

Code:

import vxi11
inst = vxi11.Instrument("138.120.217.76", "gpib0,5") 
inst.ask("*IDN?")       # Fails with vxi11Exception
inst.timeout = 10000
inst.ask("*IDN?")      # Fails with vxi11Exception

Invalid resource string

inst = vix11.Instrument("TCPIP:AAA99999-99999::INST0::INSTR")

why isn't this resource string accepted?

I'm trying to interact with a rohde-schwarz machine VXI-11 protocol format for addressing the devices in the machine is as follows:

"""
"TCPIP[board]::host address[::LAN device name][::INSTR]"

The LAN device name for sub-instrument n equals inst. Example: inst0 for sub-instrument 1. VXI-11 is a protocol that has been specifically developed for test and measurement instruments. """

Maybe the parse_visa_resource_string function needs some adjustments.

Regards,
Tyron

Request to support SRQ

I see that python-vxi11 has some code that says "SRQ", but it's not clear to me how to use it.

According to this thread I suspect that the functionality might not yet be properly implemented.

My use case is that our instrument sends an "SRQ" event when the data is ready, then I guess that I need to read the status byte and run a function that reads the data out.

I think that this library supports SRQ, but it does it via some C++.

timeout for connexion

Hello!
I recently upgraded my version of vix11.py 0.8.1 => 0.9 and I no longer find my "instrument_timeout" and "connection_timeout" parameters during initialization:

instr=vxi11.Instrument(LecroyIP) 
instr.__init__(LecroyIP, instrument_timeout=5, connection_timeout=7)
#v0.8.1

I found "instrument_timeout" with:

instr=vxi11.Instrument(LecroyIP) 
instr.timeout=5 (s)

But I struggle a bit to find the "connection_timeout" that I used when my LECROY oscilloscopes are turned off or disconnected from the network.
I think it's not much but I just spent two mornings there lol
Have a nice day and thank you for your answers.
Guillaume

Timout when reading more than max_recv_size bytes

When trying to read raw binary data with more than 16*1024=16384 bytes (this is the value of max_recv_size), I get I/O TIMEOUT Errors.

I have seen in the source code that data is received in packages up to max_recv_size bytes and then joined.

I tried to manually set smaller or larger values for max_recv_size without success.
However, I found out, that in fact there are only a few bytes missing, causing the last client.device_read(...) to produce a timeout.
For example if I set max_recv_size=4096 and try to read 32000 bytes I can receive 7 packages à 4096 bytes (thats 28672 in total) but the last read call raises a timeout exception because it can't read all of the expected missing 3328 bytes (but probably some or even most of them).

It is just an idea, but maybee there are bytes lost in the timewindow between the calls to client.device_read(...) where you append data to the previously read?

Any thoughts on that?

Please implement a configurable timeout

Hello,

I have successfully used the python-vxi11 on a rigol MSO1104z over TCP.
See
https://github.com/x8-999-github/cw-projects-experiments/blob/master/visa/Scope_arm_and_capture.ipynb and

https://github.com/x8-999-github/cw-projects-experiments/blob/master/visa/VXI_MSO1104z.ipynb

The main problem was a timeout I was getting when connecting.
Is it possible to make the socket timeout configurable(I hardcoed it here)?

#diff --git a/vxi11/rpc.py b/vxi11/rpc.py
#index 9d889a6..c744f8c 100644
#--- a/vxi11/rpc.py
#+++ b/vxi11/rpc.py
#@@ -257,6 +257,7 @@ class RawTCPClient(Client):
# 
#     def connect(self):
#         self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#+       self.sock.settimeout(2.0)
#         self.sock.connect((self.host, self.port))
# 
#     def close(self):

New release for PyPI?

Hi Alex
Do you have any plans to make a new release of python-vxi11? The latest version in PyPI is 0.9. Since then there have been various improvements (performance and list_resources). It would be nice if these were available when installing with Pip.

Setting socket Timeout on Instrument Class

Reading through the code, seems as though doing:

instrument_handle = "TCPIP::169.254.14.7::INSTR"
c = vxi11.Instrument(instrument_handle)
c.timeout = MY_TIMEOUT_IN_SECONDS

would work appropriately for setting the socket timeout duration.
Unfortunately, it seems the socket timeout duration is the same regardless of me setting this value.
Any thoughts on this?

ImportError: No module named vxi11

Hell guys,
I tried to install the vxi11 python lbrary in Ubuntu 16.04 using the next command:

sudo python setup.py install

I get the next log:

_running install
running bdist_egg
running egg_info
writing python_vxi11.egg-info/PKG-INFO
writing top-level names to python_vxi11.egg-info/top_level.txt
writing dependency_links to python_vxi11.egg-info/dependency_links.txt
writing entry points to python_vxi11.egg-info/entry_points.txt
reading manifest file 'python_vxi11.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'python_vxi11.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/vxi11
copying build/lib.linux-x86_64-2.7/vxi11/cli.py -> build/bdist.linux-x86_64/egg/vxi11
copying build/lib.linux-x86_64-2.7/vxi11/vxi11.py -> build/bdist.linux-x86_64/egg/vxi11
copying build/lib.linux-x86_64-2.7/vxi11/version.py -> build/bdist.linux-x86_64/egg/vxi11
copying build/lib.linux-x86_64-2.7/vxi11/init.py -> build/bdist.linux-x86_64/egg/vxi11
copying build/lib.linux-x86_64-2.7/vxi11/rpc.py -> build/bdist.linux-x86_64/egg/vxi11
byte-compiling build/bdist.linux-x86_64/egg/vxi11/cli.py to cli.pyc
byte-compiling build/bdist.linux-x86_64/egg/vxi11/vxi11.py to vxi11.pyc
byte-compiling build/bdist.linux-x86_64/egg/vxi11/version.py to version.pyc
byte-compiling build/bdist.linux-x86_64/egg/vxi11/init.py to init.pyc
byte-compiling build/bdist.linux-x86_64/egg/vxi11/rpc.py to rpc.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying python_vxi11.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying python_vxi11.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying python_vxi11.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying python_vxi11.egg-info/entry_points.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying python_vxi11.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating 'dist/python_vxi11-0.9-py2.7.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing python_vxi11-0.9-py2.7.egg
Removing /usr/local/lib/python2.7/dist-packages/python_vxi11-0.9-py2.7.egg
Copying python_vxi11-0.9-py2.7.egg to /usr/local/lib/python2.7/dist-packages
python-vxi11 0.9 is already the active version in easy-install.pth
Installing vxi11-cli script to /usr/local/bin

Installed /usr/local/lib/python2.7/dist-packages/python_vxi11-0.9-py2.7.egg
Processing dependencies for python-vxi11==0.9
Finished processing dependencies for python-vxi11==0.9_

as you can see there is no errors in the installation, when I tried to use in my python script:

import vxi11

get me the next error:

import vxi11
ImportError: No module named vxi11

any idea what I did wrong?

SALUDOS!!!!!

Use waitlock flag in lock()

lock() does not wait the lock timeout before failing. The waitlock flag (bit 0) is not being set. Is there a reason why this flag would never be set? If there is, perhaps add a default wait = False argument?

    def lock(self):
        "Send lock command"
        if self.link is None:
            self.open()

        # flags = 0

        # TODO: Added waitlock flag.
        flags = 1 

        error = self.client.device_lock(self.link,
                                        flags,
                                        self._lock_timeout_ms)

        if error:
            raise Vxi11Exception(error, 'lock')

Keysight E5810B slows down after 10 connections

Each time a new TCP/IP connection is established with the Keysight E5810B, it internally spawns a process that takes 50-100% of a core's CPU power. It's possible that it's internally polling aggressively. When creating multiple Instrument objects, each with its own connection, at about 10 instruments the box slows down significantly as the CPU is at saturation.

An easy workaround would be to share the client connection between all Instruments and the InterfaceDevice.

I'd be happy to put up a PR that accepts an optional client input in the initializer; however, I'm not sure if this is the approach you would prefer. An alternative approach would be a connection pool keyed on the IP address of the host; it could then grab an existing connection rather than create a new one.

Instrument.write_raw() and term_char

I'm using Python 3.5 on Ubuntu.

I modified this routine to show what I think it should be. Before it was flags = OP_FLAG_TERMCHAR_SET if a terminating char exists but was immediately followed by flags = 0.

But I'm also confused by the behavior if term_char is set. It looks like the intent is the convert it to an integer than append to data. I've been passing bytes objects to this routine. This will fail when it attempts data += term_char. Also you cannot specify term_char as a single element bytes literal such as b'\r'.

If the encoding is assumed to be 'UTF-8' anyway shouldn't this line simply be ord(term_char)?

I might also change the if self.term_char is not None to if self.term_char for readability/simplicity.

    def write_raw(self, data):
        "Write binary data to instrument"
        if self.link is None:
            self.open()

        # TODO: Test
        flags = 0

        if self.term_char is not None:
            flags |= OP_FLAG_TERMCHAR_SET
            term_char = str(self.term_char).encode('utf-8')[0]
            data += term_char

        # Was this: flags = 0

        num = len(data)

create_intr_chan error

line 443, you use pack_device_docmd_params, the correct call is be unpack_device_remote_func_parms.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.