Skip to content

Repository files navigation

EGMESH Coverage Logger

A turnkey LoRa mesh network coverage testing and heatmap tool built for community mesh networks running MeshCore firmware.

Created by Ingo Azarvand for EGMESH.NET Elk Grove, California


What it does

Runs on a Raspberry Pi with a MeshCore companion radio connected via USB. Broadcasts its own WiFi hotspot so you can connect your phone while driving. Live web dashboard shows real-time SNR ping results and GPS coordinates from your phone. After your drive, generate an interactive HTML heatmap overlaid on OpenStreetMap street maps.

How ping measurement works: The logger sends a status request through the mesh via flood routing. The repeater re-broadcasts the packet, and the companion radio captures the echo. The SNR and RSSI from that echo tell you the signal quality between your current location and the repeater.

How GPS works: The logger tries a USB GPS dongle first. If none is detected, it falls back to your phone's browser location via navigator.geolocation. HTTPS (port 5000) is required for the browser to grant geolocation permission — a self-signed cert is generated automatically during install. A plain HTTP server on port 5001 is also available for desktop browsers that don't need GPS.


Hardware required

Component Details
Raspberry Pi Pi 4 or Pi Zero 2 WH (or Pi 5)
MeshCore companion radio RAK4631, Heltec, T-Beam, etc. — USB Companion firmware
MicroSD card 16GB+
Power USB-C power bank or 12V car adapter
GPIO 17 button Momentary pushbutton — switches between hotspot and home WiFi
GPIO 27 green LED Home WiFi indicator — 1kΩ resistor to GND (optional)
GPIO 22 blue LED Hotspot indicator — 1kΩ resistor to GND (optional)

Note: A USB GPS dongle is optional. If connected, it takes priority. If not present, the logger falls back to phone GPS via navigator.geolocation.


EGMESH.NET Radio Settings

Setting Value
Frequency 910.525 MHz
Bandwidth 125 kHz
Spreading Factor SF10
Coding Rate 4/5
TX Power 22 dBm

Files

File Purpose
app.py Flask web app — routes, GPS API, logger loop
mesh_ping.py Serial ping module — auto-detects USB, captures SNR/RSSI
index.html Web dashboard UI
heatmap.py Post-drive heatmap generator
install.sh One-step installer
update.sh Copies repo files to runtime directory and restarts services
wifi_toggle.py GPIO 17 button handler — single press: hotspot, double press: home WiFi
egmesh.service systemd unit — runs logger on boot (HTTPS :5000 + HTTP :5001)
egmesh-wifi.service systemd unit — runs WiFi toggle button handler on boot
cert.pem / key.pem Self-signed TLS cert (generated by install.sh, required for phone GPS)

Quick start

1. Flash USB Companion firmware

Go to flasher.meshcore.co, select your device, choose Companion USB, and flash it.

2. Install

sudo apt-get install -y git
git clone https://github.com/ingo916/egmesh-coverage-logger.git
cd egmesh-coverage-logger
sudo bash install.sh

The install script will:

  • Install Python dependencies
  • Generate a self-signed TLS cert (cert.pem / key.pem) if not present
  • Install and enable egmesh.service (logger, HTTPS :5000 + HTTP :5001)
  • Install and enable egmesh-wifi.service (GPIO 17 WiFi toggle)

3. Plug in the hardware

Connect the companion radio to the Pi via USB. The serial port is auto-detected — no pairing or configuration needed.

4. Configure the radio (one time)

Radio settings are managed from the web UI — no file editing needed.

Open the dashboard and scroll to the Radio Configuration card. Click ↻ Read from Radio to load current settings, adjust the fields, then click ⚡ Write to Radio & Reboot to apply. meshcli is not required.

5. Configure the repeater

Repeaters are managed from the web UI — no file editing needed.

Open the dashboard and scroll to the Repeater card. Either:

  • Scan — lets the Pi query live mesh contacts and pick from the list, or
  • Add manually — enter the repeater name and public key directly

Once added, tap Select to make it the active repeater. The logger will not start until a repeater is selected.

6. Go to the field

Press the GPIO 17 button once — the Pi activates its hotspot via nmcli. Connect your phone to EGMESH-LOGGER (password: egmesh2025), then open Safari and navigate to http://10.42.0.1:5001.

The hotspot IP is 10.42.0.1. No reboot needed — the button switches modes on the fly. Double-press to return to home WiFi.

7. Start

sudo systemctl start egmesh

The service starts automatically on boot. Both ports are active:

Port Protocol Use
5000 HTTPS Phone browser — GPS logging (self-signed cert)
5001 HTTP Desktop browser — no GPS, no cert warning

The Ping Interval dropdown in the Status card lets you set how often the logger pings the repeater (5 / 10 / 15 / 20 / 30 seconds). Changes take effect after the current ping completes — no restart needed.


Connecting from a phone (GPS logging)

  1. Press GPIO 17 once → Pi switches to hotspot mode (3 slow LED blinks = ready)
  2. Connect your phone to EGMESH-LOGGER (password: egmesh2025)
  3. Open Safari and go to http://10.42.0.1:5001 — bookmark this for quick access
  4. For GPS logging, use https://10.42.0.1:5000 instead — accept the cert warning once, then grant location permission
  5. Drive or walk the coverage area

Tip — Add to Home Screen: In Safari, tap the Share button → Add to Home Screen → tap Add. The logger opens full screen from your home screen with one tap. Do this once after your first connection and you never have to type the URL again.

Connecting from a desktop browser

Navigate to http://<pi-ip>:5001 for plain HTTP access. No cert warning. GPS is not available (desktop browsers require HTTPS for geolocation).


WiFi toggle button (GPIO 17)

Press Action
Single press Switch to hotspot mode (10.42.0.1)
Double press Switch back to home WiFi

The egmesh-wifi.service runs wifi_toggle.py on boot and listens for button events.


Status LEDs (optional)

Two external LEDs give visual feedback without needing to see the onboard ACT LED — useful when the Pi is inside a 3D printed case.

LED GPIO Pin Resistor Meaning
Green GPIO 27 Pin 13 1kΩ Home WiFi — slow pulse
Blue GPIO 22 Pin 15 1kΩ Hotspot active — slow pulse

Wiring:

Pin 13 (GPIO 27) ── 1kΩ ── Green LED anode (+) ── cathode (−) ── GND
Pin 15 (GPIO 22) ── 1kΩ ── Blue LED anode  (+) ── cathode (−) ── GND
Pin 11 (GPIO 17) ── Button ── GND
Pin  9  GND      ── shared GND rail

The anode is the longer leg. The cathode is the shorter leg with the flat side on the LED body. LEDs are optional — if not wired, the pins are driven silently with no effect.


Phone GPS API

The phone browser posts location updates directly to the Pi:

POST /api/gps
Content-Type: application/json

{
  "lat": 37.123,
  "lon": -121.456
}

HTTPS on port 5000 is required — modern browsers block navigator.geolocation on plain HTTP pages.


Testing the ping manually

cd /root/egmesh_logger
source venv/bin/activate
python3 mesh_ping.py

You should see:

Trying serial: /dev/ttyACM0 @ 115200 baud
Connected via SERIAL on /dev/ttyACM0
Echo received: snr=10.75  rssi=-41  rtt=0.5s

Generate a heatmap after your drive

cd /root/egmesh_logger
source venv/bin/activate
python heatmap.py

The output file is named to match the source CSV — for example coverage_EG_SE_RAK4631_RPTR_20260326_173000.csv generates heatmap_coverage_EG_SE_RAK4631_RPTR_20260326_173000.html.

You can also generate a heatmap directly from the web UI — tap Generate Heatmap in the Files card. The download is named the same way.

Opens an interactive HTML heatmap overlaid on OpenStreetMap. Internet connection required when viewing.


Troubleshooting

"No MeshCore device found"

Make sure the companion radio is plugged in via USB and running USB Companion firmware (not BLE Companion). Check:

ls /dev/ttyACM* /dev/ttyUSB*

"Device did not respond"

The device may be running BLE Companion firmware instead of USB Companion. Reflash from flasher.meshcore.co — select Companion USB.

0 contacts / repeater not found

The repeater needs to advertise before it appears. Wait a few minutes after the logger starts. If it still doesn't appear, check that the radio frequency and spreading factor match the repeater's config (SF10, 910.525 MHz).

GPS not working on phone

  • Make sure you're on the HTTPS port (5000), not 5001
  • Accept the self-signed cert warning before granting location permission
  • If the browser shows "Location blocked", clear the permission in browser settings and reload

Hotspot IP not reachable

The hotspot IP is 10.42.0.1. Make sure you're connecting to EGMESH-LOGGER and opening http://10.42.0.1:5001 in Safari after connecting.


Updating

To update to the latest version:

cd ~/egmesh-coverage-logger
git pull origin main
sudo bash update.sh

This pulls the latest code from GitHub and deploys it to the runtime directory without reinstalling.


Adapting for your community

Add your repeater via the web UI Repeater card (name + key, or scan from mesh contacts). Set your radio frequency via the web UI Radio Configuration card. Update the header in index.html to your network name.

Common frequencies:

  • US EGMESH.NET: 910.525 MHz / BW125 / SF10 / CR4/5
  • EU868: 868.0 MHz / BW125 / SF9

Changelog

v3.1

  • Phone GPS via navigator.geolocation — USB dongle fallback if present
  • Dual-port server: HTTPS :5000 (phone/GPS) + HTTP :5001 (desktop)
  • Self-signed cert auto-generated by install.sh
  • Radio config via web UI (mc.commands.set_radio()) — meshcli no longer required
  • Repeater manager via web UI (scan or manual add)
  • WiFi toggle button on GPIO 17 (single: hotspot, double: home WiFi)
  • Dual external LEDs — GPIO 27 green (home WiFi), GPIO 22 blue (hotspot)
  • Configurable ping interval (5/10/15/20/30s) in web UI
  • Heatmap filename matches source CSV name
  • egmesh-wifi.service added to install script
  • update.sh added for deploying repo changes to runtime directory
  • Install deploys to /root/egmesh_logger/ (runs as root)
  • Hotspot IP 10.42.0.1
  • SF updated to SF10

v3.0

  • GPIO 17 WiFi toggle (initial implementation)
  • HTTPS support with self-signed cert

v2.x

  • USB GPS dongle support
  • Flask dashboard, heatmap generator
  • meshcli-based radio configuration

Credit and attribution

Created by Ingo Azarvand for EGMESH.NET Volunteer community LoRa mesh network — Elk Grove, California Emergency preparedness and neighborhood resilience.

If you use or adapt this tool, please credit EGMESH.NET and Ingo Azarvand, Elk Grove, CA in your documentation.

https://egmesh.net


License

Copyright (c) 2026 Ingo Azarvand / EGMESH.NET See LICENSE for full terms.

About

Turnkey LoRa mesh network coverage logger and heatmap tool for MeshCore networks. Built for EGMESH.NET — Elk Grove, CA.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages