Go Down

Topic: NRF24L01+ Reliability with RF24 as a Gamepad (Read 1 time) previous topic - next topic


First question I was wondering what sort of reliability people are getting with this module and RF24 library

in the pingpair example about every 10th send fails.. sometimes it will send 100 in a row fine and sometime 10 in a row might fail. I used the scanner tool to find an open channel(120 is what I ended up using as there is nothing anywhere near it)

so ultimately I want to make a wireless SNES controller and have done so.. its fairly reliable if I use 'startWrite' instead of 'write' with write it fails almost all the time.. the data I am sending is a 16bit number sent as decimal(0-4095) if I set the payload size to anything but default it fails A LOT more so my guess is I am defining the payload incorrectly

i have 10 NRF24L01+ modules and to be sure its not an issue with one of them I checked them all and all have same results.

here is the output of the sending(controller) info display:

Code: [Select]

ROLE: Controller

RX_ADDR_P0-1 = 0xe8e8f0f0e1 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe8e8f0f0e1
RX_PW_P0-6 = 0x20 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x78
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_HIGH

This is the code I am using now that is fairly reliable but I notice the odd time it doesn't send a key like it should but games are completely playable with it... I put the same code on the transmitter(controller) and Reciever I am using an UNO and a Leonardo.. I simply comment out the Keyboard lines for the UNO when I upload it.
Code: [Select]
#include <digitalWriteFast.h>
#include <NESPad2.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

int msg[1];

const char letterOutput[12] = {
  216,    // Left
  215,    // Right
  218,    // Up
  217,    // Down
  'z',    // B
  'a',    // Y
  133,    // Select - RShift
  176,    // Start - Enter
  'x',    // A
  's',    // X
  'q',    // L
  'w',    // R

int SNESbuttons[12];

int button_data;

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10

RF24 radio(9,10);
const int role_pin = 7;

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipe = 0xE8E8F0F0E1LL;

// The various roles supported by this sketch
typedef enum { role_Controller = 1, role_RCV } role_e;

// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Controller", "Reciever"};

// The role of the current running sketch
role_e role;

void setup() {
  // Role

  // set up the role pin
  pinMode(role_pin, INPUT);
  delay(20); // Just to get a solid reading on the role pin

  // read the address pin, establish our role
  if ( ! digitalRead(role_pin) ) {
    role = role_Controller;
  else {
    role = role_RCV;
  if ( role == role_RCV ) {
  printf("ROLE: %s\n\r",role_friendly_name[role]);
  // Setup and configure rf radio


  // optionally, increase the delay between retries & # of retries

  // optionally, reduce the payload size.  seems to
  // improve reliability
  if ( role == role_Controller ) {
  else {
  // Start listening

  if ( role == role_RCV ) {

  // Dump the configuration of the rf unit for debugging


void loop() {
  if (role == role_Controller) {
    msg[0] = NESPad::read(16);
  if (role == role_RCV) {
    // if there is data ready
    if (radio.available()){
      // Dump the payloads until we've gotten everything
      bool done = false;
      while (!done) {
        // Fetch the payload, and see if this was the last one.
        done = radio.read(msg,2);

        button_data = msg[0];

void snes_read() {
  SNESbuttons[0] = button_data & 64;        // Left
  SNESbuttons[1] = button_data & 128;       // Right
  SNESbuttons[2] = button_data & 16;        // Up
  SNESbuttons[3] = button_data & 32;        // Down
  SNESbuttons[4] = button_data & 1;         // B
  SNESbuttons[5] = button_data & 2;         // Y
  SNESbuttons[6] = button_data & 4;         // Select
  SNESbuttons[7] = button_data & 8;         // Start
  SNESbuttons[8] = button_data & 256;       // A
  SNESbuttons[9] = button_data & 512;       // X
  SNESbuttons[10] = button_data & 1024;     // L
  SNESbuttons[11] = button_data & 2048;     // R
  int i = 12;
  while(i--) {
    if (SNESbuttons[i]) {
    else {

this is the code that doesn't work very well(a lot of fails) I assume the above has just as many fails but it sends non-stop so it makes up for it.... also i set retries to 15 when using the below code.
Code: [Select]
  if (role == role_Controller) {
    bool different = false;
    button_data = NESPad::read(16);
    if (msg[0] != button_data) {
      different = true;
      msg[0] = button_data;
    if (different) {
      printf("Now sending...%d... ",msg[0]);
      bool ok = radio.write(msg,2);
      if (ok)


It is not a 'reliability' issue.  The transmitting module is working, as is the recieving module.  It's just that the module, and/or, the microcontroller may be doing something else when a message is xmitted.  That is why you write code to do multiple xmits, go into recieve mode, and wait for an acknowldge for the original reciever.  Timing issue.


I would assume that the example code was written correctly and it fails just as much.. except usually when it says failed(on transmitter end) the signal does get sent... so what constitutes a fail? does it know the receiver received a signal? or is it just asking the transmitter if one was sent? if its only asking the transmitter if one was sent id assume then that there is something wrong with my transmitter module if it only send once in a while


@ OP I think you would do well to read ALL you can find in this forum about the RF24XX radio's. You might find your answer already.

--> WA7EMS <--
"The solution of every problem is another problem." -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

Go Up