PyVISA-py Backend
How to use PyVISA-py as a pure-Python VISA backend with no vendor drivers. Setup, limitations, and when to use it.
PyVISA-py is a pure-Python VISA backend. It replaces NI-VISA so you can talk to instruments without installing vendor drivers. Useful on Linux servers, Docker containers, and CI environments where installing NI-VISA is impractical.
Install
pip install pyvisa pyvisa-pyFor USB instrument support, you also need a libusb binding:
pip install pyusbUse PyVISA-py as Backend
Pass "@py" when creating the ResourceManager.
import pyvisa
rm = pyvisa.ResourceManager("@py")
print(rm.list_resources())
inst = rm.open_resource("TCPIP0::192.168.1.50::inst0::INSTR")
print(inst.query("*IDN?"))
inst.close()
rm.close()Log measurements automatically
TofuPilot records test results from your PyVISA scripts regardless of which backend you use. Free to start.
If you omit the "@py" argument, PyVISA defaults to NI-VISA. If NI-VISA isn't installed, it falls back to PyVISA-py automatically (with a warning).
Interface Support
| Interface | Status | Dependency | Notes |
|---|---|---|---|
| TCP/IP (VXI-11) | Works | None | Most common for LAN instruments |
| TCP/IP (HiSLIP) | Works | None | Faster than VXI-11, preferred for modern instruments |
| TCP/IP (raw socket) | Works | None | TCPIP0::host::port::SOCKET |
| Serial (RS-232) | Works | pyserial | ASRL/dev/ttyUSB0::INSTR |
| USB (USBTMC) | Works | pyusb + libusb | Requires system-level libusb |
| GPIB | Not supported | N/A | Use NI-VISA or linux-gpib |
| PXI | Not supported | N/A | Use NI-VISA |
| VXI | Not supported | N/A | Use NI-VISA |
Install libusb for USB Support
USB instruments need libusb installed at the OS level, not just the Python package.
macOS:
brew install libusbUbuntu / Debian:
sudo apt install libusb-1.0-0-devWindows:
Download from libusb.info or use Zadig to replace the instrument's driver with WinUSB/libusb.
USB permissions on Linux
By default, USB devices need root access. Add a udev rule to allow your user to access the instrument:
echo 'SUBSYSTEM=="usb", MODE="0666"' | sudo tee /etc/udev/rules.d/99-usbtmc.rules
then sudo udevadm control --reload-rules.
PyVISA-py vs NI-VISA
| Criteria | PyVISA-py | NI-VISA |
|---|---|---|
| Install | pip install pyvisa-py | Download from ni.com, run installer |
| Platforms | Any (pure Python) | Windows, Linux, macOS (x86 only) |
| GPIB | Not supported | Full support |
| USB | Requires libusb setup | Works out of the box |
| TCP/IP | Full support | Full support |
| Serial | Full support | Full support |
| Performance | Good for most use cases | Slightly faster for bulk transfers |
| Docker / CI | Easy, no system deps (unless USB) | Hard to install in containers |
| ARM (Raspberry Pi) | Works | Not available |
Use PyVISA-py when: you only need TCP/IP or serial, you're on ARM or in a container, or you can't install NI-VISA.
Use NI-VISA when: you need GPIB, you want USB without libusb hassle, or you need maximum transfer speed.
Verify Your Backend
Check which backend PyVISA is actually using:
import pyvisa
rm = pyvisa.ResourceManager("@py")
print(f"Backend: {rm.visalib}")
print(f"Resources found: {rm.list_resources()}")
rm.close()Expected output:
Backend: /path/to/pyvisa_py/highlevel.py
Resources found: ('TCPIP0::192.168.1.50::inst0::INSTR',)Simulation Backend
PyVISA includes a @sim backend for testing without hardware. Define instrument responses in a YAML file.
spec: "1.0"
devices:
device 1:
dialogues:
- q: "*IDN?"
r: "Simulated,Instrument,SN001,1.0"
resources:
TCPIP0::192.168.1.50::inst0::INSTR:
device: device 1import pyvisa
rm = pyvisa.ResourceManager("simulated.yaml@sim")
inst = rm.open_resource("TCPIP0::192.168.1.50::inst0::INSTR")
print(inst.query("*IDN?"))
inst.close()
rm.close()This is handy for unit tests and CI pipelines where no instruments are connected.
Troubleshooting
| Problem | Fix |
|---|---|
No module named 'pyvisa_py' | pip install pyvisa-py (note the hyphen) |
| USB device not found | Install libusb and pyusb, check permissions |
Could not locate a VISA implementation | Pass "@py" explicitly to ResourceManager() |
| Serial port permission denied | Add user to dialout group: sudo usermod -aG dialout $USER |
| HiSLIP connection refused | Check instrument has HiSLIP enabled (not just VXI-11) |