CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyvisa-py

Pure Python implementation of a VISA library for instrument communication.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

usb-communication.mddocs/

USB Communication

USB device communication supporting both USBTMC (USB Test & Measurement Class) protocol for test instruments and raw USB device access for specialized hardware. PyVISA-py provides comprehensive USB support through PyUSB with automatic device discovery and proper permission handling.

Capabilities

USBSession Class

Base class for USB device communication providing common functionality for both USBTMC instruments and raw USB devices.

class USBSession:
    """Base class for USB device communication via PyUSB."""
    
    def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
        """
        Initialize USB session (base class).
        
        Args:
            resource_manager_session (VISARMSession): Parent RM session
            resource_name (str): USB resource name
            parsed (rname.ResourceName): Parsed resource name
            open_timeout (int): Connection timeout in milliseconds
        """
    
    def read(self, count):
        """
        Read data from USB device.
        
        Args:
            count (int): Maximum number of bytes to read
            
        Returns:
            Tuple[bytes, StatusCode]: Data read and operation status
        """
    
    def write(self, data):
        """
        Write data to USB device.
        
        Args:
            data (bytes): Data to transmit
            
        Returns:
            Tuple[int, StatusCode]: Number of bytes written and status
        """
    
    def close(self):
        """
        Close USB connection and release device.
        
        Returns:
            StatusCode: Operation result
        """
    
    @staticmethod
    def list_resources():
        """
        List available USB devices (implemented in subclasses).
        
        Returns:
            List[str]: List of USB device resource strings
        """

USBInstrSession Class

Handles USB instrument communication using the USBTMC protocol, which is the standard for USB-connected test and measurement instruments.

class USBInstrSession(USBSession):
    """Session for USB instrument communication via USBTMC."""
    
    def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
        """
        Initialize USB USBTMC instrument session.
        
        Args:
            resource_manager_session (VISARMSession): Parent RM session
            resource_name (str): USB INSTR resource name
            parsed (rname.ResourceName): Parsed resource name
            open_timeout (int): Connection timeout in milliseconds
        """
    
    def clear(self):
        """
        Clear USB instrument (send USBTMC clear command).
        
        Returns:
            StatusCode: Operation result
        """
    
    @staticmethod
    def list_resources():
        """
        List available USB USBTMC instruments.
        
        Returns:
            List[str]: List of USB INSTR resource strings
        """

USBRawSession Class

Provides raw USB device access for specialized communication protocols that don't use USBTMC.

class USBRawSession:
    """Session for raw USB device communication."""
    
    def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
        """
        Initialize raw USB session.
        
        Args:
            resource_manager_session (VISARMSession): Parent RM session
            resource_name (str): Raw USB resource name
            parsed (rname.ResourceName): Parsed resource name
            open_timeout (int): Connection timeout in milliseconds
        """
    
    def read(self, count):
        """
        Read data from USB device via bulk/interrupt transfer.
        
        Args:
            count (int): Maximum number of bytes to read
            
        Returns:
            Tuple[bytes, StatusCode]: Data read and operation status
        """
    
    def write(self, data):
        """
        Write data to USB device via bulk/interrupt transfer.
        
        Args:
            data (bytes): Data to transmit
            
        Returns:
            Tuple[int, StatusCode]: Number of bytes written and status
        """
    
    def close(self):
        """
        Close raw USB connection.
        
        Returns:
            StatusCode: Operation result
        """
    
    @staticmethod
    def list_resources():
        """
        List available raw USB devices.
        
        Returns:
            List[str]: List of raw USB device resource strings
        """

USB Device Management

Control USB device configuration, interfaces, and endpoints for proper communication setup.

# USB configuration methods (internal use)
def _configure_device(device, interface_number):
    """Configure USB device interface for communication."""

def _find_endpoints(interface):
    """Find bulk IN and OUT endpoints for data transfer."""

def _claim_interface(device, interface_number):
    """Claim USB interface for exclusive access."""

def _release_interface(device, interface_number):
    """Release USB interface when done."""

Usage Examples

USB Instrument Communication

import pyvisa

# Use PyVISA-py backend
rm = pyvisa.ResourceManager('@py')

# List USB instruments
usb_resources = rm.list_resources('USB?*::INSTR')
print("USB instruments:", usb_resources)

# Resource string format: USB[board]::vendor_id::product_id::serial::interface::INSTR
# Example: "USB0::0x1234::0x5678::ABC123::0::INSTR"

if usb_resources:
    try:
        # Open USB instrument
        inst = rm.open_resource(usb_resources[0])
        
        # Configure timeout
        inst.timeout = 5000  # 5 seconds
        
        # Standard SCPI communication
        inst.write("*RST")  # Reset instrument
        idn = inst.query("*IDN?")
        print("Instrument ID:", idn.strip())
        
        # Read measurement data
        inst.write("MEAS:VOLT:DC?")
        voltage = float(inst.read())
        print(f"Voltage: {voltage} V")
        
    except pyvisa.VisaIOError as e:
        print(f"USB communication error: {e}")
    finally:
        inst.close()

rm.close()

Raw USB Device Access

# Open raw USB device for custom protocols
raw_resources = rm.list_resources('USB?*::RAW')
print("Raw USB devices:", raw_resources)

if raw_resources:
    try:
        # Open raw USB device
        device = rm.open_resource(raw_resources[0])
        
        # Send custom command
        command = b'\\x01\\x02\\x03\\x04'  # Custom protocol command
        bytes_written = device.write_raw(command)
        print(f"Sent {bytes_written} bytes")
        
        # Read response
        response = device.read_raw(64)  # Read up to 64 bytes
        print(f"Received: {response.hex()}")
        
    except pyvisa.VisaIOError as e:
        print(f"Raw USB error: {e}")
    finally:
        device.close()

USB Device Discovery

# Discover USB devices with specific vendor/product IDs
def find_usb_device(vendor_id, product_id):
    """Find USB device by vendor and product ID."""
    rm = pyvisa.ResourceManager('@py')
    
    # List all USB resources
    all_usb = rm.list_resources('USB?*')
    
    # Filter by vendor/product ID
    target_vid = f"{vendor_id:04X}"
    target_pid = f"{product_id:04X}"
    
    matching_devices = []
    for resource in all_usb:
        if f"::{target_vid}::{target_pid}::" in resource:
            matching_devices.append(resource)
    
    rm.close()
    return matching_devices

# Find Keysight devices (vendor ID 0x2A8D)
keysight_devices = find_usb_device(0x2A8D, 0x0001)  # Example product ID
print("Keysight USB devices:", keysight_devices)

Bulk Data Transfer

# High-speed data transfer for instruments that support it
inst = rm.open_resource("USB0::0x1234::0x5678::ABC123::0::INSTR")

try:
    # Request large data block
    inst.write("DATA:ARRAY?")  # Request array data
    
    # Read large binary data block
    # Some instruments send data length first
    header = inst.read_bytes(4)  # Read length header
    data_length = int.from_bytes(header, byteorder='big')
    
    # Read the actual data
    bulk_data = inst.read_bytes(data_length)
    print(f"Received {len(bulk_data)} bytes of data")
    
    # Process binary data (example: 16-bit integers)
    import struct
    values = struct.unpack(f'>{data_length//2}H', bulk_data)
    print(f"First 10 values: {values[:10]}")
    
except pyvisa.VisaIOError as e:
    print(f"Bulk transfer error: {e}")
finally:
    inst.close()

USB Configuration Management

# Check USB device configuration
inst = rm.open_resource("USB0::0x1234::0x5678::ABC123::0::INSTR")

try:
    # Get USB-specific attributes
    manufacturer = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_MANF_NAME)
    model = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_MODEL_NAME)
    serial = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_SERIAL_NUM)
    
    print(f"Manufacturer: {manufacturer}")
    print(f"Model: {model}")
    print(f"Serial: {serial}")
    
    # Check USB interface information
    interface_num = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_INTFC_NUM)
    alt_setting = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_ALT_SETTING)
    
    print(f"Interface: {interface_num}, Alt Setting: {alt_setting}")
    
except Exception as e:
    print(f"Error reading USB attributes: {e}")
finally:
    inst.close()

Resource String Format

USB resource strings follow the VISA standard format:

USB[board]::vendor_id::product_id::serial_number::interface_number::[INSTR|RAW]

Components:

  • board: USB host controller (usually 0)
  • vendor_id: 4-digit hex vendor ID (e.g., 0x1234)
  • product_id: 4-digit hex product ID (e.g., 0x5678)
  • serial_number: Device serial number string
  • interface_number: USB interface number (usually 0)
  • resource_class: INSTR for USBTMC, RAW for direct access

Examples:

  • USB0::0x2A8D::0x0001::MY12345678::0::INSTR - Keysight USBTMC instrument
  • USB0::0x1234::0x5678::SN123456::0::RAW - Raw USB device
  • USB::0x0957::0x2918::MY50001234::INSTR - Short form (board defaults to 0)

Error Handling

Common USB communication errors and solutions:

from pyvisa import VisaIOError
from pyvisa.constants import StatusCode

try:
    inst = rm.open_resource("USB0::0x1234::0x5678::ABC123::0::INSTR")
except VisaIOError as e:
    if e.error_code == StatusCode.error_resource_not_found:
        print("USB device not found - check connection and drivers")
    elif e.error_code == StatusCode.error_resource_busy:
        print("USB device busy - another application may be using it")
    elif e.error_code == StatusCode.error_insufficient_location_information:
        print("Invalid USB resource string format")
    else:
        print(f"USB open error: {e}")

# Handle communication timeouts
try:
    response = inst.query("*IDN?", timeout=2000)
except VisaIOError as e:
    if e.error_code == StatusCode.error_timeout:
        print("USB communication timeout - device may not respond to SCPI")
    elif e.error_code == StatusCode.error_io:
        print("USB I/O error - check USB connection")

Dependencies

USB communication requires the PyUSB package and appropriate USB backend libraries:

# Install USB support
pip install pyvisa-py[usb]

# Or install PyUSB directly
pip install pyusb

USB Backend Requirements:

  • Windows: Uses WinUSB driver or libusb-win32
  • Linux: Uses libusb-1.0 (usually pre-installed)
  • macOS: Uses libusb (install via Homebrew: brew install libusb)

Device Permissions

Linux

USB devices may require proper permissions or udev rules:

# Add user to dialout group for USB access
sudo usermod -a -G dialout $USER

# Or create udev rule for specific devices
# /etc/udev/rules.d/99-usb-instruments.rules:
# SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", MODE="0666"

Windows

  • Install appropriate USB drivers (often provided by instrument manufacturer)
  • Some devices require libusb or WinUSB drivers instead of vendor drivers
  • Use Zadig tool to install WinUSB drivers for raw USB access

macOS

  • Usually works out of the box with libusb
  • Some instruments may require disabling System Integrity Protection for driver access

USBTMC Protocol Details

The USB Test & Measurement Class provides standardized communication for instruments:

  • Bulk-OUT: Host to device commands and data
  • Bulk-IN: Device to host responses and data
  • Interrupt-IN: Device status and service requests
  • Message headers: Protocol overhead for message framing
  • Device clear: USBTMC-specific clear operation
  • Status byte: IEEE 488.2 status byte support over USB

Install with Tessl CLI

npx tessl i tessl/pypi-pyvisa-py

docs

core-backend.md

gpib-communication.md

index.md

prologix-adapters.md

serial-communication.md

tcpip-communication.md

usb-communication.md

tile.json