From 5edac3007ca33453c3e6350eecf2c84dbd471a79 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Wed, 11 Feb 2026 12:54:31 -0700 Subject: [PATCH] =?UTF-8?q?Add=20Di=C3=A1taxis=20documentation=20for=20mul?= =?UTF-8?q?ti-VNA=20features?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- astro.config.mjs | 4 + .../docs/getting-started/quickstart.mdx | 3 +- src/content/docs/hardware/external-clock.mdx | 264 ++++++++++++++ src/content/docs/hardware/trigger-wiring.mdx | 232 +++++++++++++ src/content/docs/mcnanovna/multi-vna.mdx | 321 ++++++++++++++++++ src/content/docs/mcnanovna/overview.mdx | 30 +- src/content/docs/mcnanovna/tools.mdx | 70 +++- .../docs/tutorials/multi-vna-basics.mdx | 222 ++++++++++++ 8 files changed, 1136 insertions(+), 10 deletions(-) create mode 100644 src/content/docs/hardware/external-clock.mdx create mode 100644 src/content/docs/hardware/trigger-wiring.mdx create mode 100644 src/content/docs/mcnanovna/multi-vna.mdx create mode 100644 src/content/docs/tutorials/multi-vna-basics.mdx diff --git a/astro.config.mjs b/astro.config.mjs index ce33e5b..a4d2773 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -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' }, ], }, { diff --git a/src/content/docs/getting-started/quickstart.mdx b/src/content/docs/getting-started/quickstart.mdx index 4e9cef3..60bfb47 100644 --- a/src/content/docs/getting-started/quickstart.mdx +++ b/src/content/docs/getting-started/quickstart.mdx @@ -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 diff --git a/src/content/docs/hardware/external-clock.mdx b/src/content/docs/hardware/external-clock.mdx new file mode 100644 index 0000000..19c3e04 --- /dev/null +++ b/src/content/docs/hardware/external-clock.mdx @@ -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. + + + +## 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 + + + + Phased arrays require known phase relationships between elements. Software or trigger sync alone can't provide phase information. + + + Multiple-input-multiple-output antenna characterization needs coherent phase measurement across all paths. + + + Comparing oscillator phase noise requires a more stable reference than the internal crystal. + + + Verify beam patterns and null depths on multi-element antennas. + + + +## 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 | + + + +## 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 + + +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) + + + +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 + + + +## 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: + + +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. + + + +## 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 diff --git a/src/content/docs/hardware/trigger-wiring.mdx b/src/content/docs/hardware/trigger-wiring.mdx new file mode 100644 index 0000000..a641e3d --- /dev/null +++ b/src/content/docs/hardware/trigger-wiring.mdx @@ -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 + + + +## 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 │ +└─────────────────────────────────────────┘ +``` + + + +## Wiring 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 + + + +## 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 +} +``` + + + +## 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 diff --git a/src/content/docs/mcnanovna/multi-vna.mdx b/src/content/docs/mcnanovna/multi-vna.mdx new file mode 100644 index 0000000..634680b --- /dev/null +++ b/src/content/docs/mcnanovna/multi-vna.mdx @@ -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 + + + + **±2-5ms timing** + + Parallel async execution via software. Works with any firmware, no modifications needed. + + Best for: Antenna comparison, SWR checks, signal level surveys + + + **±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 + + + **±1° phase alignment** + + All VNAs share a 26 MHz clock reference plus hardware trigger. + + Best for: Antenna arrays, MIMO, beamforming, phase noise comparison + + + +## Tier Details + + + + ### 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 + ) + ``` + + + + ### 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 + ) + ``` + + + + ### 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 + ) + ``` + + + +## 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 diff --git a/src/content/docs/mcnanovna/overview.mdx b/src/content/docs/mcnanovna/overview.mdx index 1295484..121e0c2 100644 --- a/src/content/docs/mcnanovna/overview.mdx +++ b/src/content/docs/mcnanovna/overview.mdx @@ -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 │ │ +│ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` diff --git a/src/content/docs/mcnanovna/tools.mdx b/src/content/docs/mcnanovna/tools.mdx index 553d5ab..75dab1b 100644 --- a/src/content/docs/mcnanovna/tools.mdx +++ b/src/content/docs/mcnanovna/tools.mdx @@ -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 | + + + ## Example Usage @@ -156,4 +206,20 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; Calls: save(0) ``` + + ``` + 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() + ``` + diff --git a/src/content/docs/tutorials/multi-vna-basics.mdx b/src/content/docs/tutorials/multi-vna-basics.mdx new file mode 100644 index 0000000..1c3ad2e --- /dev/null +++ b/src/content/docs/tutorials/multi-vna-basics.mdx @@ -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 + + + +## Discover Your Devices + + +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 | + + + +## 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" + + + +## Calibrate Each VNA + + +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" + + + + + +## Run a Synchronized Sweep + +Now connect your antennas—one to each VNA's Port 1. + + +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). + + + +## Compare Antenna Performance + + +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. + + + +## 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