Multi-Bridge Setup
A single AR488 bridge controls one GPIB bus with up to 30 instruments. When your equipment spans multiple buses — separate test benches, different rooms, or a mix of USB and WiFi connections — mcgpib manages them all from one server. This tutorial shows you how to configure two bridges and run cross-bus operations.
When you need multiple bridges
Section titled “When you need multiple bridges”Common scenarios:
- Separate test benches — one bench for analog measurements, another for RF or power. Each has its own GPIB bus and bridge.
- Mixed transports — a USB-connected bridge on the bench in front of you, and a WiFi bridge on a rack across the lab.
- Isolation — sensitive measurement equipment on one bus, noisy power supplies on another, to avoid bus contention and ground loops.
- Scale — more than 30 instruments. Each GPIB bus supports 30 addresses, so a second bridge doubles your capacity.
Each bridge operates independently. The server talks to them concurrently when they are on separate buses, and serializes commands within each bridge using per-bridge locks.
Configure two bridges
Section titled “Configure two bridges”Create or update your configuration file with two [[bridge]] sections. The double brackets in TOML denote an array — each [[bridge]] block defines one bridge.
[server]log_level = "INFO"
# USB-connected bridge on the local bench[[bridge]]name = "bench-a"transport = "serial"port = "/dev/ttyUSB0"baudrate = 115200auto_scan = trueauto_identify = trueread_timeout_ms = 3000inter_command_delay_ms = 10
# WiFi-connected bridge on the far rack[[bridge]]name = "rack-b"transport = "tcp"host = "192.168.1.50"tcp_port = 23auto_scan = trueauto_identify = trueread_timeout_ms = 5000inter_command_delay_ms = 20A few things to note:
- Each bridge must have a unique
name. This is how you address them in every tool call. Pick names that reflect their physical location or purpose. - Transport settings are per-bridge. You can mix serial and TCP bridges freely.
- Timeouts are independent. The WiFi bridge (
rack-b) has longer timeouts because wireless adds latency. The USB bridge (bench-a) uses tighter defaults.
Connect both bridges
Section titled “Connect both bridges”-
List configured bridges
Start a Claude Code session and verify the server sees both bridges:
> List my GPIB bridgesClaude calls
list_bridges():Bridges:bench-a: serial (/dev/ttyUSB0) [disconnected]rack-b: tcp (192.168.1.50:23) [disconnected]Both bridges are configured but not yet connected.
-
Connect the first bridge
> Connect to bench-aClaude calls
connect_bridge("bench-a"):Connected to bench-a: AR488 GPIB controller 0.05.99Discovered 2 instrument(s):Address 5: KEITHLEY INSTRUMENTS INC. 2000Address 22: Agilent Technologies E3631A -
Connect the second bridge
> Connect to rack-b tooClaude calls
connect_bridge("rack-b"):Connected to rack-b: AR488 GPIB controller 0.05.99Discovered 2 instrument(s):Address 1: HEWLETT-PACKARD 34401AAddress 10: Tektronix TDS 2024B -
View all instruments across both buses
> Show me all instrumentsClaude calls
list_instruments()(with no bridge filter):Discovered instruments:[bench-a] Address 5: KEITHLEY INSTRUMENTS INC. 2000[bench-a] Address 22: Agilent Technologies E3631A[rack-b] Address 1: HEWLETT-PACKARD 34401A[rack-b] Address 10: Tektronix TDS 2024BThe bridge name prefix (
[bench-a],[rack-b]) tells you which bus each instrument is on.
Cross-bus operations
Section titled “Cross-bus operations”With both bridges connected, you can orchestrate workflows that span buses. The bridge_name parameter in every tool call routes the command to the correct bridge.
Here is a practical example: read a voltage on bench-a while adjusting a power supply on rack-b. Suppose you are characterizing how a device under test responds to supply voltage changes.
-
Set the power supply output
The Agilent E3631A at address 22 on bench-a has three outputs. Set the +6V output to 3.3V:
> Set the E3631A on bench-a to output 3.3V on the +6V channelClaude calls:
instrument_write("bench-a", 22, "INST P6V")— select the +6V outputinstrument_write("bench-a", 22, "VOLT 3.3")— set voltage to 3.3Vinstrument_write("bench-a", 22, "OUTP ON")— enable the output
Sent to address 22: INST P6VSent to address 22: VOLT 3.3Sent to address 22: OUTP ON -
Read the resulting voltage on the other bus
The HP 34401A at address 1 on rack-b is probing the device under test:
> Read DC voltage on the HP 34401A on rack-bClaude calls:
instrument_write("rack-b", 1, "CONF:VOLT:DC")instrument_query("rack-b", 1, "READ?")
Sent to address 1: CONF:VOLT:DC+3.29120E+003.291V measured at the DUT — reasonable for a 3.3V supply with some drop across the circuit.
-
Sweep and measure
You can ask Claude to automate the full sequence:
> Sweep the E3631A supply voltage from 3.0V to 5.0V in 0.5V steps.> At each step, wait 500ms for settling, then read the voltage on> the HP 34401A. Show me a table of set voltage vs measured voltage.Claude will interleave
instrument_writecalls on bench-a withinstrument_querycalls on rack-b, building a table as it goes:| Set (V) | Measured (V) ||---------|-------------|| 3.0 | 2.987 || 3.5 | 3.491 || 4.0 | 3.993 || 4.5 | 4.488 || 5.0 | 4.982 |
Use the bus_health_check prompt
Section titled “Use the bus_health_check prompt”mcgpib includes a bus_health_check prompt that audits all bridges in a single pass. This is useful for verifying your multi-bridge setup is healthy.
> Run a bus health checkClaude activates the bus_health_check prompt and executes a systematic sequence:
- Calls
list_bridges()to enumerate all configured bridges - For each connected bridge, calls
bus_scan()andcheck_srq() - For disconnected bridges, attempts
connect_bridge() - Calls
serial_poll()on each bridge to check for instruments requesting service
The resulting report looks something like:
GPIB Infrastructure Health Report==================================
Bridges: 2 configured, 2 connected, 0 failed
bench-a (serial /dev/ttyUSB0): Firmware: AR488 GPIB controller 0.05.99 Instruments: 2 discovered, 2 identified Address 5: KEITHLEY INSTRUMENTS INC. 2000 — status 0x00 (idle) Address 22: Agilent Technologies E3631A — status 0x00 (idle) SRQ: not asserted
rack-b (tcp 192.168.1.50:23): Firmware: AR488 GPIB controller 0.05.99 Instruments: 2 discovered, 2 identified Address 1: HEWLETT-PACKARD 34401A — status 0x00 (idle) Address 10: Tektronix TDS 2024B — status 0x40 [SRQ] SRQ: ASSERTED — device at address 10 requesting service
Recommendations: - Address 10 on rack-b has SRQ asserted. Run serial_poll("rack-b", 10) and check *ESR? to determine the cause.Bridge-specific timeouts
Section titled “Bridge-specific timeouts”Different instruments and transports need different timing. You can adjust timeouts at runtime without restarting the server using configure_bridge.
-
Increase timeout for a slow instrument
Some instruments — particularly older HP meters or anything doing an internal self-test — take several seconds to respond. If you are getting timeout errors on rack-b:
> Set the read timeout on rack-b to 10 secondsClaude calls
configure_bridge("rack-b", read_timeout_ms=10000):Configured rack-b: read_timeout_ms=10000This takes effect immediately for all subsequent operations on that bridge. Other bridges are not affected.
-
Tune EOS settings for a specific instrument
Some instruments expect line endings different from the default CRLF. The
eosparameter controls what the bridge appends when sending data:Value Line ending 0CR+LF (default) 1CR only 2LF only 3None > Set bench-a to use LF line endingsClaude calls
configure_bridge("bench-a", eos=2):Configured bench-a: eos=2 -
View current bridge configuration
To check what a bridge is currently configured to:
> Show me the status of rack-bClaude calls
bridge_status("rack-b"):{"name": "rack-b","transport_type": "tcp","connection_state": "connected","firmware_version": "AR488 GPIB controller 0.05.99","controller_address": 0,"current_address": 1,"read_timeout_ms": 10000,"tcp_host": "192.168.1.50","tcp_port": 23}
Concurrency model
Section titled “Concurrency model”Understanding how mcgpib handles concurrent access helps you reason about what is safe to do in multi-bridge setups.
Across bridges: concurrent. Each bridge has its own asyncio lock and its own transport (serial port or TCP socket). Operations on bench-a and rack-b can proceed simultaneously without blocking each other.
Within a bridge: serialized. GPIB is a shared bus — only one device can talk at a time. The per-bridge lock ensures that if two tool calls target the same bridge, one waits for the other to complete. You cannot corrupt bus state by making overlapping requests.
Practical implication: If Claude needs to read a voltage on bench-a and set a current limit on rack-b, those two operations can overlap. But if Claude needs to write a command and then read a response on the same bridge, those are always sequential — which is exactly how GPIB works.
What is next
Section titled “What is next”- Configuration Reference — full documentation of all config fields and the search path
- Bridge Management Reference — details on connect, disconnect, status, and configure tools
- Prompts Reference — all five guided workflows, including
initialize_benchandtroubleshoot_instrument