Reverse Engineering a Quadcopter RC, or: How to not miss the needle while throwing the haystack in the air (Part 1)

EDIT: The series got featured on my favorite hackspiration site…! Thanks to Brian Benchoff for his very kind and encouraging review. It got me hovering around like a quadcopter all day with a big smile on my face, asking my wife to ask me again what the hours and nights spent on this project were for… And it won’t be the last ;o)

Discounters. Perfect for basic groceries, good quality at a fair price and above all: clear. I mean, who needs ten different brands for milk with twenty different prices when they all come from the same cow?!? But that’s a different topic…

The other day, LIDL offered this nice little quaocopter for only 30 Euro. I just couldn’t resist, especially not after reading through Dzls’ post on controlling a toy quaocopter with an Arduino (also featured on Unfortunately he doesn’t go much into detail when it comes to the SPI eavesdropping part (probably because it was just too easy and not worth elaborating on it). As I only had little to no experience with that specific interface other than using pre-defined libraries to let my Arduino talk to sensors and radio modules, I accepted the challenge. In the end, I managed to reverse engineer the protocol, pair the quaocopter with an Arduino UNO and build my own RC. It is even possible to change the address and use a different one than the original remote control does…

There is still three misterious bytes in the data packets, which seem to be somewhat of a counter (one counting up, the other two counting down), but they don’t seem to influence the operation much. I had the Arduino “move” the throttle up and down for almost 30 minutes and did not change the values seeing no impact.

copter and box

Quadcopter on the box, remote already disassembled

Part one of this project will describe the way from zero to finding the right channel up to listening to ALL the communication on a specific channel (promiscuous mode). Later parts will talk about how to interpret the received data and how to tap into the SPI communication (and the pitfalls of it) to finally bring all the bits and pieces together. To keep things short and simple, I will not go into detail on things like how to connect an nRF24L01 transceiver to the arduino board, as there are already plenty of examples all over the web. The project shall be more about the (quite rewarding) learning curve experienced through reverse engineering.

So this is what I did (of course only after taking the quadcopter for a short spin):

Step 1: Check Documentation (yes, this includes the manual!)

The box and also the 75 page manual (4 languages) did not give away much. The only half useful information was the specification of the remote control:

  • Transmitting Frequency 2.4 GHz
  • Range: max 30m
  • Operating Voltage: 3 x 1.5V Batteries

The remote itself has a “4-CH” sticker on it, which most probably refers rather to the transmitted information (throttle, yaw, pitch and roll) than the radio characteristics.

So nothing on used channels, CE certificates or anything. What the manual does talk about is “intended use”, which I probably violated a litte here…

Step 2: Listen to the radio

In one of my drawers I had two Sparkfun nRF24L01+ breakout boards, which are also operating on 2.4GHz. Following the scanner example, which came with the RF24 library written by J.Coliz, I started scanning the 127 channels. The code needed a little adjustment to 1) make the range of scanned channels a bit more narrow and 2) to reduce overhead and make the scanning faster. The code can be found in my github repository.

The serial output during a few scans showed increased activity between channels 58 and 62, and closing the range and threshold, the most traffic was found on channel 60.

Step 3: Listen to Channel 60 – First haystack

A rather challenging step. The nRF24L01 board is meant to receive make messages only visible when they have been

  • received on a chosen channel (0 .. 127)
  • at a chose data rate (250kbps, 1Mbit or 2Mbit)
  • with a chosen header that can be anything between 3 to 5 bytes long

It is able to listen on six “pipes” simultaniously, though, but they would be sharing the first 2 – 4 bytes of the address. This seemed to be quite a haystack (about 2,3xE^29 straws, given that we already know the right frequency).

SDR would have been one option, but probably too timeconsuming. So I did a quick search on promiscuous mode, which is not officially supported by the nRF24L01. It led me to Travis Goodspeed’s blog on which he is desribing in detail how to tag into the radio stream of a wireless 2.4GHz keyboard. He was using an “illegal” register setting for the address length on the nRF24L01 along with the fact that the preamble byte of each transmission would be either 01010101 (0x55) or 10101010 (0xAA), depending on whether the first bit of the address in use is set to 0 or 1. So with CRC turned off, one byte of the address being either 0x00 or 0xFF (hoping for noise to trigger it) and the second byte being either 0x55 or 0xAA, chances were pretty high to catch whole transmission packets including the address, packet control field, payload and CRC byte(s) as described on p.28 of the nRF24L01+ product specification. I also had to hope the protocol used by the RC transceiver would be similar to the one used by the nRF24 (which in fact it is. As it turned out, those low cost modules like the RFM70 or the Beken BK2423 are pretty similar to the nRF24L01).

This is what the normal transmission Flow would look like: The receiver gets triggered by the preamble, checks the CRC and address and would make the payload availabletransmission flow normal

This is what the “promiscuous” reception looks like: The receiver gets triggered by random noise, uses more noise as first byte of the address and the the preamble of the RC is being interpreted as the second byte of the address. CRC check was deactivated, thus whatever might be in the following 32 byte is being concidered as payload.transmission flow promiscuousIf the data comes from the RC (and follows the RF24 protocol), the received message will definitely contain the address bytes and also the packet control bits, if there are any. Depending on the RC address length (up to 5 bytes), there might be a worst case overlap of 25 bytes and 7 bits for the RC payload. Expecting a rather small ammout of data to be sent (supposedly one byte each for throttle, yaw, pitch and roll, maybe some control bytes, so probably no more than 8 bytes), the whole transmission might even fit into the received payload (and as we will see in the serial output and when , it does!)

The code for the promiscuous receiver can be found in my github repository.




About Michael Melchior

Husband, Father, computer scientist, commercial helicopter pilot. Full of ideas and open minded, I try to see challenges in what others call problems.
This entry was posted in Projects, QC-360-A1 and tagged , , , , . Bookmark the permalink.

10 Responses to Reverse Engineering a Quadcopter RC, or: How to not miss the needle while throwing the haystack in the air (Part 1)

  1. Pingback: Reverse Engineering a Quadcopter RC, or: How to not miss the needle while throwing the haystack in the air (Part 2) | Michael Melchior

  2. Pingback: Reverse Engineering a Quadcopter RC, or: How to not miss the needle while throwing the haystack in the air (Part 4) | Michael Melchior

  3. Pingback: Reverse Engineering Quadcopter Protocols | Hackaday

  4. Pingback: Reverse Engineering Quadcopter Protocols - SHelfinger

  5. Pingback: Reverse Engineering Quadcopter Protocols | BH

  6. Pingback: Reverse Engineering a Quadcopter RC, or: How to not miss the needle while throwing the haystack in the air (Part 1) | Michael Melchior – ooo00

  7. Pingback: Weekendowa Lektura 2016-08-20 – wydanie podwójne | Zaufana Trzecia Strona

  8. Kishore says:

    Awesome tut…I am pretty much new to RC sniffing and hacking..I got a small doubt..Can any 2.4 GHz receiver(say NRF24L01) sniffs signal from any 2.4 GHz transmitter(say different from NRF) even if their protocols are different… from what I read that NRF24L01 uses enhanced shockburst protocol(ESB) the transmitter in the quad also the same or different..Sorry if I am missing anything..

    • Hey Kishore,

      thanks for your comment. I’m not much of an expert either, but from what I found, the two 2.4GHz transceivers were pretty similar when it comes to design, protocol and features. As far as I understood, the ESB is a feature that can be turned on / off and yes, I’m quite positive that even other receivers should have the ability to sni… uhm… work in promiscous mode… Can you tell me more about the recevier you are planning to use?


  9. gandolfin says:

    hi, thank you for this tuto.

    For step 2, i have this code. i have switch on the receiver and use all the command (forward, back, right, left) what do you think ?


    STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
    RX_ADDR_P0-1 = 0xe7e7e7e7e7 0xc2c2c2c2c2
    RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
    TX_ADDR = 0xe7e7e7e7e7
    RX_PW_P0-6 = 0x00 0x00 0x00 0x00 0x00 0x00
    EN_AA = 0x00
    EN_RXADDR = 0x03
    RF_CH = 0x4c
    RF_SETUP = 0x07
    CONFIG = 0x06
    DYNPD/FEATURE = 0x00 0x00
    Data Rate = 1MBPS
    Model = nRF24L01+
    CRC Length = Disabled
    PA Power = PA_MAX

    14: 9
    15: 7
    16: 9
    17: 7


    14: 6
    15: 6
    16: 6
    19: 7
    40: 6
    41: 6
    62: 8
    63: 7
    64: 7
    65: 7

    14: 8
    15: 8
    16: 8
    20: 6
    21: 6
    40: 8
    41: 8
    42: 8
    62: 9
    63: 9
    64: 8


    15: 7
    20: 7
    40: 7
    41: 6
    42: 7
    62: 8
    63: 8
    64: 8

    15: 8
    16: 6
    20: 7
    40: 7
    41: 7
    42: 7
    62: 9
    63: 8
    64: 7

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s