Pluto Drone Monitor & Control Demo

Attention

Work-in-progress

Overview

This demo shows how to use an ADALM-PLUTO (Pluto SDR) as a passive spectrum monitor for common UAV/UAS control and video bands (2.4 GHz and 5.8 GHz). It provides a real-time spectrogram, basic signal classification (e.g., OFDM-ish vs narrowband/RC-like), and a simple event log. The goal is to demonstrate ADEF-relevant Counter-UAS awareness: seeing band activity, identifying likely signal types, and discussing next steps such as zooming, hopping detection, or AoA with additional hardware.

Hardware Setup

Required - 1× ADI ADALM-PLUTO (Pluto SDR) - PC/laptop (Windows, Linux, or macOS) - USB cable (micro-USB to USB-A/C as appropriate) - Antenna for 2.4 GHz (and optionally 5.8 GHz) with SMA adapter as needed

Recommended - Directional/panel antenna (2.4/5.8 GHz) for better SNR and spatial discrimination - Fixed attenuators (e.g., 20–40 dB) for close-range/near-field captures - USB ferrite choke to reduce conducted noise - Tripod or stand for antenna

Connections 1. Connect the antenna to Pluto SDR RX port (SMA). 2. Connect Pluto to the host PC via USB. 3. (Optional) If using Ethernet-over-USB, ensure the Pluto enumerates at 192.168.2.1.

Power-up & Indicators - The Pluto powers from USB. After enumeration, status LEDs should indicate activity. - If using a powered hub, ensure stable 5 V supply.

Jumpers/Switches - Use factory defaults unless you have a specific configuration. - Ensure the RF shield and connectors are secure; no special jumpers are required.

Software Setup

Get the code - Clone or copy the demo scripts into a working folder (e.g., pluto_uav_demo/). - Example files referenced below: - uav_monitor.py (real-time scan/classifier) - requirements.txt (Python dependencies)

Install prerequisites - Python 3.9–3.12 recommended - Install Pluto/LibIIO support on your OS (driver/udev rules where applicable)

Create environment and install

# (optional) create a venv
python -m venv .venv

# activate:  Windows PowerShell:
.\.venv\Scripts\Activate.ps1

#  Linux/macOS:
source .venv/bin/activate

# install dependencies
pip install -r requirements.txt
# or minimal:
pip install pyadi-iio numpy matplotlib

requirements.txt (example)

pyadi-iio
numpy
matplotlib
# optional for GUI dashboards later:
# pyqtgraph
# flask
# flask-socketio

Running the Demo

Quick start (2.4 GHz passive scan & classify)

# USB connection (defaults to 192.168.2.1 via USB/Ethernet gadget)
python uav_monitor.py --band 2.4 --device ip:192.168.2.1

Common options - --band {2.4,5.8} : choose target band - --device URI : e.g., ip:192.168.2.1 or usb:1.0.5 - --sr SR : sample rate in S/s for scan mode (default ~3e6) - --rf-bw BW : analog filter bandwidth (default ~3e6) - --step STEP : scan step in Hz (default ~2e6) - --fft N : FFT size (default 2048) - --avg ALPHA : EWMA average (0–1, default 0.6)

Example commands

# 5.8 GHz band with slightly larger step and FFT
python uav_monitor.py --band 5.8 --step 3000000 --fft 4096

# Force USB backend URI
python uav_monitor.py --band 2.4 --device usb:1.0.5

# Use wider analog BW and faster scan integration
python uav_monitor.py --band 2.4 --rf-bw 4000000 --int 0.05

What the script does - Tunes Pluto across the selected band in small windows (scan mode) - Computes PSD (FFT) and updates: - A rolling spectrogram (time vs frequency offset) - A live PSD trace for the current window - Runs a simple classifier: - OFDM-ish (flat, wider OBW → likely Wi-Fi/video) - Narrowband (sharp, small OBW → likely RC/telemetry) - Intermediate/Unknown - Prints a timestamped log of strong detections

Expected Results

On success you should see: - A live spectrogram (upper plot) where active channels appear as bright bands - A PSD line (lower plot) with a visible peak when a signal is in the current window - A status line with: - Center frequency (CF) - Peak offset - Estimated occupied bandwidth (OBW) - Spectral flatness - Classification label

Sample terminal log

[14:22:31.124Z] CF=2438.000 MHz  Peak=2439.002 MHz  OBW=1.42 MHz  Flat=0.67  Class=OFDM-ish (Wi-Fi/video?)
[14:22:32.211Z] CF=2462.000 MHz  Peak=2461.998 MHz  OBW=0.09 MHz  Flat=0.21  Class=Narrowband (RC/telemetry?)

If you switch to a directional antenna and point at a controller or FPV link: - OFDM-like channels (video/Wi-Fi) will appear as broader, flatter plateaus - RC/telemetry will appear as narrower, sharp peaks

Troubleshooting (Optional)

Pluto not found / permission errors - Windows: install ADI/LibIIO drivers; replug USB; try different port/cable - Linux: add udev rules for libiio; run without sudo once rules are applied - Verify URI: ip:192.168.2.1 usually works over USB-Ethernet gadget

Flat/noisy spectrum, no signals - Check antenna type and frequency band - Move closer to the source (or use a directional antenna) - Increase integration time (--int) or averaging (--avg) - Verify local RF environment actually has activity at that time

Clipping / overload near strong sources - Add attenuation (10–40 dB) - Use “slow_attack” AGC (default) or try manual RX gain

Choppy UI / high CPU - Reduce FFT size (e.g., 1024) - Increase scan step to fewer windows - Close other heavy applications

Plots don’t show (headless) - Ensure a local display backend (matplotlib) - On WSL/SSH, use X11 forwarding or run on native OS

Resources

  • ADALM-PLUTO (Pluto SDR) product page and user guides

  • LibIIO / pyadi-iio documentation

  • Example SDR spectrum/waterfall tutorials (GNU Radio, matplotlib)

  • Antenna references for 2.4/5.8 GHz monitoring

  • (Optional extensions)

    • Zoom-mode wideband capture (e.g., ~20 MS/s) for full Wi-Fi channel view

    • Frequency-hopping (FH-like) detector using short-dwell clustering

    • Flask/Socket.IO dashboard with detection feed and CSV logging

    • Two-channel AoA with external front-end (e.g., phased array/beamformer)