0
# USB Communication
1
2
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.
3
4
## Capabilities
5
6
### USBSession Class
7
8
Base class for USB device communication providing common functionality for both USBTMC instruments and raw USB devices.
9
10
```python { .api }
11
class USBSession:
12
"""Base class for USB device communication via PyUSB."""
13
14
def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
15
"""
16
Initialize USB session (base class).
17
18
Args:
19
resource_manager_session (VISARMSession): Parent RM session
20
resource_name (str): USB resource name
21
parsed (rname.ResourceName): Parsed resource name
22
open_timeout (int): Connection timeout in milliseconds
23
"""
24
25
def read(self, count):
26
"""
27
Read data from USB device.
28
29
Args:
30
count (int): Maximum number of bytes to read
31
32
Returns:
33
Tuple[bytes, StatusCode]: Data read and operation status
34
"""
35
36
def write(self, data):
37
"""
38
Write data to USB device.
39
40
Args:
41
data (bytes): Data to transmit
42
43
Returns:
44
Tuple[int, StatusCode]: Number of bytes written and status
45
"""
46
47
def close(self):
48
"""
49
Close USB connection and release device.
50
51
Returns:
52
StatusCode: Operation result
53
"""
54
55
@staticmethod
56
def list_resources():
57
"""
58
List available USB devices (implemented in subclasses).
59
60
Returns:
61
List[str]: List of USB device resource strings
62
"""
63
```
64
65
### USBInstrSession Class
66
67
Handles USB instrument communication using the USBTMC protocol, which is the standard for USB-connected test and measurement instruments.
68
69
```python { .api }
70
class USBInstrSession(USBSession):
71
"""Session for USB instrument communication via USBTMC."""
72
73
def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
74
"""
75
Initialize USB USBTMC instrument session.
76
77
Args:
78
resource_manager_session (VISARMSession): Parent RM session
79
resource_name (str): USB INSTR resource name
80
parsed (rname.ResourceName): Parsed resource name
81
open_timeout (int): Connection timeout in milliseconds
82
"""
83
84
def clear(self):
85
"""
86
Clear USB instrument (send USBTMC clear command).
87
88
Returns:
89
StatusCode: Operation result
90
"""
91
92
@staticmethod
93
def list_resources():
94
"""
95
List available USB USBTMC instruments.
96
97
Returns:
98
List[str]: List of USB INSTR resource strings
99
"""
100
```
101
102
### USBRawSession Class
103
104
Provides raw USB device access for specialized communication protocols that don't use USBTMC.
105
106
```python { .api }
107
class USBRawSession:
108
"""Session for raw USB device communication."""
109
110
def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
111
"""
112
Initialize raw USB session.
113
114
Args:
115
resource_manager_session (VISARMSession): Parent RM session
116
resource_name (str): Raw USB resource name
117
parsed (rname.ResourceName): Parsed resource name
118
open_timeout (int): Connection timeout in milliseconds
119
"""
120
121
def read(self, count):
122
"""
123
Read data from USB device via bulk/interrupt transfer.
124
125
Args:
126
count (int): Maximum number of bytes to read
127
128
Returns:
129
Tuple[bytes, StatusCode]: Data read and operation status
130
"""
131
132
def write(self, data):
133
"""
134
Write data to USB device via bulk/interrupt transfer.
135
136
Args:
137
data (bytes): Data to transmit
138
139
Returns:
140
Tuple[int, StatusCode]: Number of bytes written and status
141
"""
142
143
def close(self):
144
"""
145
Close raw USB connection.
146
147
Returns:
148
StatusCode: Operation result
149
"""
150
151
@staticmethod
152
def list_resources():
153
"""
154
List available raw USB devices.
155
156
Returns:
157
List[str]: List of raw USB device resource strings
158
"""
159
```
160
161
### USB Device Management
162
163
Control USB device configuration, interfaces, and endpoints for proper communication setup.
164
165
```python { .api }
166
# USB configuration methods (internal use)
167
def _configure_device(device, interface_number):
168
"""Configure USB device interface for communication."""
169
170
def _find_endpoints(interface):
171
"""Find bulk IN and OUT endpoints for data transfer."""
172
173
def _claim_interface(device, interface_number):
174
"""Claim USB interface for exclusive access."""
175
176
def _release_interface(device, interface_number):
177
"""Release USB interface when done."""
178
```
179
180
## Usage Examples
181
182
### USB Instrument Communication
183
184
```python
185
import pyvisa
186
187
# Use PyVISA-py backend
188
rm = pyvisa.ResourceManager('@py')
189
190
# List USB instruments
191
usb_resources = rm.list_resources('USB?*::INSTR')
192
print("USB instruments:", usb_resources)
193
194
# Resource string format: USB[board]::vendor_id::product_id::serial::interface::INSTR
195
# Example: "USB0::0x1234::0x5678::ABC123::0::INSTR"
196
197
if usb_resources:
198
try:
199
# Open USB instrument
200
inst = rm.open_resource(usb_resources[0])
201
202
# Configure timeout
203
inst.timeout = 5000 # 5 seconds
204
205
# Standard SCPI communication
206
inst.write("*RST") # Reset instrument
207
idn = inst.query("*IDN?")
208
print("Instrument ID:", idn.strip())
209
210
# Read measurement data
211
inst.write("MEAS:VOLT:DC?")
212
voltage = float(inst.read())
213
print(f"Voltage: {voltage} V")
214
215
except pyvisa.VisaIOError as e:
216
print(f"USB communication error: {e}")
217
finally:
218
inst.close()
219
220
rm.close()
221
```
222
223
### Raw USB Device Access
224
225
```python
226
# Open raw USB device for custom protocols
227
raw_resources = rm.list_resources('USB?*::RAW')
228
print("Raw USB devices:", raw_resources)
229
230
if raw_resources:
231
try:
232
# Open raw USB device
233
device = rm.open_resource(raw_resources[0])
234
235
# Send custom command
236
command = b'\\x01\\x02\\x03\\x04' # Custom protocol command
237
bytes_written = device.write_raw(command)
238
print(f"Sent {bytes_written} bytes")
239
240
# Read response
241
response = device.read_raw(64) # Read up to 64 bytes
242
print(f"Received: {response.hex()}")
243
244
except pyvisa.VisaIOError as e:
245
print(f"Raw USB error: {e}")
246
finally:
247
device.close()
248
```
249
250
### USB Device Discovery
251
252
```python
253
# Discover USB devices with specific vendor/product IDs
254
def find_usb_device(vendor_id, product_id):
255
"""Find USB device by vendor and product ID."""
256
rm = pyvisa.ResourceManager('@py')
257
258
# List all USB resources
259
all_usb = rm.list_resources('USB?*')
260
261
# Filter by vendor/product ID
262
target_vid = f"{vendor_id:04X}"
263
target_pid = f"{product_id:04X}"
264
265
matching_devices = []
266
for resource in all_usb:
267
if f"::{target_vid}::{target_pid}::" in resource:
268
matching_devices.append(resource)
269
270
rm.close()
271
return matching_devices
272
273
# Find Keysight devices (vendor ID 0x2A8D)
274
keysight_devices = find_usb_device(0x2A8D, 0x0001) # Example product ID
275
print("Keysight USB devices:", keysight_devices)
276
```
277
278
### Bulk Data Transfer
279
280
```python
281
# High-speed data transfer for instruments that support it
282
inst = rm.open_resource("USB0::0x1234::0x5678::ABC123::0::INSTR")
283
284
try:
285
# Request large data block
286
inst.write("DATA:ARRAY?") # Request array data
287
288
# Read large binary data block
289
# Some instruments send data length first
290
header = inst.read_bytes(4) # Read length header
291
data_length = int.from_bytes(header, byteorder='big')
292
293
# Read the actual data
294
bulk_data = inst.read_bytes(data_length)
295
print(f"Received {len(bulk_data)} bytes of data")
296
297
# Process binary data (example: 16-bit integers)
298
import struct
299
values = struct.unpack(f'>{data_length//2}H', bulk_data)
300
print(f"First 10 values: {values[:10]}")
301
302
except pyvisa.VisaIOError as e:
303
print(f"Bulk transfer error: {e}")
304
finally:
305
inst.close()
306
```
307
308
### USB Configuration Management
309
310
```python
311
# Check USB device configuration
312
inst = rm.open_resource("USB0::0x1234::0x5678::ABC123::0::INSTR")
313
314
try:
315
# Get USB-specific attributes
316
manufacturer = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_MANF_NAME)
317
model = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_MODEL_NAME)
318
serial = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_SERIAL_NUM)
319
320
print(f"Manufacturer: {manufacturer}")
321
print(f"Model: {model}")
322
print(f"Serial: {serial}")
323
324
# Check USB interface information
325
interface_num = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_INTFC_NUM)
326
alt_setting = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_ALT_SETTING)
327
328
print(f"Interface: {interface_num}, Alt Setting: {alt_setting}")
329
330
except Exception as e:
331
print(f"Error reading USB attributes: {e}")
332
finally:
333
inst.close()
334
```
335
336
## Resource String Format
337
338
USB resource strings follow the VISA standard format:
339
340
```
341
USB[board]::vendor_id::product_id::serial_number::interface_number::[INSTR|RAW]
342
```
343
344
**Components:**
345
- **board**: USB host controller (usually 0)
346
- **vendor_id**: 4-digit hex vendor ID (e.g., 0x1234)
347
- **product_id**: 4-digit hex product ID (e.g., 0x5678)
348
- **serial_number**: Device serial number string
349
- **interface_number**: USB interface number (usually 0)
350
- **resource_class**: INSTR for USBTMC, RAW for direct access
351
352
**Examples:**
353
- `USB0::0x2A8D::0x0001::MY12345678::0::INSTR` - Keysight USBTMC instrument
354
- `USB0::0x1234::0x5678::SN123456::0::RAW` - Raw USB device
355
- `USB::0x0957::0x2918::MY50001234::INSTR` - Short form (board defaults to 0)
356
357
## Error Handling
358
359
Common USB communication errors and solutions:
360
361
```python
362
from pyvisa import VisaIOError
363
from pyvisa.constants import StatusCode
364
365
try:
366
inst = rm.open_resource("USB0::0x1234::0x5678::ABC123::0::INSTR")
367
except VisaIOError as e:
368
if e.error_code == StatusCode.error_resource_not_found:
369
print("USB device not found - check connection and drivers")
370
elif e.error_code == StatusCode.error_resource_busy:
371
print("USB device busy - another application may be using it")
372
elif e.error_code == StatusCode.error_insufficient_location_information:
373
print("Invalid USB resource string format")
374
else:
375
print(f"USB open error: {e}")
376
377
# Handle communication timeouts
378
try:
379
response = inst.query("*IDN?", timeout=2000)
380
except VisaIOError as e:
381
if e.error_code == StatusCode.error_timeout:
382
print("USB communication timeout - device may not respond to SCPI")
383
elif e.error_code == StatusCode.error_io:
384
print("USB I/O error - check USB connection")
385
```
386
387
## Dependencies
388
389
USB communication requires the PyUSB package and appropriate USB backend libraries:
390
391
```bash
392
# Install USB support
393
pip install pyvisa-py[usb]
394
395
# Or install PyUSB directly
396
pip install pyusb
397
```
398
399
**USB Backend Requirements:**
400
- **Windows**: Uses WinUSB driver or libusb-win32
401
- **Linux**: Uses libusb-1.0 (usually pre-installed)
402
- **macOS**: Uses libusb (install via Homebrew: `brew install libusb`)
403
404
## Device Permissions
405
406
### Linux
407
USB devices may require proper permissions or udev rules:
408
409
```bash
410
# Add user to dialout group for USB access
411
sudo usermod -a -G dialout $USER
412
413
# Or create udev rule for specific devices
414
# /etc/udev/rules.d/99-usb-instruments.rules:
415
# SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", MODE="0666"
416
```
417
418
### Windows
419
- Install appropriate USB drivers (often provided by instrument manufacturer)
420
- Some devices require libusb or WinUSB drivers instead of vendor drivers
421
- Use Zadig tool to install WinUSB drivers for raw USB access
422
423
### macOS
424
- Usually works out of the box with libusb
425
- Some instruments may require disabling System Integrity Protection for driver access
426
427
## USBTMC Protocol Details
428
429
The USB Test & Measurement Class provides standardized communication for instruments:
430
431
- **Bulk-OUT**: Host to device commands and data
432
- **Bulk-IN**: Device to host responses and data
433
- **Interrupt-IN**: Device status and service requests
434
- **Message headers**: Protocol overhead for message framing
435
- **Device clear**: USBTMC-specific clear operation
436
- **Status byte**: IEEE 488.2 status byte support over USB