Forked from colonelpanichacks/drone-mesh-mapper Enhanced by Clint (cyberrover.ca)
A distributed drone Remote ID detection and mapping system using ESP32 sensor nodes, Meshtastic LoRa mesh networking, and a Raspberry Pi base station with real-time web UI.
REMOTE NODES (field) BASE STATION (RPi)
┌──────────────────────────┐ ┌───────────────────────────┐
│ XIAO ESP32S3 │ │ Heltec V3 (Meshtastic) │
│ WiFi + BLE drone detect │ │ │ USB │
│ + GY-NEO6MV2 GPS │ LoRa 915MHz │ ▼ │
│ │ UART │ ─────────────> │ mesh_bridge.py (protobuf) │
│ ▼ │ multi-hop │ │ PTY │
│ Heltec V3 / Tracker V1.1 │ │ ▼ │
│ (Meshtastic mesh radio) │ │ mesh-mapper.py :5000 │
└──────────────────────────┘ │ real-time web map │
└───────────────────────────┘
- Dual-core WiFi + BLE Open Drone ID scanning
- OUI-based manufacturer detection (DJI, Parrot, Skydio, Autel, Yuneec + 10 more)
- SSID pattern matching for non-ODID-compliant drones
- WiFi channel hopping (ch1/6/11, 80% dwell on ch6 for NAN)
- GPS support (GY-NEO6MV2) — node position in every detection
- FreeRTOS mutex thread safety on shared data
- Detection method bitmask (
detectfield) and OUI hint in JSON
- Reads from Heltec V3 via Meshtastic Python API (USB protobuf)
- Creates virtual serial port (PTY) for mesh-mapper.py
- Eliminates the error-prone CP2102-to-GPIO wiring
- Auto-reconnect, health monitoring, stats logging
- Thread safety locks on
tracked_pairsand CSV writes - Removed 9 duplicate function definitions (silent override bug)
- Fixed
--headlessto keep web server running - Reduced polling overhead (restorePaths 200ms → 10s)
- Detection method display in map popups (📡 WiFi NAN, 📶 BLE, 🔍 OUI)
- OUI manufacturer badge in drone sidebar
- Detecting node 📡 markers on the map
/api/node_positionsand/api/observer_positionendpoints--observer-lat/--observer-longCLI args for headless RPi- Enhanced CSV with 6 new columns
See FORK_SETUP.md for the complete step-by-step guide to fork, integrate, and deploy.
cd firmware
pio run -e remote_node -t uploadSee meshtastic-config/README.md
# Install mesh-mapper.py (upstream)
python3 RPI/install_rpi.py --branch main --install-dir /opt/mesh-mapper
# Copy fork enhancements
cp base-station/mesh_bridge.py /opt/mesh-mapper/
cp base-station/start_base_station.py /opt/mesh-mapper/
# Apply patches
python3 patches/patch_mesh_mapper_p0.py /opt/mesh-mapper/mesh-mapper.py
python3 patches/patch_mesh_mapper_r2.py /opt/mesh-mapper/mesh-mapper.py
# Install dependencies
sudo pip3 install meshtastic flask flask-socketio pyserial requests urllib3 --break-system-packages
# Run
python3 /opt/mesh-mapper/start_base_station.py --port /dev/ttyUSB0Web UI at http://<RPi-IP>:5000
drone-mesh-mapper/
├── README.md # This file
├── FORK_SETUP.md # Step-by-step fork/integration guide
├── CHANGELOG.md # Version history
├── .gitignore
├── firmware/ # PlatformIO project (XIAO ESP32S3)
│ ├── platformio.ini # Build config: remote_node + home_node
│ ├── README.md # Build/flash/config guide
│ └── src/
│ ├── main_remote.cpp # Detection firmware (961 lines)
│ ├── main_home.cpp # Optional hardware dedup bridge
│ ├── drone_detect.h # Config, OUI tables, data structures
│ ├── opendroneid.c/h # ODID protocol decoder (Apache-2.0)
│ ├── odid_wifi.h # WiFi ODID frame parsing
│ └── wifi.c # WiFi NAN/beacon helpers
├── base-station/ # RPi base station scripts
│ ├── README.md # Setup guide
│ ├── mesh_bridge.py # Meshtastic USB → PTY bridge
│ └── start_base_station.py # Combined launcher
├── patches/ # Patches for upstream mesh-mapper.py
│ ├── patch_mesh_mapper_p0.py # P0: Thread safety, dedup, headless fix
│ └── patch_mesh_mapper_r2.py # R2: v2.1.0 fields, popups, node markers
├── meshtastic-config/ # Meshtastic setup for all Heltec types
│ └── README.md # V3, Tracker V1.1, base station config
├── docs/ # Additional documentation
│ └── RPi-Base-Station-Setup.md
└── RPI/ # RPi installer (from upstream)
└── install_rpi.py # Fetches mesh-mapper.py from GitHub
| Component | Purpose |
|---|---|
| Seeed XIAO ESP32S3 | Drone detection (WiFi + BLE) |
| Heltec V3 or Tracker V1.1 | Meshtastic LoRa mesh radio |
| GY-NEO6MV2 GPS (optional) | Node position reporting |
| 3 wires | TX, RX, GND between XIAO and Heltec |
| Component | Purpose |
|---|---|
| Raspberry Pi 3B+/4/5 | Runs mesh_bridge.py + mesh-mapper.py |
| Heltec WiFi LoRa 32 V3 | LoRa mesh receiver (USB to RPi) |
| LoRa antenna (915MHz) | Must be connected |
{
"mac": "aa:bb:cc:dd:ee:ff",
"rssi": -62,
"drone_lat": 43.653200,
"drone_long": -79.383200,
"drone_altitude": 120,
"pilot_lat": 43.651000,
"pilot_long": -79.384500,
"basic_id": "FA-12345",
"node_id": "A1B2",
"detect": "odid_nan",
"oui_hint": "DJI",
"node_lat": 43.650000,
"node_long": -79.380000,
"node_alt": 76.2
}MIT (firmware and fork enhancements), Apache-2.0 (OpenDroneID library)
- colonelpanichacks — Original drone-mesh-mapper project
- opendroneid — Open Drone ID protocol library
- Meshtastic — LoRa mesh firmware