Add Diátaxis documentation for multi-VNA features

New pages covering all 4 quadrants:
- Tutorial: tutorials/multi-vna-basics.mdx
- How-To: hardware/trigger-wiring.mdx, hardware/external-clock.mdx
- Explanation: mcnanovna/multi-vna.mdx

Updated sidebar navigation and cross-links in overview, tools,
and quickstart pages.
This commit is contained in:
Ryan Malloy 2026-02-11 12:54:31 -07:00
parent 0e5553c661
commit 5edac3007c
8 changed files with 1136 additions and 10 deletions

View File

@ -32,6 +32,7 @@ export default defineConfig({
{ label: 'Overview', slug: 'mcnanovna/overview' },
{ label: 'Tool Reference', slug: 'mcnanovna/tools' },
{ label: 'Prompts', slug: 'mcnanovna/prompts' },
{ label: 'Multi-VNA Coordination', slug: 'mcnanovna/multi-vna' },
{ label: 'Web UI', slug: 'mcnanovna/webui' },
],
},
@ -49,6 +50,8 @@ export default defineConfig({
{ label: 'Positioner Build', slug: 'hardware/positioner-build' },
{ label: 'Wiring Diagram', slug: 'hardware/wiring' },
{ label: 'Firmware', slug: 'hardware/firmware' },
{ label: 'VNA Trigger Wiring', slug: 'hardware/trigger-wiring' },
{ label: 'VNA External Clock', slug: 'hardware/external-clock' },
],
},
{
@ -57,6 +60,7 @@ export default defineConfig({
{ label: '3D Pattern Measurement', slug: 'tutorials/pattern-measurement' },
{ label: 'VNA Calibration', slug: 'tutorials/calibration' },
{ label: 'Antenna Analysis', slug: 'tutorials/antenna-analysis' },
{ label: 'Multi-VNA Basics', slug: 'tutorials/multi-vna-basics' },
],
},
{

View File

@ -49,7 +49,8 @@ You should see device details like firmware version, serial number, and frequenc
- [Install mcpositioner](/mcpositioner/overview/) for automated antenna measurements
- [Run a calibration](/tutorials/calibration/) for accurate measurements
- [Explore all 78 tools](/mcnanovna/tools/)
- [Explore all 91 tools](/mcnanovna/tools/)
- [Multi-VNA measurements](/tutorials/multi-vna-basics/) — Use two VNAs together
## Troubleshooting

View File

@ -0,0 +1,264 @@
---
title: VNA External Clock Modification
description: Share a clock reference for Tier 3 phase-coherent measurements
---
import { Steps, Tabs, TabItem, Aside, Card, CardGrid } from '@astrojs/starlight/components';
Phase-coherent operation (Tier 3) locks all VNAs to a shared 26 MHz reference clock, achieving ±1° phase alignment. This is essential for antenna arrays, MIMO testing, and any measurement where relative phase matters.
<Aside type="caution">
This modification requires PCB surgery—cutting traces and soldering to IC pins. It voids your warranty and risks damaging the VNA if done incorrectly. Only proceed if you're comfortable with fine-pitch SMD work.
</Aside>
## Prerequisites
Complete [hardware trigger wiring (Tier 2)](/hardware/trigger-wiring/) first. Phase coherent operation requires both:
1. Shared clock reference (this modification)
2. Hardware trigger synchronization (Tier 2)
## When You Need This
<CardGrid stagger>
<Card title="Antenna Arrays" icon="rocket">
Phased arrays require known phase relationships between elements. Software or trigger sync alone can't provide phase information.
</Card>
<Card title="MIMO Systems" icon="laptop">
Multiple-input-multiple-output antenna characterization needs coherent phase measurement across all paths.
</Card>
<Card title="Phase Noise Measurement" icon="star">
Comparing oscillator phase noise requires a more stable reference than the internal crystal.
</Card>
<Card title="Beamforming Verification" icon="seti:satellite">
Verify beam patterns and null depths on multi-element antennas.
</Card>
</CardGrid>
## Clock Reference Options
| Source | Stability | Cost | Best For |
|--------|-----------|------|----------|
| **OCXO** (oven crystal) | ~1 ppb | $50-200 | Bench work, highest stability |
| **TCXO** | ~1 ppm | $10-30 | Portable, adequate for most |
| **GPS-DO** (GPS disciplined) | ~0.01 ppb | $100-300 | Absolute accuracy, traceable |
| **Single VNA CLK2** | Device-dependent | $0 | Quick hack, tap one VNA's Si5351 |
<Aside type="tip">
For most amateur work, a TCXO is sufficient and much cheaper than an OCXO. The key is that all VNAs share the *same* reference—absolute stability matters less than matching.
</Aside>
## Parts Needed
- 26 MHz reference oscillator (OCXO, TCXO, or GPS-DO module)
- Clock distribution splitter (for 3+ VNAs)
- 100nF DC blocking capacitors (0402 or 0603)
- SMA connectors and coax
- Fine soldering equipment (hot air recommended)
## Modification Steps
<Steps>
1. **Open the enclosure**
Remove the four screws and carefully separate the front panel from the PCB. Note the ribbon cable to the LCD.
2. **Locate the Si5351**
The Si5351 clock generator IC is typically near the MCU. It's a small QFN package marked "Si5351A" or similar.
```
┌──────────────────────────────────────┐
│ │
│ ┌─────┐ │
│ │Si5351│◄── Clock generator │
│ └─────┘ │
│ │ │
│ [Y1]◄── 26 MHz crystal │
│ │
└──────────────────────────────────────┘
```
3. **Cut the crystal trace**
The Si5351 CLKIN pin (pin 1) connects to the on-board 26 MHz crystal. Cut this trace to disconnect the internal crystal:
- Use a sharp blade or micro drill
- Cut between the crystal and pin 1
- Verify with multimeter (no continuity)
<Aside type="caution">
This is the point of no return. Once cut, the VNA won't work without an external clock.
</Aside>
4. **Add DC blocking capacitor**
Solder a 100nF capacitor in series with the external clock input:
```
External ┌───┐
Clock ─────►│100n├────► Si5351 CLKIN (pin 1)
└───┘
```
This blocks any DC offset from your reference source.
5. **Add external clock connection**
Options for bringing the clock signal in:
- **SMA connector**: Drill the enclosure, mount an SMA
- **Wire**: Run a thin coax through an existing opening
- **Test point**: Solder to an accessible pad
Keep the clock path short (< 5cm) to minimize pickup.
6. **Reassemble and test**
- Reconnect the LCD ribbon cable
- Reassemble enclosure
- Apply external 26 MHz reference
- Verify VNA powers up and runs
</Steps>
## Clock Distribution
For multiple VNAs, distribute the reference clock:
```
┌──────────────────────┐
│ 26 MHz Reference │
│ (OCXO or GPS-DO) │
└──────────┬───────────┘
┌────────────────┼────────────────┐
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ VNA #1 │ │ VNA #2 │ │ VNA #N │
│ (Leader) │ │(Follower) │ │(Follower) │
│ │ │ │ │ │
│ CLK_IN ←──│────│── CLK ────│────│── CLK │
│ TRIG_OUT ─│────│→ TRIG_IN │ │→ TRIG_IN │
└───────────┘ └───────────┘ └───────────┘
```
### Distribution options
| Method | VNAs | Notes |
|--------|------|-------|
| **Direct** | 2 | Split with 50Ω resistors |
| **Clock buffer IC** | 2-8 | LMK00101, CDCE913, etc. |
| **RF splitter** | Any | Power divider, adds insertion loss |
**Important**: Use equal-length cables to all VNAs for matched phase.
## Firmware Commands
Custom firmware adds these clock commands:
| Command | Description |
|---------|-------------|
| `clk_ref {internal\|external}` | Select clock source |
| `clk_status` | PLL lock status, phase offset |
### Switching to external clock
```
raw_command(command="clk_ref external")
```
The Si5351 PLLs need ~100ms to lock after switching. Check lock status:
```
raw_command(command="clk_status")
# Output: locked=true, source=external
```
## Using phase_coherent_sweep
Once all VNAs have external clock and trigger wiring:
Say: "Run a phase-coherent sweep on all devices from 430 to 440 MHz"
The assistant calls:
```
phase_coherent_sweep(
device_ids=["0001234567", "0009876543", "0005555555"],
start_hz=430000000,
stop_hz=440000000,
points=101
)
```
This automatically:
1. Switches all devices to external clock
2. Waits for PLL lock (~100ms)
3. Configures trigger (leader + followers)
4. Runs hardware-synced sweep
5. Restores internal clock
## Validation
After completing the modification, verify phase coherence:
<Steps>
1. **Connect a known reference**
Use a power splitter to feed the same signal to S11 on all VNAs.
2. **Measure phase**
Compare S11 phase readings across VNAs at the same frequency. With phase coherence, they should match within ±1°.
3. **Sweep and compare**
Run multiple sweeps. Phase should be stable across sweeps—if it drifts, check clock distribution.
</Steps>
## Troubleshooting
### PLL won't lock
1. Verify 26 MHz signal at CLKIN (oscilloscope)
2. Check signal level: Si5351 expects 0.6-1.6 Vpp
3. Ensure DC blocking cap is present and not shorted
4. Try different clock source
### Phase drifts over time
1. Allow OCXO to warm up (15-30 minutes)
2. Check cable connections for intermittent contact
3. Verify clock splitter isn't introducing phase shift
4. Avoid temperature changes during measurement
### VNA won't start without external clock
1. Reconnect internal crystal (unsolder cut)
2. Use a backup clock source
3. Consider adding a switch for internal/external
### Phase varies with frequency
1. Expected: cables have frequency-dependent phase shift
2. Use matched-length clock distribution cables
3. Calibrate VNAs at each frequency band
## Specifications
| Parameter | Value |
|-----------|-------|
| Reference frequency | 26 MHz (must match Si5351 XTAL spec) |
| Input level | 0.6-1.6 Vpp into CLKIN |
| PLL lock time | ~100 ms |
| Phase accuracy | ±1° at 1 GHz |
| Jitter contribution | < 1 ps RMS (typical) |
## Next Steps
- [Multi-VNA Coordination](/mcnanovna/multi-vna/) — Understand all three tiers
- [Hardware Trigger Wiring](/hardware/trigger-wiring/) — Required for Tier 3
- [Tool Reference](/mcnanovna/tools/) — Phase coherent tools

View File

@ -0,0 +1,232 @@
---
title: VNA Hardware Trigger Wiring
description: Wire multiple NanoVNAs for Tier 2 synchronized measurements
---
import { Steps, Tabs, TabItem, Aside } from '@astrojs/starlight/components';
Hardware trigger synchronization (Tier 2) achieves ±10-50µs timing between VNAs—100x tighter than software coordination. This guide shows you how to wire the trigger lines between devices.
## When You Need This
| Use Case | Tier 1 (Software) | Tier 2 (Hardware Trigger) |
|----------|-------------------|---------------------------|
| Antenna comparison | ✓ | ✓ |
| SWR/impedance | ✓ | ✓ |
| Signal level measurements | ✓ | ✓ |
| Transmission path timing | Limited | ✓ |
| Differential S21 | Limited | ✓ |
| Multi-VNA transfer functions | ✗ | ✓ |
For phase-aligned measurements, you'll also need [external clock (Tier 3)](/hardware/external-clock/).
## Parts Needed
- Jumper wires (Dupont or similar)
- Soldering iron and solder (fine tip recommended)
- NanoVNA-H with custom firmware supporting trigger commands
<Aside type="caution">
This modification requires soldering to small test points. If you're not comfortable with fine soldering, consider having an experienced friend help.
</Aside>
## Pin Locations
The trigger system uses two GPIO pins on the STM32F303:
| Pin | Function | Location | Description |
|-----|----------|----------|-------------|
| **PA0** | TRIG_IN | See board diagram | External trigger input (rising edge) |
| **PB14** | TRIG_OUT | See board diagram | Pulse output at sweep start |
### NanoVNA-H Rev 3.4 Board
```
┌─────────────────────────────────────────┐
│ │
│ ┌───────────────────────┐ │
│ │ │ │
│ │ LCD │ │
│ │ │ │
│ └───────────────────────┘ │
│ │
│ │
│ [PA0]● ●[PB14] │
│ TRIG_IN TRIG_OUT │
│ │
│ ┌──┐ ┌──┐ │
│ │P1│ │P2│ │
│ └──┘ └──┘ │
│ Port 1 Port 2 │
└─────────────────────────────────────────┘
```
<Aside type="note">
Pin locations vary by board revision. On some boards, these pins are on test points. On others, you may need to solder directly to the MCU. Consult your board's schematic.
</Aside>
## Wiring Steps
<Steps>
1. **Identify the leader VNA**
Choose one VNA as the "leader"—it will generate the trigger pulse that starts all sweeps. The others are "followers."
2. **Solder wires to pins**
On the **leader VNA**:
- Solder a wire to **PB14** (TRIG_OUT)
On each **follower VNA**:
- Solder a wire to **PA0** (TRIG_IN)
Use thin wire (30 AWG or similar) to avoid stressing the pads.
3. **Connect the trigger bus**
Wire all followers' TRIG_IN lines to the leader's TRIG_OUT:
```
Leader VNA Follower VNA #1
┌─────────┐ ┌─────────┐
│ PB14 │──────────────────│ PA0 │
│(TRIG_OUT)│ │(TRIG_IN) │
└─────────┘ │ └─────────┘
│ Follower VNA #2
│ ┌─────────┐
└────────│ PA0 │
│(TRIG_IN) │
└─────────┘
```
For more than 2 followers, daisy-chain or use a splitter.
4. **Verify ground reference**
All VNAs share ground via USB (same host computer). No additional ground wire needed.
If using VNAs on different computers, add a common ground wire.
5. **Test trigger signaling**
Use a multimeter or oscilloscope to verify:
- PB14 can be toggled (use `raw_command("trig_out pulse")`)
- PA0 sees the pulse on followers
</Steps>
## Firmware Requirements
Stock NanoVNA firmware doesn't include trigger commands. You need custom firmware with:
| Command | Description |
|---------|-------------|
| `trig_mode {software\|hardware\|leader\|follower}` | Set trigger mode |
| `trig_out {on\|off\|pulse}` | Manual trigger control |
| `trig_status` | Read trigger state |
Check capability with `detect_capabilities()`:
```json
{
"device_id": "0001234567",
"capabilities": {
"hardware_trigger": true,
"external_clock": false
},
"tier": 2
}
```
<Aside type="tip">
See the NanoVNA-H community firmware for trigger-enabled builds, or build your own from the ChibiOS-based source.
</Aside>
## Using hardware_sync_sweep
Once wiring is complete and firmware supports triggers:
Say: "Run a hardware-synced sweep from 144 to 148 MHz with device 0001234567 as leader"
The assistant calls:
```
hardware_sync_sweep(
leader_device_id="0001234567",
follower_device_ids=["0009876543"],
start_hz=144000000,
stop_hz=148000000,
points=101
)
```
This automatically:
1. Sets leader to "leader" mode
2. Sets followers to "follower" mode
3. Runs parallel scans (hardware synchronized)
4. Restores "software" mode
## Testing the Trigger Line
### Manual test via raw_command
```
# On leader - generate pulse
raw_command(device_id="0001234567", command="trig_out pulse")
# On follower - check status
raw_command(device_id="0009876543", command="trig_status")
```
Expected output: `trigger_count` should increment.
### Oscilloscope verification
- Pulse width: ~10µs
- Rising edge: < 1µs
- Voltage: 3.3V logic level
## Troubleshooting
### Trigger not detected
1. Verify wiring continuity with multimeter
2. Check firmware has `trig_mode` command: `raw_command("help")`
3. Ensure ground is shared between VNAs
4. Try shorter trigger wire (< 30cm recommended)
### Erratic triggering
1. Add 100Ω series resistor on TRIG_OUT to reduce ringing
2. Keep trigger wire away from RF paths
3. Use shielded wire for long runs (> 30cm)
4. Check for EMI from nearby equipment
### Sweeps still not synchronized
1. Verify both VNAs have same sweep settings (start, stop, points)
2. Check trigger mode is correctly set before sweep
3. Ensure leader starts sweep before followers timeout
### Capability shows false
1. Firmware may not support triggers
2. Flash custom firmware with trigger support
3. Run `detect_capabilities()` after firmware update
## Electrical Specifications
| Parameter | Value |
|-----------|-------|
| TRIG_OUT pulse width | 10µs |
| TRIG_IN threshold | 1.6V (TTL-compatible) |
| Maximum trigger cable length | 1m (unshielded), 5m (shielded) |
| Edge-to-sweep latency | < 50µs |
## Next Steps
- [External Clock Modification](/hardware/external-clock/) — Add Tier 3 phase coherence
- [Multi-VNA Coordination](/mcnanovna/multi-vna/) — Understand all synchronization tiers
- [Tool Reference](/mcnanovna/tools/) — Hardware trigger tools

View File

@ -0,0 +1,321 @@
---
title: Multi-VNA Coordination
description: Synchronized measurements across multiple NanoVNA devices
---
import { Tabs, TabItem, Aside, Card, CardGrid } from '@astrojs/starlight/components';
mcnanovna can control multiple NanoVNA devices simultaneously, enabling measurements that a single 2-port VNA can't perform. This page explains the three synchronization tiers and when to use each.
## Why Multiple VNAs?
A single NanoVNA provides 2 ports—enough for S11 (reflection) and S21 (transmission) through one device. Multiple VNAs expand your measurement capability:
| VNAs | Ports | Enables |
|------|-------|---------|
| 1 | 2 | S11, S21 (standard) |
| 2 | 4 | True 4-port, A/B comparison, long path loss |
| 3+ | 2N | Phased arrays, MIMO, multi-element antennas |
## The Synchronization Challenge
When measuring across multiple VNAs, timing matters:
- **Amplitude comparison**: ±5ms is fine—signal levels don't change that fast
- **Time-aligned capture**: Need ±10-50µs for transfer functions
- **Phase alignment**: Need shared clock for coherent phase
mcnanovna provides three tiers to match your precision needs.
## The Three Tiers
<CardGrid stagger>
<Card title="Tier 1: Software" icon="laptop">
**±2-5ms timing**
Parallel async execution via software. Works with any firmware, no modifications needed.
Best for: Antenna comparison, SWR checks, signal level surveys
</Card>
<Card title="Tier 2: Hardware Trigger" icon="seti:pipeline">
**±10-50µs timing**
One VNA triggers the others via GPIO. Requires custom firmware and trigger wiring.
Best for: Transfer functions, differential S21, timing-sensitive measurements
</Card>
<Card title="Tier 3: Phase Coherent" icon="rocket">
**±1° phase alignment**
All VNAs share a 26 MHz clock reference plus hardware trigger.
Best for: Antenna arrays, MIMO, beamforming, phase noise comparison
</Card>
</CardGrid>
## Tier Details
<Tabs>
<TabItem label="Tier 1: Software">
### How It Works
mcnanovna sends scan commands to all VNAs in parallel using Python's `asyncio`. The timing depends on USB latency and OS scheduling.
### Requirements
- Multiple VNAs connected via USB
- Stock firmware (any version)
- No hardware modifications
### Limitations
- ±2-5ms timing (good enough for most amplitude measurements)
- No phase relationship between devices
- USB contention can add jitter
### Tools
| Tool | Description |
|------|-------------|
| `sync_sweep` | Parallel sweep across devices |
| `multi_antenna_compare` | Compare S11 metrics |
| `differential_s21` | Two-VNA transmission |
### Example
```
sync_sweep(
device_ids=["0001234567", "0009876543"],
start_hz=144000000,
stop_hz=148000000,
points=101
)
```
</TabItem>
<TabItem label="Tier 2: Hardware Trigger">
### How It Works
One VNA (leader) pulses a GPIO at sweep start. Other VNAs (followers) wait for this trigger before beginning their sweep.
### Requirements
- Custom firmware with trigger commands (`trig_mode`, `trig_out`)
- Physical trigger wire from leader TRIG_OUT to follower TRIG_IN
- See [Hardware Trigger Wiring](/hardware/trigger-wiring/)
### Limitations
- ±10-50µs timing (excellent for amplitude)
- Still no phase coherence (each VNA has its own clock)
- Requires soldering and firmware changes
### Tools
| Tool | Description |
|------|-------------|
| `set_trigger_mode` | Configure leader/follower |
| `hardware_sync_sweep` | Hardware-triggered sweep |
### Example
```
hardware_sync_sweep(
leader_device_id="0001234567",
follower_device_ids=["0009876543"],
start_hz=144000000,
stop_hz=148000000,
points=101
)
```
</TabItem>
<TabItem label="Tier 3: Phase Coherent">
### How It Works
All VNAs receive the same 26 MHz reference clock from an external source (OCXO, GPS-DO). Combined with hardware trigger, sweeps are phase-aligned.
### Requirements
- Tier 2 prerequisites (trigger wiring + firmware)
- External 26 MHz reference oscillator
- PCB modification to inject clock at Si5351
- See [External Clock Modification](/hardware/external-clock/)
### Limitations
- Requires invasive hardware modification
- More expensive (reference oscillator)
- Voids warranty
- Overkill for most measurements
### Tools
| Tool | Description |
|------|-------------|
| `set_clock_reference` | Switch internal/external |
| `phase_coherent_sweep` | Phase-aligned sweep |
### Example
```
phase_coherent_sweep(
device_ids=["0001234567", "0009876543", "0005555555"],
start_hz=430000000,
stop_hz=440000000,
points=101
)
```
</TabItem>
</Tabs>
## Smart Tier Selection
Don't want to think about tiers? Use `coordinated_sweep`:
```
coordinated_sweep(
start_hz=144000000,
stop_hz=148000000,
points=101
)
```
It automatically selects the best method based on detected capabilities:
```
┌─────────────────────┐
│ coordinated_sweep() │
└──────────┬──────────┘
┌───────────────┼───────────────┐
│ │ │
▼ │ ▼
┌─────────────────┐ │ ┌─────────────────┐
│ All have │ │ │ All have │
│ external_clock? │───Yes──┘ │ hardware_trigger?│
└────────┬────────┘ │ └────────┬────────┘
│No │ │Yes
└────────────┐ │ ┌────────┘
▼ ▼ ▼
┌─────────────────┐
│ Use Tier 3 │
│ phase_coherent │
└─────────────────┘
│No
┌─────────────────┐
│ Use Tier 2 │
│hardware_trigger │
└─────────────────┘
│No
┌─────────────────┐
│ Use Tier 1 │
│ software │
└─────────────────┘
```
## Device Management
### Discovery
```
list_devices()
```
Returns all connected VNAs with their capabilities:
```json
{
"devices": [
{
"device_id": "0001234567",
"port": "/dev/ttyACM0",
"board": "NanoVNA-H4",
"connected": true,
"capabilities": {
"hardware_trigger": true,
"external_clock": false
}
}
],
"default": "0001234567"
}
```
### Targeting
**Default device**: When one VNA is connected, it's automatically the default. With multiple, set one:
```
set_default_device(device_id="0001234567")
```
**Explicit targeting**: Override default with `device_id` on any tool:
```
scan(device_id="0009876543", start_hz=144e6, stop_hz=148e6)
```
### Hot-plug Detection
After connecting/disconnecting VNAs:
```
refresh_devices()
```
## Common Workflows
### A/B Antenna Comparison
Connect two antennas to two VNAs, then:
```
multi_antenna_compare(
device_ids=["antenna_a_vna", "antenna_b_vna"],
start_hz=144000000,
stop_hz=148000000
)
```
Returns:
| Metric | Antenna A | Antenna B |
|--------|-----------|-----------|
| Min SWR | 1.15 | 1.32 |
| Resonance | 145.2 MHz | 144.8 MHz |
| Bandwidth | 4.1 MHz | 3.2 MHz |
### Long Cable Path Loss
Measure a cable too long to keep both ends near one VNA:
```
differential_s21(
source_device_id="near_end_vna",
receiver_device_id="far_end_vna",
start_hz=1000000,
stop_hz=500000000
)
```
The source VNA outputs CW while the receiver measures. Returns S21 magnitude at each frequency.
## Guided Prompts
mcnanovna includes prompts for multi-VNA workflows:
| Prompt | Description |
|--------|-------------|
| `multi_device_setup` | Initial device discovery and configuration |
| `hardware_trigger_setup` | Tier 2 wiring and testing guide |
| `phase_coherent_setup` | Tier 3 clock reference setup |
## See Also
- [Multi-VNA Tutorial](/tutorials/multi-vna-basics/) — Hands-on first multi-VNA measurement
- [Hardware Trigger Wiring](/hardware/trigger-wiring/) — Tier 2 physical setup
- [External Clock Modification](/hardware/external-clock/) — Tier 3 clock distribution
- [Tool Reference](/mcnanovna/tools/) — All coordination tools

View File

@ -5,7 +5,7 @@ description: MCP server for NanoVNA-H vector network analyzers
import { Aside } from '@astrojs/starlight/components';
mcnanovna gives LLMs direct control of NanoVNA-H vector network analyzers over USB serial. It exposes 78 MCP tools for frequency sweeps, S-parameter measurements, calibration, LCD capture, RF analysis, and 3D antenna radiation pattern visualization.
mcnanovna gives LLMs direct control of NanoVNA-H vector network analyzers over USB serial. It exposes 91 MCP tools for frequency sweeps, S-parameter measurements, calibration, LCD capture, RF analysis, 3D antenna radiation pattern visualization, and multi-VNA coordination.
## Capabilities
@ -34,6 +34,20 @@ mcnanovna gives LLMs direct control of NanoVNA-H vector network analyzers over U
- Pattern import from CSV, EMCAR, NEC2, Touchstone S1P
- Optional Three.js web viewer
### Multi-VNA Coordination
- Control multiple NanoVNA devices simultaneously
- Three synchronization tiers with increasing precision
- Device targeting via optional `device_id` parameter on all tools
- Automatic sync method selection with `coordinated_sweep`
| Tier | Method | Precision | Requirements |
|------|--------|-----------|--------------|
| 1 | Software | ±2-5ms | None (stock firmware) |
| 2 | Hardware Trigger | ±10-50µs | Custom firmware + trigger wire |
| 3 | Phase Coherent | ±1° | External clock + Tier 2 |
See [Multi-VNA Coordination](/mcnanovna/multi-vna/) for detailed tier comparison and workflow guides.
## Supported Hardware
| Device | Frequency Range | Notes |
@ -57,21 +71,23 @@ Other NanoVNA variants using the same USB serial protocol (VID 0x0483, PID 0x574
│ │ mcnanovna server │ │
│ │ ┌─────────┐ ┌────────────┐ ┌─────────────┐ │ │
│ │ │ tools/ │ │ protocol.py│ │calculations │ │ │
│ │ │ 8 mixins│ │ USB serial│ │ S-param │ │ │
│ │ │ 9 mixins│ │ USB serial│ │ S-param │ │ │
│ │ └────┬────┘ └─────┬──────┘ │ math │ │ │
│ │ │ │ └─────────────┘ │ │
│ │ ▼ ▼ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ NanoVNA class │ │ │
│ │ │ (connection lifecycle, auto-reconnect) │ │ │
│ │ │ DeviceRegistry (multi-VNA) │ │ │
│ │ │ ┌────────────┐ ┌────────────┐ │ │ │
│ │ │ │ NanoVNA #1 │ ... │ NanoVNA #N │ │ │ │
│ │ │ └────────────┘ └────────────┘ │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ USB Serial │
│ ▼ │
┌──────────────────┐
│ NanoVNA-H │
└──────────────────┘
┌──────────────┐ ┌──────────────┐
│ NanoVNA-H #1 │...│ NanoVNA-H #N │
└──────────────┘ └──────────────┘
└─────────────────────────────────────────────────────────┘
```

View File

@ -1,9 +1,9 @@
---
title: Tool Reference
description: All 78 mcnanovna MCP tools
description: All 91 mcnanovna MCP tools
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
import { Tabs, TabItem, Aside } from '@astrojs/starlight/components';
## Measurement Tools
@ -123,6 +123,56 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
| `import_pattern_s1p` | Import from Touchstone S1P |
| `list_pattern_formats` | List supported import formats |
## Coordination Tools
Manage and synchronize multiple NanoVNA devices simultaneously.
### Device Management
| Tool | Description |
|------|-------------|
| `list_devices` | List all connected VNAs with status and capabilities |
| `refresh_devices` | Re-scan USB ports for hot-plugged devices |
| `set_default_device` | Set default VNA for subsequent calls |
| `clear_default_device` | Clear default, require explicit device_id |
| `detect_capabilities` | Check hardware trigger and clock support |
### Tier 1: Software Synchronization
| Tool | Description |
|------|-------------|
| `sync_sweep` | Software-coordinated parallel sweep (±2-5ms) |
| `multi_antenna_compare` | Compare S11 across multiple antennas |
| `differential_s21` | Two-VNA transmission measurement |
### Tier 2: Hardware Trigger
Requires custom firmware and physical trigger wiring. See [VNA Trigger Wiring](/hardware/trigger-wiring/) for hardware setup.
| Tool | Description |
|------|-------------|
| `set_trigger_mode` | Configure hardware trigger mode |
| `hardware_sync_sweep` | Hardware-triggered sync sweep (±10-50µs) |
### Tier 3: Phase Coherent
Requires external 26 MHz clock reference plus Tier 2. See [VNA External Clock](/hardware/external-clock/) for hardware modification guide.
| Tool | Description |
|------|-------------|
| `set_clock_reference` | Set internal/external clock reference |
| `phase_coherent_sweep` | Phase-coherent sweep with shared clock (±1°) |
### Smart Coordination
| Tool | Description |
|------|-------------|
| `coordinated_sweep` | Auto-selects best available sync method |
<Aside type="tip">
All 78 original tools accept an optional `device_id` parameter to target a specific VNA. Without it, commands go to the default device (or the only connected device).
</Aside>
## Example Usage
<Tabs>
@ -156,4 +206,20 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
Calls: save(0)
```
</TabItem>
<TabItem label="Multi-VNA">
```
User: Compare my two 2m antennas simultaneously
Calls: list_devices()
# Returns: [{id: "0001234567", ...}, {id: "0007654321", ...}]
Calls: sync_sweep(
device_ids=["0001234567", "0007654321"],
start_hz=144000000,
stop_hz=148000000,
points=101
)
Calls: multi_antenna_compare()
```
</TabItem>
</Tabs>

View File

@ -0,0 +1,222 @@
---
title: Your First Multi-VNA Measurement
description: Compare antennas using two NanoVNAs simultaneously
---
import { Steps, Tabs, TabItem, Aside } from '@astrojs/starlight/components';
In this tutorial, you'll use two NanoVNA devices together to measure and compare two antennas side-by-side. By the end, you'll understand device discovery, targeting, and software-synchronized sweeps.
## What You'll Learn
- Discover all connected VNAs
- Target specific devices
- Run synchronized sweeps
- Compare antenna performance
## Prerequisites
- Two NanoVNA-H devices connected via USB
- Two antennas to compare (or one antenna with two feedlines)
- mcnanovna MCP server installed
<Aside type="note">
This tutorial uses Tier 1 (software) synchronization, which works with any NanoVNA firmware. No modifications needed.
</Aside>
## Discover Your Devices
<Steps>
1. **Connect both VNAs**
Plug both NanoVNA devices into USB ports. Each needs its own port.
2. **List devices**
Say: "List all connected NanoVNA devices"
The assistant calls `list_devices()` and returns something like:
```json
{
"devices": [
{"device_id": "0001234567", "port": "/dev/ttyACM0", "board": "NanoVNA-H4"},
{"device_id": "0009876543", "port": "/dev/ttyACM1", "board": "NanoVNA-H"}
],
"default": "0001234567",
"count": 2
}
```
3. **Note the device IDs**
Each VNA has a unique `device_id` (its serial number or port path). Write these down:
| Device ID | Connected Antenna |
|-----------|-------------------|
| 0001234567 | Antenna A |
| 0009876543 | Antenna B |
</Steps>
## Set Up Device Targeting
With multiple VNAs, you have two options for targeting:
### Option 1: Set a Default
If you'll mostly use one VNA:
Say: "Set device 0001234567 as the default"
Now all single-device tools (scan, analyze, etc.) will target that VNA unless you specify otherwise.
### Option 2: Specify Each Time
Add `device_id` to any tool call:
Say: "Scan from 144 to 148 MHz on device 0009876543"
<Aside type="tip">
When only one VNA is connected, it becomes the default automatically. Multi-VNA targeting only matters when you have multiple devices.
</Aside>
## Calibrate Each VNA
<Steps>
1. **Calibrate the first VNA**
Say: "Calibrate device 0001234567 for 144 to 148 MHz"
Follow the SOLT calibration steps: load, open, short, through.
Say: "Save calibration to slot 1"
2. **Calibrate the second VNA**
Say: "Calibrate device 0009876543 for 144 to 148 MHz"
Repeat the same procedure with the second VNA's calibration standards.
Say: "Save calibration to slot 1"
</Steps>
<Aside type="caution">
Use the same frequency range for both VNAs. Calibrate each with its own cables and adapters—the ones you'll use for measurement.
</Aside>
## Run a Synchronized Sweep
Now connect your antennas—one to each VNA's Port 1.
<Steps>
1. **Run sync_sweep**
Say: "Run a synchronized sweep on both VNAs from 144 to 148 MHz"
The assistant calls:
```
sync_sweep(
device_ids=["0001234567", "0009876543"],
start_hz=144000000,
stop_hz=148000000,
points=101
)
```
2. **Review the results**
You'll get S11 data from both devices, swept at the same time (within ±2-5ms).
</Steps>
## Compare Antenna Performance
<Steps>
1. **Run multi_antenna_compare**
Say: "Compare my two antennas on the 2m band"
The assistant calls `multi_antenna_compare()` and returns a comparison table:
| Metric | Antenna A (0001234567) | Antenna B (0009876543) |
|--------|------------------------|------------------------|
| Min SWR | 1.15 | 1.32 |
| Resonance | 145.2 MHz | 144.8 MHz |
| Bandwidth (< 2:1) | 4.1 MHz | 3.2 MHz |
| Z at resonance | 48 + j2 Ω | 42 - j8 Ω |
2. **Interpret the results**
- **Min SWR**: Lower is better. Antenna A has better match.
- **Resonance**: Where SWR is lowest. Neither is at band center.
- **Bandwidth**: Wider is more versatile. Antenna A has broader coverage.
- **Z at resonance**: Closer to 50 Ω is better. Both are reasonable.
</Steps>
## Understanding the Results
### What Sync Sweep Gives You
Software synchronization (Tier 1) starts both sweeps within 2-5ms of each other. This is adequate for:
- Antenna comparison
- Signal level measurements
- SWR/impedance analysis
It's **not** precise enough for:
- Phase measurements between devices
- Antenna array characterization
- MIMO testing
For those, you'll need [hardware trigger (Tier 2)](/hardware/trigger-wiring/) or [phase coherent (Tier 3)](/hardware/external-clock/).
### Device Capabilities
Check what sync methods each device supports:
Say: "Check capabilities of device 0001234567"
```json
{
"device_id": "0001234567",
"capabilities": {
"hardware_trigger": false,
"external_clock": false
},
"tier": 1
}
```
Stock firmware shows Tier 1 only. Custom firmware enables Tier 2/3.
## Troubleshooting
### Only one device shows up
1. Check USB connections
2. Try different USB ports (avoid hubs)
3. Run `refresh_devices()` to re-scan
4. Check permissions: `sudo usermod -aG dialout $USER` (Linux)
### Device IDs keep changing
Port paths like `/dev/ttyACM0` can change on reconnect. If available, use the serial number (e.g., `0001234567`) instead—it's stable across reconnects.
### Timing concerns
Tier 1's ±2-5ms is sufficient for most comparisons. If you see inconsistent results, ensure:
- Both VNAs have stable connections
- Neither is being accessed by another program
- USB host isn't under heavy load
## Next Steps
- [Multi-VNA Coordination](/mcnanovna/multi-vna/) — Understand all three synchronization tiers
- [Hardware Trigger Wiring](/hardware/trigger-wiring/) — Achieve ±10-50µs precision
- [Tool Reference](/mcnanovna/tools/) — All coordination tools