Sunday, July 27, 2014

nRF24L01+ sniffer - part 2


The requirement to use cheap commodity hardware resulted in the use of a standard Arduino Uno R3 and a single nRF24L01+ module. Some male-female Dupont cables connect the radio to the Arduino. Other Arduino's based on AtMega328 should also work, as long as they have a serial interface to the PC and 3.3V power supply for the radio (the nRF24 I/O pins are 5V tolerant).
Be careful as multiple variants exist of the nRF24L01+ modules, and they don't all use the same layout for the pin header!

Connect the two as follows:
nRF24L01+ module pinout

FunctionArduino Uno pinnRF24L01+

Some applications don't connect the IRQ line, but the sniffer requires it to quickly respond to received packets.
This is what my sniffer looks like:

nRF24 sniffer hardware: Arduino Uno, prototype shield, some Dupont cables and nRF24L01+ module
I didn't have any male-female Dupont cables at hand, so I put a prototype shield inbetween to turn the female headers into male.


The required software is split in the following parts:
  • Sketch running on the Arduino: configures the nRF24 radio and reads any messages received using SPI. It determines the actual payload size for each message and adds a microsecond-resolution timestamp. The messages are buffered in the Atmega328 and sent to the host over a serial connection. It keeps track of the number of lost messages, when the buffer is full.
  • Console application 'Nrf24Sniff.exe' (currently only Windows) which sends configuration data to the Arduino sketch and reads captured packets from the sketch, using a serial connection. The packets received are forwarded in libpcap-format to a named pipe. Wireshark will be instructed to capture from this named pipe (too bad it cannot capture directly from a serial connection).
  • Wireshark to visualize the captured packets, filter them and gather statistics.
  • Wireshark will be extended with one or more plugins (called dissectors, currently only precompiled for Windows) which recognize the nRF24 packet format and take it apart. Protocols which use the nRF24 as transport layer (e.g. MySensors) require a separate dissector.


As you can see in the description above, the console application and Wireshark dissectors are currently only available for Windows (anyone who volunteers to port them to Linux and/or Mac, please do so and let me know).
In the description below I assume you've already downloaded and installed:
  • Wireshark - I used 1.10.8, either 32- or 64-bits
  • Arduino IDE - I used 1.5.6-r2, but I guess any 1.5.x version will do
First download and extract the software I developed as a single zip-file from my GitHub repository.

Arduino sniffer sketch
Either move the contents from the 'Arduino' directory to your Arduino users' directory (c:\users\<yourname>\Documents\Arduino) or copy it elsewhere and instruct the Arduino IDE to use that directory by pointing Preferences -> Sketchbook location to it and restart. I'm a bit reluctant when it comes to copying libraries to your regular users' Arduino directory as it might conflict with any libraries already present. Beware that I changed some small thinks in the RF24 library that's included.
Start the Arduino IDE, load the NRF24_sniff sketch, connect the hardware setup as described above, select the correct board & comport and download the compiled sketch.

The Windows console application which transfers captured data from a serial interface to a named pipe can be found in the 'SerialToPipe/bin/Win32' directory. Just copy this executable somewhere convenient.

Wireshark dissector(s)
Choose the directory matching your 32- or 64-bits install from 'Wireshark/bin/Win32' or 'Wireshark/bin/Win64' and copy the nrf24.dll to the Wireshark plugins directory, e.g. 'c:\Program Files\Wireshark\plugins\1.10.8\'.
Those using the MySensors library can also copy either mysensors1.dll (version 1.3 of the library) or mysensors2.dll (version 1.4beta), depending on the library version you're working with. Better not copy both of them as these are heuristic dissectors which have problems detecting the protocol version reliably.


Connect the hardware running the sniffer sketch to your PC (either using an RS232 connection or a serial-to-USB bridge as present on the Arduino Uno). Note the comport assigned by Windows (the same port as in the Arduino IDE). Assure the Arduino IDE's Serial Monitor is not running as it will block access to the serial port.

Nrf24sniff.exe can be started from a cmd-window. It supports a number of commandline parameters which control its behaviour (display them using 'Nrf24Sniff.exe -h'):

For example, when monitoring MySensors 1.4beta traffic (at non-default 1Mb/s), using the Arduino Uno sniffer connected to com17, I run the tool as follows:

Nrf24Sniff.exe -P17 -c76 -r0 -l5 -p4 -a0xA8A8E1FC00 -C2

The address length is set to 5 bytes (-l5), of which 4 bytes are used as base address (-p4) (Please refer to part 1 of this series for a description of addressing schemes). Passing only the comport would have been sufficient in this case, as the rest of the parameters are all set to defaults.

Now run it:

Keep it running and open another console window to start Wireshark:

This instructs Wireshark to start capturing from interface (-i) \\.\pipe\wireshark (that's the named pipe Nrf24Sniff.exe will be writing to) and to start capturing immediately (-k). More commandline options for Wireshark can be found here.

After Wireshark starts capturing, the Nrf24Sniff console window will display a 'Wait for sniffer to restart' message for a few seconds (at most):

If it hangs here, restart the sniffer hardware manually by pressing the reset button on the Arduino (I'm working on that...).

As Wireshark has no clue how to interpret the data coming through our named pipe, we have to tell it which dissector to use.
Switch over to Wireshark and select Edit -> Preferences.
In the preferences window, open the protocols tree, scroll down and select DLT_USER.
Press the edit button for the 'Encapsulations table' and press New. Enter the data as in the screenshot below:

Press OK, OK, OK. Any packets on air that match the radio configuration should now be captured in Wireshark!

The Nrf24Sniff console shows a count of packets captured and lost:

What's next

The next and last part of this series will dive into the possibilities of Wireshark and the dissectors I've implemented for nRF24 packets and the MySensors protocol.

Aug 3 - statically linked Nrf24sniff.exe, so dependency on msvcr110.dll no longer exists. Should also work on WinXP now.


  1. When i upload the sniffer.ino , i get the error: circularbuffer.h is missed??
    i use arduino 1.5.8

  2. You need first to Import the libraries CircularBuffer and RF24

  3. I use wireshark 1.12.1 and receive and error
    "The procedure entry point tvb_length cold not be located in the dynamic library......"
    Some one cold help me?

  4. Hey Ariel,

    I developed using Wireshark 1.10.8. Probably the API has slightly changed since then.
    Please try with Wireshark 1.10.x.

  5. Is it possible to use this with an Arduino Mega 2560 or an Arduino Pro?

    1. In principle it should work (maybe you have to change some pin assignments). I didn't test it, though.