In the last post, we looked at creating a 15.75 kilometre SSH link with two RNodes acting as wireless network cards. Today, we’re going to be a bit more passive. Using just a single RNode, we’ll put the device into promiscuous mode to sniff LoRa packets and dump them to a computer.

For this to work, the RNode must be in host-controlled mode. This is the default, but if you have been following along with the previous examples, now is a good time to use the RNode Config Utility to put the device back into host-controlled mode. Remember to replace /dev/ttyUSB0 with the serial port your device is attached to.

./rnodeconf /dev/ttyUSB0 -N

The device is now ready to listen for packets! We’ll use a program made specifically for this purpose, called LoRaMon. If you already have Python3 and pip installed, you can install LoRaMon very easily with pip:

pip3 install loramon

You can also clone it directly from my GitHub repository if you prefer that:

git clone

Once you’ve got it installed, you can run loramon without any arguments to display the usage information.

usage: loramon [-h] [-C] [-W directory] [--freq Hz] [--bw Hz] [--txp dBm]
               [--sf factor] [--cr rate]
LoRa packet sniffer for RNode hardware.
positional arguments:
  port           Serial port where RNode is attached
optional arguments:
  -h, --help     show this help message and exit
  -C, --console  Print captured packets to the console
  -W directory   Write captured packets to a directory
  --freq Hz      Frequency in Hz
  --bw Hz        Bandwidth in Hze
  --txp dBm      TX power in dBm
  --sf factor    Spreading factor
  --cr rate      Coding rate

As you can see, we’ll need to specify the serial port the RNode is connected to, and what frequency we will listen on, as well as which LoRa parameters we are using. It’s worth noting that the coding rate (–cr flag) is primarily used to specify the coding rate if LoRaMon is used to inject packets. RNode will pick up packets with any coding rate, but will send them out as specified by the parameter.

So let’s make LoRaMon listen on 868.1 MHz, with a 125 KHz bandwidth, and spreading factor 7. We just set the coding rate to the default of 5. I’ll also make LoRaMon dump packets to the directory “loracapture” by using the -W flag:

./loramon /dev/ttyUSB0 -C -W loracapture --freq 868100000 --bw 125000 --sf 7 --cr 5

You should see something similar to this:

[2018-07-01 21:13:59] Opening serial port /dev/tty.usbserial-DN03E0FS...
[2018-07-01 21:14:02] RNode connected
[2018-07-01 21:14:02] Firmware version: 1.06
[2018-07-01 21:14:02] Radio reporting frequency is 868.1 MHz
[2018-07-01 21:14:02] Radio reporting bandwidth is 125.0 KHz
[2018-07-01 21:14:02] Radio reporting TX power is 2 dBm
[2018-07-01 21:14:02] Radio reporting spreading factor is 7
[2018-07-01 21:14:02] Radio reporting coding rate is 5
[2018-07-01 21:14:02] RNode in LoRa promiscuous mode and listening

That’s it! The RNode is now in promiscuous mode, and sniffing out LoRa packets. All captured packets will be dumped to the console, and also written to the specified directory.

6 thoughts on “LoRa packet sniffing with RNode

  1. hello,
    I m trying to use the packet sniffing feature with a Lora tracker sending data to a local lora GW but I can’t see any packet being sniffed.
    The setup works well I get to this :

    rnodeconf /dev/tty.usbserial-D307GM8R -N
    [2020-11-07 13:04:23] Opening serial port /dev/tty.usbserial-D307GM8R…
    [2020-11-07 13:04:26] Device connected
    [2020-11-07 13:04:26] Firmware version: 1.16
    [2020-11-07 13:04:26] Reading EEPROM…
    [2020-11-07 13:04:26] EEPROM checksum correct
    [2020-11-07 13:04:26] Device signature validated
    [2020-11-07 13:04:26] Device set to normal (host-controlled) operating mode
    (base) seller@MBP-de-Seller rnodeconfigutil % loramon /dev/tty.usbserial-D307GM8R –freq 868100000 –bw 125000 –sf 11 –cr 5 -C -W loracapture
    [2020-11-07 13:04:38] Opening serial port /dev/tty.usbserial-D307GM8R…
    [2020-11-07 13:04:41] RNode connected
    [2020-11-07 13:04:41] Firmware version: 1.16
    [2020-11-07 13:04:41] Radio reporting frequency is 868.1 MHz
    [2020-11-07 13:04:41] Radio reporting bandwidth is 125.0 KHz
    [2020-11-07 13:04:41] Radio reporting TX power is 2 dBm
    [2020-11-07 13:04:41] Radio reporting spreading factor is 11
    [2020-11-07 13:04:41] Radio reporting coding rate is 5
    [2020-11-07 13:04:41] RNode in LoRa promiscuous mode and listening

    but even though I can see from the gw console that some packets are sent with those parameters, it doesn’t show up on the console (nor to the specified location).
    I have updated the FW . I can see the device flashing blue from time to time.

    Any idea what might be the problem?

    1. Can you doublecheck that the Frequency, Bandwidth and Spreading Factor is identical to the transmit settings on the gateway/tracker (depending on what you want to monitor). Be aware that your setup might use different uplink and downlink frequencies and settings, so that might be the problem.

      1. Hello,
        I have doublechecked and it worked with one error message : [2020-11-11 16:57:13] Error while writing packet to disk,
        I could see the output on the console though.
        What is strange is that the packet captured according to the GW data was received by the GW on a different frequency than the frequency I was listening on the rnode. is that possible that they are slightly off?
        Thank you

        1. I have made some follow up test and I’m able to capture the packets via the console.
          I still get an error when trying the -W option :
          Error while writing packet to disk
          The file “2020-11-15_12-36-45.902348.pkt” is created but empty and then I get the error message.
          I have checked the directory access rights and it seems correct.
          Thanks for your help

          1. Thanks for the info! I’m going to look into this, as it seems to be a bug with LoRaMon. If I need more info to reproduce it, I’ll get in touch 🙂

  2. Hello,

    I think I found where the issue is.
    In the file , line #403

    replace :
    file = open(rnode_instance.write_dir+”/”+filename, “w”)

    file = open(rnode_instance.write_dir+”/”+filename, “wb”)

    and it will work fine.


Leave a Reply

Your email address will not be published. Required fields are marked *