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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
|
.. _faq-migrating:
Migrating from PyVISA < 1.5
===========================
.. note:: if you want PyVISA 1.4 compatibility use PyVISA 1.5 that provides
Python 3 support, better visa library detection heuristics,
Windows, Linux and OS X support, and no singleton object.
PyVISA 1.6+ introduces a few compatibility breaks.
Some of these decisions were inspired by the ``visalib`` package as a part of Lantz_
Short summary
-------------
PyVISA 1.5 has full compatibility with previous versions of PyVISA using the
legacy module (changing some of the underlying implementation). But you are
encouraged to do a few things differently if you want to keep up with the
latest developments and be compatible with PyVISA > 1.5.
Indeed PyVISA 1.6 breaks compatibility to bring across a few good things.
**If you are doing:**
>>> import pyvisa
>>> keithley = pyvisa.instrument("GPIB::12")
>>> print(keithley.ask("*IDN?"))
change it to:
>>> import pyvisa
>>> rm = pyvisa.ResourceManager()
>>> keithley = rm.open_resource("GPIB::12")
>>> print(keithley.query("*IDN?"))
**If you are doing:**
>>> print(pyvisa.get_instruments_list())
change it to:
>>> print(rm.list_resources())
**If you are doing:**
>>> import pyvisa.vpp43 as vpp43
>>> vpp43.visa_library.load_library("/path/to/my/libvisa.so.7")
change it to:
>>> import pyvisa
>>> rm = pyvisa.ResourceManager("/path/to/my/libvisa.so.7")
>>> lib = rm.visalib
**If you are doing::**
>>> vpp43.lock(session)
change it to::
>>> lib.lock(session)
or better:
>>> resource.lock()
**If you are doing::**
>>> inst.term_chars = '\r'
change it to::
>>> inst.read_termination = '\r'
>>> inst.write_termination = '\r'
**If you are doing::**
>>> print(lib.status)
change it to::
>>> print(lib.last_status)
or even better, do it per resource::
>>> print(rm.last_status) # for the resource manager
>>> print(inst.last_status) # for a specific instrument
**If you are doing::**
>>> inst.timeout = 1 # Seconds
change it to::
>>> inst.timeout = 1000 # Milliseconds
As you see, most of the code shown above is making a few things explict.
It adds 1 line of code (instantiating the ResourceManager object)
which is not a big deal but it makes things cleaner.
If you were using ``printf``, ``queryf``, ``scanf``, ``sprintf`` or ``sscanf`` of ``vpp43``,
rewrite as pure Python code (see below).
If you were using ``Instrument.delay``, change your code or use ``Instrument.query_delay``
(see below).
A few alias has been created to ease the transition:
- ask -> query
- ask_delay -> query_delay
- get_instrument -> open_resource
A more detailed description
---------------------------
Dropped support for string related functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The VISA library includes functions to search and manipulate strings such as ``printf``,
``queryf``, ``scanf``, ``sprintf`` and ``sscanf``. This makes sense as VISA involves a lot of
string handling operations. The original PyVISA implementation wrapped these functions.
But these operations are easily expressed in pure python and therefore were rarely used.
PyVISA 1.5 keeps these functions for backwards compatibility but they are removed in 1.6.
We suggest that you replace such functions by a pure Python version.
Isolated low-level wrapping module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the original PyVISA implementation, the low level implementation (``vpp43``) was
mixed with higher level constructs. The VISA library was wrapped using ctypes.
In 1.5, we refactored it as ``ctwrapper``. This allows us to test the
foreign function calls by isolating them from higher level abstractions.
More importantly, it also allows us to build new low level modules that
can be used as drop in replacements for ``ctwrapper`` in high level modules.
In 1.6, we made the ``ResourceManager`` the object exposed to the user. The type of the
``VisaLibrary`` can selected depending of the ``library_path`` and obtained from a plugin
package.
We have two of such packages planned:
- a Mock module that allows you to test a PyVISA program even if you do not have
VISA installed.
- a CFFI based wrapper. CFFI is new python package that allows easier and more
robust wrapping of foreign libraries. It might be part of Python in the future.
PyVISA 1.5 keeps ``vpp43`` in the legacy subpackage (reimplemented on top of ``ctwrapper``)
to help with the migration. This module is gone in 1.6.
All functions that were present in ``vpp43`` are now present in ``ctwrapper`` but they
take an additional first parameter: the foreign library wrapper.
We suggest that you replace ``vpp43`` by accessing the ``VisaLibrary`` object under the attribute
visalib of the resource manager which provides all foreign functions as bound methods (see below).
No singleton objects
~~~~~~~~~~~~~~~~~~~~
The original PyVISA implementation relied on a singleton, global objects for the
library wrapper (named ``visa_library``, an instance of the old ``pyvisa.vpp43.VisaLibrary``)
and the resource manager (named ``resource_manager``, and instance of the old
``pyvisa.visa.ResourceManager``). These were instantiated on import and the user
could rebind to a different library using the ``load_library`` method. Calling this
method however did not affect ``resource_manager`` and might lead to an inconsistent
state.
There were additionally a few global structures such a ``status`` which stored the last
status returned by the library and the warning context to prevent unwanted warnings.
In 1.5, there is a new ``VisaLibrary`` class and a new ``ResourceManager`` class (they are
both in ``pyvisa.highlevel``). The new classes are not singletons, at least not in the
strict sense. Multiple instances of ``VisaLibrary`` and ``ResourceManager`` are possible,
but only if they refer to different foreign libraries. In code, this means:
>>> lib1 = pyvisa.VisaLibrary("/path/to/my/libvisa.so.7")
>>> lib2 = pyvisa.VisaLibrary("/path/to/my/libvisa.so.7")
>>> lib3 = pyvisa.VisaLibrary("/path/to/my/libvisa.so.8")
>>> lib1 is lib2
True
>>> lib1 is lib3
False
Most of the time, you will not need access to a ``VisaLibrary`` object but to a ``ResourceManager``.
You can do:
>>> lib = pyvisa.VisaLibrary("/path/to/my/libvisa.so.7")
>>> rm = lib.resource_manager
or equivalently:
>>> rm = pyvisa.ResourceManager("/path/to/my/libvisa.so.7")
.. note:: If the path for the library is not given, the path is obtained from
the user settings file (if exists) or guessed from the OS.
In 1.6, the state returned by the library is stored per resource. Additionally,
warnings can be silenced by resource as well. You can access with the ``last_status``
property.
All together, these changes makes PyVISA thread safe.
VisaLibrary methods as way to call Visa functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the original PyVISA implementation, the ``VisaLibrary`` class was just having
a reference to the ctypes library and a few functions.
In 1.5, we introduced a new ``VisaLibrary`` class (``pyvisa.highlevel``) which has
every single low level function defined in ``ctwrapper`` as bound methods. In code,
this means that you can do::
>>> import pyvisa
>>> rm = pyvisa.ResourceManager("/path/to/my/libvisa.so.7")
>>> lib = rm.visalib
>>> print(lib.read_stb(session))
(But it is very likely that you do not have to do it as the resource should have the
function you need)
It also has every single VISA foreign function in the underlying library as static
method. In code, this means that you can do::
>>> status = ctypes.c_ushort()
>>> ret lib.viReadSTB(session, ctypes.byref(status))
>>> print(ret.value)
Ask vs. query
~~~~~~~~~~~~~
Historically, the method ``ask`` has been used in PyVISA to do a ``write`` followed
by a ``read``. But in many other programs this operation is called ``query``. Thereby
we have decided to switch the name, keeping an alias to help with the transition.
However, ``ask_for_values`` has not been aliased to ``query_values`` because the API
is different. ``ask_for_values`` still uses the old formatting API which is limited
and broken. We suggest that you migrate everything to ``query_values``
Seconds to milliseconds
~~~~~~~~~~~~~~~~~~~~~~~
The timeout is now in milliseconds (not in seconds as it was before). The reason
behind this change is to make it coherent with all other VISA implementations out
there. The C-API, LabVIEW, .NET: all use milliseconds. Using the same units not
only makes it easy to migrate to PyVISA but also allows to profit from all other
VISA docs out there without extra cognitive effort.
Removal of Instrument.delay and added Instrument.query_delay
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the original PyVISA implementation, ``Instrument`` takes a ``delay``
argument that adds a pause after each write operation (This also can
be changed using the ``delay`` attribute).
In PyVISA 1.6, ``delay`` is removed. Delays after write operations must
be added to the application code. Instead, a new attribute and argument
``query_delay`` is available. This allows you to pause between ``write` and ``read``
operations inside ``query``. Additionally, ``query`` takes an optional argument
called ``query`` allowing you to change it for each method call.
Deprecated term_chars and automatic removal of CR + LF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the original PyVISA implementation, ``Instrument`` takes a ``term_chars``
argument to change at the read and write termination characters. If this
argument is ``None``, ``CR + LF`` is appended to each outgoing message and
not expected for incoming messages (although removed if present).
In PyVISA 1.6, ``term_chars`` is replaced by ``read_termination` and
``write_termination``. In this way, you can set independently the termination
for each operation. Automatic removal of ``CR + LF`` is also gone in 1.6.
.. _Lantz: https://lantz.readthedocs.org/
|