0
# TCP/IP Communication
1
2
Network-based instrument communication supporting multiple protocols including VXI-11, HiSLIP (High-Speed LAN Instrument Protocol), VICP (VISA over IP), and raw TCP sockets. PyVISA-py provides comprehensive Ethernet instrument support with automatic protocol detection and network discovery capabilities.
3
4
## Capabilities
5
6
### TCPIPInstrSession Class
7
8
Main dispatcher for TCP/IP instrument communication that automatically creates the appropriate protocol-specific session (VXI-11 or HiSLIP) based on the resource string format.
9
10
```python { .api }
11
class TCPIPInstrSession:
12
"""Dispatcher that creates VXI-11 or HiSLIP sessions based on resource string."""
13
14
def __new__(cls, resource_manager_session, resource_name, parsed, open_timeout):
15
"""
16
Create appropriate TCP/IP session based on resource string.
17
18
Args:
19
resource_manager_session (VISARMSession): Parent RM session
20
resource_name (str): TCP/IP resource name
21
parsed (rname.ResourceName): Parsed resource name
22
open_timeout (int): Connection timeout in milliseconds
23
24
Returns:
25
TCPIPInstrVxi11 or TCPIPInstrHiSLIP: Protocol-specific session instance
26
"""
27
28
@staticmethod
29
def list_resources():
30
"""
31
List available TCP/IP instruments via network discovery.
32
33
Returns:
34
List[str]: Combined list from VXI-11 and HiSLIP discovery
35
"""
36
```
37
38
### TCPIPInstrVxi11 Class
39
40
VXI-11 protocol implementation for standard Ethernet instrument communication.
41
42
```python { .api }
43
class TCPIPInstrVxi11:
44
"""TCP/IP session using VXI-11 protocol for network instruments."""
45
46
def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
47
"""
48
Initialize VXI-11 session.
49
50
Args:
51
resource_manager_session (VISARMSession): Parent RM session
52
resource_name (str): TCP/IP resource name
53
parsed (rname.ResourceName): Parsed resource name
54
open_timeout (int): Connection timeout in milliseconds
55
"""
56
57
def read(self, count):
58
"""
59
Read data via VXI-11 protocol.
60
61
Args:
62
count (int): Maximum number of bytes to read
63
64
Returns:
65
Tuple[bytes, StatusCode]: Data read and operation status
66
"""
67
68
def write(self, data):
69
"""
70
Write data via VXI-11 protocol.
71
72
Args:
73
data (bytes): Data to transmit
74
75
Returns:
76
Tuple[int, StatusCode]: Number of bytes written and status
77
"""
78
79
def clear(self):
80
"""
81
Clear instrument via VXI-11 device clear.
82
83
Returns:
84
StatusCode: Operation result
85
"""
86
87
@staticmethod
88
def list_resources():
89
"""
90
Discover VXI-11 instruments via broadcast.
91
92
Returns:
93
List[str]: List of VXI-11 instrument resource strings
94
"""
95
```
96
97
### TCPIPInstrHiSLIP Class
98
99
HiSLIP (High-Speed LAN Instrument Protocol) implementation for high-performance Ethernet communication.
100
101
```python { .api }
102
class TCPIPInstrHiSLIP:
103
"""TCP/IP session using HiSLIP protocol for high-speed instruments."""
104
105
def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
106
"""
107
Initialize HiSLIP session.
108
109
Args:
110
resource_manager_session (VISARMSession): Parent RM session
111
resource_name (str): HiSLIP resource name
112
parsed (rname.ResourceName): Parsed resource name
113
open_timeout (int): Connection timeout in milliseconds
114
"""
115
116
def read(self, count):
117
"""
118
Read data via HiSLIP protocol.
119
120
Args:
121
count (int): Maximum number of bytes to read
122
123
Returns:
124
Tuple[bytes, StatusCode]: Data read and operation status
125
"""
126
127
def write(self, data):
128
"""
129
Write data via HiSLIP protocol.
130
131
Args:
132
data (bytes): Data to transmit
133
134
Returns:
135
Tuple[int, StatusCode]: Number of bytes written and status
136
"""
137
138
def clear(self):
139
"""
140
Clear instrument via HiSLIP device clear.
141
142
Returns:
143
StatusCode: Operation result
144
"""
145
146
@staticmethod
147
def list_resources():
148
"""
149
Discover HiSLIP instruments via mDNS.
150
151
Returns:
152
List[str]: List of HiSLIP instrument resource strings
153
"""
154
```
155
156
### TCPIPInstrVicp Class
157
158
VICP (VISA over IP) protocol implementation for LeCroy/Teledyne oscilloscopes.
159
160
```python { .api }
161
class TCPIPInstrVicp:
162
"""TCP/IP session using VICP protocol for LeCroy oscilloscopes."""
163
164
def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
165
"""
166
Initialize VICP session.
167
168
Args:
169
resource_manager_session (VISARMSession): Parent RM session
170
resource_name (str): VICP resource name
171
parsed (rname.ResourceName): Parsed resource name
172
open_timeout (int): Connection timeout in milliseconds
173
"""
174
175
def read(self, count):
176
"""
177
Read data via VICP protocol.
178
179
Args:
180
count (int): Maximum number of bytes to read
181
182
Returns:
183
Tuple[bytes, StatusCode]: Data read and operation status
184
"""
185
186
def write(self, data):
187
"""
188
Write data via VICP protocol.
189
190
Args:
191
data (bytes): Data to transmit
192
193
Returns:
194
Tuple[int, StatusCode]: Number of bytes written and status
195
"""
196
```
197
198
### TCPIPSocketSession Class
199
200
Provides raw TCP socket communication for instruments using proprietary protocols or simple socket-based communication.
201
202
```python { .api }
203
class TCPIPSocketSession:
204
"""Session for raw TCP socket communication."""
205
206
def __init__(self, resource_manager_session, resource_name, parsed, open_timeout):
207
"""
208
Initialize TCP socket session.
209
210
Args:
211
resource_manager_session (VISARMSession): Parent RM session
212
resource_name (str): TCP socket resource name
213
parsed (rname.ResourceName): Parsed resource name
214
open_timeout (int): Connection timeout in milliseconds
215
"""
216
217
def read(self, count):
218
"""
219
Read data from TCP socket.
220
221
Args:
222
count (int): Maximum number of bytes to read
223
224
Returns:
225
Tuple[bytes, StatusCode]: Data read and operation status
226
"""
227
228
def write(self, data):
229
"""
230
Write data to TCP socket.
231
232
Args:
233
data (bytes): Data to transmit
234
235
Returns:
236
Tuple[int, StatusCode]: Number of bytes written and status
237
"""
238
239
def close(self):
240
"""
241
Close TCP socket connection.
242
243
Returns:
244
StatusCode: Operation result
245
"""
246
```
247
248
### Protocol-Specific Classes
249
250
Internal protocol implementations that handle the low-level communication details for each network protocol.
251
252
```python { .api }
253
class TCPIPInstrVxi11:
254
"""VXI-11 protocol implementation for network instruments."""
255
256
class TCPIPInstrHiSLIP:
257
"""HiSLIP protocol implementation for high-speed network instruments."""
258
259
class TCPIPInstrVicp:
260
"""VICP protocol implementation for LeCroy oscilloscopes."""
261
```
262
263
## Usage Examples
264
265
### VXI-11 Instrument Communication
266
267
```python
268
import pyvisa
269
270
# Use PyVISA-py backend
271
rm = pyvisa.ResourceManager('@py')
272
273
# VXI-11 is the default protocol for TCPIP::hostname::INSTR
274
try:
275
# Open VXI-11 instrument
276
inst = rm.open_resource("TCPIP::192.168.1.100::INSTR")
277
278
# Configure timeout
279
inst.timeout = 5000 # 5 seconds
280
281
# Standard SCPI communication
282
idn = inst.query("*IDN?")
283
print("Instrument ID:", idn.strip())
284
285
# Device reset and configuration
286
inst.write("*RST")
287
inst.write("*CLS") # Clear status
288
289
# Read measurement
290
inst.write("MEAS:VOLT:DC?")
291
voltage = float(inst.read())
292
print(f"Measured voltage: {voltage} V")
293
294
except pyvisa.VisaIOError as e:
295
print(f"VXI-11 communication error: {e}")
296
finally:
297
inst.close()
298
299
rm.close()
300
```
301
302
### HiSLIP Communication
303
304
```python
305
# HiSLIP provides faster communication than VXI-11
306
# Resource format: TCPIP::hostname::hislip[session]::INSTR
307
308
try:
309
# Open HiSLIP instrument (session 0 is default)
310
inst = rm.open_resource("TCPIP::192.168.1.101::hislip0::INSTR")
311
312
# HiSLIP supports larger messages and faster transfer
313
inst.timeout = 10000 # 10 seconds for large data
314
315
# Query instrument capabilities
316
options = inst.query("*OPT?")
317
print("Instrument options:", options)
318
319
# Request large data block
320
inst.write("DATA:CAPTURE?") # Request waveform data
321
waveform_data = inst.read_bytes(1000000) # Read 1MB of data
322
print(f"Received {len(waveform_data)} bytes of waveform data")
323
324
except pyvisa.VisaIOError as e:
325
print(f"HiSLIP communication error: {e}")
326
finally:
327
inst.close()
328
```
329
330
### Raw TCP Socket Communication
331
332
```python
333
# Raw TCP socket for proprietary protocols
334
# Resource format: TCPIP::hostname::port::SOCKET
335
336
try:
337
# Open raw TCP socket
338
socket_inst = rm.open_resource("TCPIP::192.168.1.102::5025::SOCKET")
339
340
# Set socket-specific options
341
socket_inst.timeout = 3000
342
socket_inst.read_termination = '\\n'
343
socket_inst.write_termination = '\\n'
344
345
# Send raw commands
346
socket_inst.write("GET_STATUS")
347
status = socket_inst.read()
348
print("Device status:", status.strip())
349
350
# Binary protocol example
351
command = b'\\x02\\x01\\x00\\x04DATA\\x03' # Custom binary command
352
socket_inst.write_raw(command)
353
response = socket_inst.read_raw(128)
354
print(f"Binary response: {response.hex()}")
355
356
except pyvisa.VisaIOError as e:
357
print(f"TCP socket error: {e}")
358
finally:
359
socket_inst.close()
360
```
361
362
### VICP Protocol (LeCroy Oscilloscopes)
363
364
```python
365
# VICP is used by LeCroy/Teledyne oscilloscopes
366
# Requires pyvicp package: pip install pyvisa-py[vicp]
367
368
try:
369
# Open VICP instrument
370
scope = rm.open_resource("VICP::192.168.1.103::INSTR")
371
372
# LeCroy-specific commands
373
idn = scope.query("*IDN?")
374
print("Oscilloscope:", idn.strip())
375
376
# Configure timebase
377
scope.write("TIME_DIV 1E-6") # 1 µs/div
378
379
# Capture and read waveform
380
scope.write("ARM")
381
scope.write("WAIT") # Wait for trigger
382
383
# Read waveform data
384
scope.write("C1:WAVEFORM?")
385
waveform = scope.read_raw(10000000) # Read up to 10MB
386
print(f"Waveform size: {len(waveform)} bytes")
387
388
except pyvisa.VisaIOError as e:
389
print(f"VICP communication error: {e}")
390
finally:
391
scope.close()
392
```
393
394
### Network Discovery
395
396
```python
397
# Discover instruments on the network
398
def discover_network_instruments():
399
"""Discover instruments using various methods."""
400
rm = pyvisa.ResourceManager('@py')
401
402
# Method 1: List all TCPIP resources (includes discovered devices)
403
tcpip_resources = rm.list_resources('TCPIP?*::INSTR')
404
print("Discovered TCPIP instruments:", tcpip_resources)
405
406
# Method 2: List socket resources
407
socket_resources = rm.list_resources('TCPIP?*::SOCKET')
408
print("Available socket connections:", socket_resources)
409
410
# Method 3: List HiSLIP resources (if zeroconf available)
411
hislip_resources = rm.list_resources('TCPIP?*::hislip?*::INSTR')
412
print("HiSLIP instruments:", hislip_resources)
413
414
# Method 4: List VICP resources (if pyvicp and zeroconf available)
415
vicp_resources = rm.list_resources('VICP?*::INSTR')
416
print("VICP instruments:", vicp_resources)
417
418
rm.close()
419
return tcpip_resources + socket_resources + hislip_resources + vicp_resources
420
421
# Run discovery
422
instruments = discover_network_instruments()
423
```
424
425
### Connection Management and Keepalive
426
427
```python
428
# Configure TCP keepalive for reliable connections
429
inst = rm.open_resource("TCPIP::192.168.1.100::INSTR")
430
431
try:
432
# Enable TCP keepalive (PyVISA-py specific attribute)
433
inst.set_visa_attribute(pyvisa.constants.VI_ATTR_TCPIP_KEEPALIVE, True)
434
435
# Configure keepalive parameters (if supported by platform)
436
inst.set_visa_attribute(pyvisa.constants.VI_ATTR_TCPIP_ADDR, "192.168.1.100")
437
438
# Set large timeout for long operations
439
inst.timeout = 30000 # 30 seconds
440
441
# Perform long-running operation
442
inst.write("SYSTEM:PRESET") # May take time to complete
443
inst.query("*OPC?") # Wait for operation complete
444
445
except Exception as e:
446
print(f"Keepalive configuration error: {e}")
447
finally:
448
inst.close()
449
```
450
451
## Resource String Formats
452
453
TCP/IP resource strings support multiple formats:
454
455
### VXI-11 Instruments
456
```
457
TCPIP::[board]::hostname[::lan_device_name]::INSTR
458
```
459
- `TCPIP::192.168.1.100::INSTR` - Basic VXI-11
460
- `TCPIP0::scope.local::inst0::INSTR` - With board and device name
461
462
### HiSLIP Instruments
463
```
464
TCPIP::[board]::hostname::hislip[session]::INSTR
465
```
466
- `TCPIP::192.168.1.101::hislip0::INSTR` - HiSLIP session 0
467
- `TCPIP::analyzer.lab.com::hislip::INSTR` - Default session
468
469
### Raw TCP Sockets
470
```
471
TCPIP::[board]::hostname::port::SOCKET
472
```
473
- `TCPIP::192.168.1.102::5025::SOCKET` - SCPI port
474
- `TCPIP0::device.local::8080::SOCKET` - Custom port
475
476
### VICP Instruments
477
```
478
VICP::[board]::hostname::INSTR
479
```
480
- `VICP::192.168.1.103::INSTR` - LeCroy oscilloscope
481
482
## Error Handling
483
484
Network communication errors and troubleshooting:
485
486
```python
487
from pyvisa import VisaIOError
488
from pyvisa.constants import StatusCode
489
import socket
490
491
try:
492
inst = rm.open_resource("TCPIP::192.168.1.100::INSTR")
493
except VisaIOError as e:
494
if e.error_code == StatusCode.error_resource_not_found:
495
print("Host not reachable - check IP address and network")
496
elif e.error_code == StatusCode.error_timeout:
497
print("Connection timeout - device may not support VXI-11")
498
elif e.error_code == StatusCode.error_connection_lost:
499
print("Network connection lost")
500
else:
501
print(f"Network error: {e}")
502
503
# Handle protocol-specific errors
504
try:
505
response = inst.query("*IDN?", timeout=5000)
506
except VisaIOError as e:
507
if e.error_code == StatusCode.error_timeout:
508
print("Command timeout - check if device supports SCPI")
509
elif e.error_code == StatusCode.error_io:
510
print("I/O error - network communication failed")
511
512
# Check network connectivity
513
def test_network_connectivity(hostname, port=111): # VXI-11 uses port 111
514
"""Test if host is reachable on specified port."""
515
try:
516
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
517
sock.settimeout(3)
518
result = sock.connect_ex((hostname, port))
519
sock.close()
520
return result == 0
521
except Exception:
522
return False
523
524
if not test_network_connectivity("192.168.1.100"):
525
print("Host not reachable on VXI-11 port")
526
```
527
528
## Dependencies
529
530
TCP/IP communication has optional dependencies for enhanced functionality:
531
532
```bash
533
# Install all TCP/IP features
534
pip install pyvisa-py[psutil,hislip-discovery,vicp]
535
536
# Individual packages:
537
pip install psutil # Enhanced network interface discovery
538
pip install zeroconf # HiSLIP and VICP device discovery
539
pip install pyvicp # VICP protocol support
540
```
541
542
## Network Discovery
543
544
### VXI-11 Discovery
545
- Uses RPC portmapper (port 111) to discover instruments
546
- Broadcasts VXI-11 discovery requests on local network
547
- Automatically finds instruments that respond to VXI-11
548
549
### HiSLIP Discovery
550
- Uses mDNS/Bonjour service discovery (requires zeroconf)
551
- Discovers HiSLIP instruments advertising "_hislip._tcp" service
552
- Provides automatic instrument name resolution
553
554
### VICP Discovery
555
- Uses mDNS to discover LeCroy oscilloscopes (requires zeroconf and pyvicp)
556
- Finds instruments advertising "_vicp-ctrl._tcp" service
557
- Automatically configures VICP connection parameters
558
559
## Protocol Comparison
560
561
| Protocol | Speed | Features | Use Case |
562
|----------|-------|----------|----------|
563
| VXI-11 | Medium | Standard, reliable | General instruments |
564
| HiSLIP | High | Fast, efficient | High-throughput data |
565
| VICP | High | LeCroy-specific | LeCroy oscilloscopes |
566
| Raw TCP | Variable | Custom protocols | Proprietary devices |
567
568
## Security Considerations
569
570
- Network instruments are often unsecured - use on trusted networks only
571
- Some protocols transmit data in plain text
572
- Configure firewalls to restrict instrument access
573
- Consider VPN for remote instrument access
574
- Use instrument-specific security features when available