// troubleshooting
For each symptom, the cause and what to do about it. Many of these problems give no error message: the radio is just silent, or a board looks dead when only the plug is the wrong way round.
Cause: spreading factor, bandwidth or coding rate differs. A LoRa radio only decodes packets with exactly the same SF, BW and CR. Anything else is noise to it.
Fix: set all nodes to the same four values and check them on the device itself, not only in your config. The frequency may differ by a few hundred Hz (well within 125 kHz), the other three may not. For ReticulumNet: 869.463 MHz, BW 125 kHz, SF8, Coding Rate 5. See LoRa.
# settings the radio actually uses
rnodeconf --info /dev/ttyACM0
Cause: the receiver is overloaded by a transmitter a few centimetres away.
Fix: keep them 1 to 2 metres apart for a test.
Cause: on boards with an external amplifier, such as the Heltec V4, the value in the log is probably the level of the SX1262 before that amplifier. The SX1262 itself goes up to 22 dBm. Configured 28 dBm, txp=19 in the log: the difference is the amplifier gain.
Fix: none. Check that pa=1 is in the TX line: then the amplifier is active.
Cause: --txp only accepts 0 to 17.
Fix: give the value at the rnodeconf prompt, for example with echo.
echo 21 | rnodeconf -T --freq 869463000 --bw 125000 --sf 8 --cr 5 /dev/ttyACM0
Cause: on one side of the USB-C connector a data pin makes no contact. USB-C has two sets of data pins, and which one is used depends on how you insert the plug. A charge only cable gives the same picture.
Fix: turn the plug 180 degrees, before you try other cables or button sequences. If nothing shows up, plug a phone into the same port with the same cable. If the computer sees the phone, the problem is the board.
# live list of USB devices
ls /sys/bus/usb/devices/
# kernel messages while plugging in
sudo dmesg -w
Cause: marginal contact in the connector (EPROTO). This comes before the previous problem: the connector is failing.
Fix: use the other orientation and plug the board straight into the computer, not into a hub. A board that keeps dropping out can take other devices on the same hub down with it.
Cause: another program holds the serial port open: a serial monitor, a script, or a service expecting a different device on the same port. Errors such as "Inflate error" or an MD5 mismatch look like a cable problem, but they are not.
Fix: find the process and stop it while flashing.
lsof /dev/ttyACM0
Cause: the header of the merged image gives a different flash size than the board has, for example 8 MB on a board with 16 MB. If you flash with --flash_size keep, esptool takes over that wrong value. Signs: every restart at the same address, and not a single line from the firmware itself.
Fix: erase the flash, flash with the correct size, and then remove power for a real cold start. Byte 4 of the image should be 4f for 16 MB; for 8 MB it says 3f.
# check the header
od -An -tx1 -N8 firmware_merged.bin
# erase and flash for a board with 16 MB
esptool --chip esp32s3 --port /dev/ttyACM0 erase_flash
esptool --chip esp32s3 --port /dev/ttyACM0 write_flash --flash_mode dio --flash_freq 80m --flash_size 16MB 0x0 firmware_merged.bin
Cause: on many cheap enclosures that port goes to the charging board, with power only and no data lines.
Fix: open the enclosure and use the USB-C on the board itself. On some ready made repeaters, such as the SenseCAP Solar Node P1, the external port is fully wired through.
Cause: voltage drop as soon as WiFi and radio start (brownout).
Fix: use a short cable or a power supply that delivers enough current.
Cause: the firmware compares the hash of its own image with a target hash in EEPROM. When you flash a .uf2, the bootloader does not know the image size, so that target hash was never set. As a result rnodeconf -T seems to work, but the settings are silently not saved.
Fix: set the target hash to the hash the firmware reports itself. After a .uf2 flash that is the hash of zero bytes. Check it after every new flash.
rnodeconf --get-firmware-hash /dev/ttyACM0
rnodeconf --get-target-firmware-hash /dev/ttyACM0
rnodeconf -H e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 /dev/ttyACM0
Cause: you put the port in the config: port = tcp://192.168.1.50:7633. RNS adds port 7633 itself and tries to look up the whole string as a hostname.
Fix: leave the port out.
[[LoRa]]
type = RNodeInterface
port = tcp://192.168.1.50
Cause: pip install upgrades rns and lxmf system wide, including under services that run on a specific version.
Fix: install extra tools in their own virtual environment, or with pipx.
python3 -m venv ~/nomadnet-venv
~/nomadnet-venv/bin/pip install nomadnet
Cause: the time on rmap.world is when the announce was received, not when it was sent. Transport nodes store announces and send them out again when someone requests a path. If the discovery announce comes from a host (rnsd) rather than the board, it also goes out while the radio is off. Values such as battery voltage and noise floor stay at the last known reading.
Fix: do not draw conclusions from the map alone. You only know for sure when the node's address shows up in the log of another node within LoRa range, or when you read out the node itself.
Cause: with most firmware a discovery announce goes out once every six hours, plus one shortly after boot. A node without internet only reaches the map when a transport node with an internet connection passes its announce on.
Fix: enable discovery (discoverable = yes in rnsd, or the advert option in standalone firmware), restart the node for an immediate announce and wait a few minutes. See on the map.
Cause: rmap.world only removes a node after 7 days without an announce. Removing it by hand is not possible.
Fix: wait. If announces keep arriving, check whether a host with discoverable = yes is announcing on behalf of that node.
Cause: rnpath reads the path table, which can be filled by an old announce. A path with an unlikely number of hops is usually such old knowledge. rnprobe only works towards the probe address of a transport node, not its discovery address.
Fix: probe rnstransport.probe with the right address, and do not read a timeout as proof that the node is dead.
rnpath <destination hash>
rnprobe rnstransport.probe <probe hash>
Cause: the project README names a different network and address than the firmware uses.
Fix: hold PRG for more than 5 seconds. Connect to the open WiFi network RTNode-Setup and go to http://10.0.0.1. The portal also opens on a board without a saved configuration, and after 5 resets in a row before the firmware runs stably. Switching off and on with a power switch does not count as a reset. There are no commands over the serial port.
Cause: the firmware loads its tables from flash. paths and dsts therefore say nothing about reception.
Fix: watch the pin counter (packets in). If it goes up, the node is really receiving.
Cause: RTNode has no OTA, and the portal cannot receive firmware.
Fix: flashing only works over USB. For a node in a hard to reach spot, every update means going there.
Cause: a charge LED only tells you there is voltage on the charging circuit. On boards with two identical JST connectors, such as the Heltec V4 (solar panel and battery), a cable on the wrong connector can light the LED while the ESP32 does not start.
Fix: check which connector the cable belongs on, and check whether the node really transmits (TX lines in the log, or reception on another node).
Cause: JST cables come from different manufacturers with the wire order reversed. Reverse polarity on the battery connector destroys the board.
Fix: before connecting, compare the plus and minus on the board with the wire colours. Fitting does not mean it is right.