Stock repeater firmware β per-node signal can't be measured. Sorry.
The packet log does report SNR/RSSI, but with no usable identity for it:
Flood packets are logged with their original sender, not the neighbour your
repeater actually heard β so the signal can't be attributed to anyone.
Direct packets are almost always your own companion sitting right next to the repeater
(always strong) β useless for range.
There is no packet path and no per-sender RSSI, so incoming traffic can only be grouped
as direct / unknown.
What you can do:
Use Discover nodes β it lists the repeaters yours hears directly, identified,
but SNR only (no RSSI).
Flash the repeater with a MESH_PACKET_LOGGING firmware build. It emits RAW packets this
app decodes to recover the real last hop together with SNR and RSSI β the only way to get
full per-node signal data from a repeater.
Connect to a MeshCore companion device via Bluetooth or USB to start monitoring RX logs.
?Filter applied
Sends a discovery request β nearby nodes reply with their public key and the SNR they measured for your signal.?
Seen repeaters
Repeater?
RX
Max SNR
Last SNR
Max RSSI
Last RSSI
Last seen
Waiting for dataβ¦
SNR history?
RSSI history?
Signal 3D map?
Drag to pan Β· scroll/pinch to zoom Β· two-finger twist to tilt/rotate
Location not enabled.
Allow location and capture some packets to populate the 3D map.
Received packets?
?Filter applied
Debug
Inject a fake RX entry to test prefix-collision handling. Hex is interpreted high-byte first, the same way path IDs arrive from the decoder. Examples: 5E (1-byte), 5E9F, 5E9F1234, or direct.
Connect over WiFi
Enter the IP address and TCP port of a MeshCore companion running the WiFi firmware.
Filtered to
?
Selected
MeshCore Signal Tester
Connects to a MeshCore companion radio (Bluetooth, USB, or β in the Android app β WiFi) or a MeshCore repeater (USB) and monitors incoming LoRa mesh packets in real time β tracking which packets were received, via which repeaters, and with what signal quality. The Discover nodes button sends an active discovery request so nearby nodes announce themselves and report the signal quality they measured for you; everything else is passive listening.
Getting started
Click Connect Bluetooth (or Connect USB for a wired serial connection, or Connect WiFi in the Android app) and select your MeshCore device. Packet data appears automatically as the device picks up LoRa traffic. Previously used devices (Bluetooth, USB and WiFi) appear as quick-connect buttons. Click any section title to collapse or expand that section. Use βΉ Stop / βΆ Resume to suspend data collection without disconnecting β collection pauses automatically on disconnect and resumes on reconnect.
Use Import CSV / Export CSV to save the captured packets to a file and reload them later, and Clear data to wipe the current session. If an established connection drops unexpectedly β cable unplugged, device reset, or out of range β a full-screen alarm warns you that data collection has stopped (a deliberate disconnect won't trigger it).
What you can connect to
The app auto-detects the device β you don't pick a type. A companion radio (Bluetooth, USB, or WiFi in the Android app) pushes every received packet fully decoded, which is the richest source. A repeater (USB only) instead exposes a text CLI the app drives; how much it can report depends on its firmware (see below).
Key concepts
Repeater
direct means a flood-routed packet was received at the first hop β no intermediate repeater. Otherwise the ID shown is the last mesh node that forwarded the packet toward your device.
SNR
Signal-to-Noise Ratio in dB. Positive = signal is above the noise floor. LoRa can decode even at negative SNR (down to about β20 dB).
RSSI
Received Signal Strength Indicator β radio power in dBm. Less negative = stronger. β70 dBm: excellent Β· β120 dBm: very weak.
Noise floor
Background RF noise level, estimated as RSSI β SNR. Shown as the shaded area on the RSSI chart.
Selecting and filtering repeaters
Click any repeater row in Seen Repeaters, a column header in Received Packets, a dot in the 3D map, or a dot in the charts to select that repeater. The selection dims all other repeaters across every view simultaneously. A notice appears top-right with options to filter to that repeater only or deselect. Click the same item again to deselect.
Use Filter repeaters to restrict all views to one or more repeaters by ID prefix (comma-separated). Filtering is more persistent than selection β it stays active until you clear it. While a filter is active, a notice top-right shows which repeater is filtered and lets you clear it.
Repeater ID prefix resolution
Path IDs can arrive as 1β3 byte prefixes of the full 4-byte node ID. The app resolves them progressively:
When a longer ID arrives for a node already seen as a shorter prefix, the column is promoted to the longer label (e.g. 12 β 1234).
If a short prefix turns out to be ambiguous β it matches two or more known distinct nodes β those ambiguous packets are grouped under a combined label (e.g. 1234/1289) while each specific node keeps its own column.
Each additional sibling is added to the combined label (e.g. 1111/1122/1133). The combined column always represents packets whose exact origin is uncertain among those nodes.
If a more-precise ID later arrives for one of the siblings, its part of the label is updated too (e.g. 1234/1289 β 123456/1289).
Display & appearance
Theme β the βοΈ / π button toggles light and dark mode; your choice is remembered.
Text size β scales the whole interface (Small β Larger) for readability on small or high-DPI screens; remembered across sessions.
2D graphs dot size β scales the points drawn on the SNR and RSSI charts.
3D map dot size β set separately in the 3D map's β menu, alongside the map source, guide lines, and location marker.
Device location β the 3D map's β menu can show the connected device's own position (a blue antenna marker), when the companion or repeater reports one. Off by default. A companion shows its current position β its live onboard-GPS fix if it has one, otherwise its configured advert position; a repeater shows its get lat/get lon setting. Nothing appears if the device has no position set. While the marker is shown, a connected companion's position is re-read about once a second, so one with live GPS tracks your movement; a repeater's position is static and read once on connect.
Repeater firmware: stock vs. logging build
How much a repeater can report depends on its firmware. Stock builds expose only the packet log and neighbour table, so forwarded packets can't be tied to a specific last hop β they show as direct / unknown, and per-node signal comes only from the neighbour table (SNR, no RSSI). A MESH_PACKET_LOGGING build streams raw packets the app decodes for the real last-hop ID with both SNR and RSSI, like a companion β the build to use for a measurement node. Full details are in the project README.
Android app
A native Android wrapper is available for field use. It packages this web app into an APK so it works fully offline β no browser needed. It also adds a Connect WiFi option β a raw TCP link to a companion running the WiFi firmware β which a browser can't do. The radio link (Bluetooth, USB or WiFi) and the GPS work run in a native foreground service, so data collection keeps going with the screen off or the app in the background β you can drop the phone in your pocket and keep mapping signal as you move. A plain browser tab would suspend and stop collecting once the screen turns off, which is exactly what this avoids.
The Keep screen on toggle is a separate convenience for when you do want the display to stay lit β e.g. to watch packets arrive live while walking. It only affects the screen, not collection.
This is a hobby project and the author doesn't own an iOS device to build or test on β sorry.
About
MeshCore Signal Tester was created by AleΕ‘ Janda. If you have feedback, found a bug, or just want to say hi β feel free to reach out at ales.janda@kyblsoft.cz.
The app was developed with the help of Claude Code.
β οΈ
Device disconnected
The connection to your MeshCore device was lost unexpectedly. Data collection has stopped.