1

My arduino uno with the NRF24L01 combination gives failed messages on writing.

Using the basic example code 'getting started' literally copied from: http://tmrh20.github.io/RF24/GettingStarted_8ino-example.html, my serial monitor constantly writes 'failed' (See attached screenshot)

The setup is for my Arduino uno as described in the table on http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo#PP (Arduino pin for TMRh20 RF24 Library)

The code:

/*
* Getting Started example sketch for nRF24L01+ radios
* This is a very basic example of how to send data from one node to another
* Updated: Dec 2014 by TMRh20
*/
#include <SPI.h>
#include "RF24.h"
#include <printf.h>

/****************** User Config ***************************/
/***      Set this radio as radio number 0 or 1         ***/
bool radioNumber = 1;
/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(7,8);
/**********************************************************/
byte addresses[][6] = {"1Node","2Node"};
// Used to control whether this node is sending or receiving
bool role = 0;
void setup() {
  Serial.begin(115200);
  printf_begin();
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));

  radio.begin();
  // Set the PA Level low to prevent power supply related issues since this is a
 // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  radio.setPALevel(RF24_PA_LOW);

  // Open a writing and reading pipe on each radio, with opposite addresses
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.printDetails();
  // Start the radio listening for data
  radio.startListening();
}
void loop() {


/****************** Ping Out Role ***************************/  
if (role == 1)  {

    radio.stopListening();                                    // First, stop listening so we can talk.


    Serial.println(F("Now sending"));
    unsigned long start_time = micros();                             // Take the time, and send it.  This will block until complete
     if (!radio.write( &start_time, sizeof(unsigned long) )){
       Serial.println(F("failed"));
     }

    radio.startListening();                                    // Now, continue listening

    unsigned long started_waiting_at = micros();               // Set up a timeout period, get the current microseconds
    boolean timeout = false;                                   // Set up a variable to indicate if a response was received or not

    while ( ! radio.available() ){                             // While nothing is received
      if (micros() - started_waiting_at > 200000 ){            // If waited longer than 200ms, indicate timeout and exit while loop
          timeout = true;
          break;
      }      
    }

    if ( timeout ){                                             // Describe the results
        Serial.println(F("Failed, response timed out."));
    }else{
        unsigned long got_time;                                 // Grab the response, compare, and send to debugging spew
        radio.read( &got_time, sizeof(unsigned long) );
        unsigned long end_time = micros();

        // Spew it
        Serial.print(F("Sent "));
        Serial.print(start_time);
        Serial.print(F(", Got response "));
        Serial.print(got_time);
        Serial.print(F(", Round-trip delay "));
        Serial.print(end_time-start_time);
        Serial.println(F(" microseconds"));
    }
    // Try again 1s later
    delay(1000);
  }
/****************** Pong Back Role ***************************/
  if ( role == 0 )
  {
    unsigned long got_time;

    if( radio.available()){
                                                                    // Variable for the received timestamp
      while (radio.available()) {                                   // While there is data ready
        radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
      }

      radio.stopListening();                                        // First, stop listening so we can talk   
      radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.      
      radio.startListening();                                       // Now, resume listening so we catch the next packets.     
      Serial.print(F("Sent response "));
      Serial.println(got_time);  
   }
 }
/****************** Change Roles via Serial Commands ***************************/
  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == 0 ){      
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      role = 1;                  // Become the primary transmitter (ping out)

   }else
    if ( c == 'R' && role == 1 ){
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));      
       role = 0;                // Become the primary receiver (pong back)
       radio.startListening();

    }
  }
} // Loop

While my other arduino has the same setup only radioNumber = 0 on that one.

The monitor output: monitor output

My setup: Arduino setup

EDIT: Ok so i managed to run printDetails() (thanks for the help on that one) This came up with:

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0x65646f4e31 0x65646f4e32
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0x65646f4e31
RX_PW_P0-6   = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x02
RF_CH        = 0x4c
RF_SETUP     = 0x03
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_LOW

on arduino one, and with the following on arduino 2 with radionumber = 1

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0x65646f4e32 0x65646f4e31
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0x65646f4e32
RX_PW_P0-6   = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x02
RF_CH        = 0x4c
RF_SETUP     = 0x03
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_LOW
  • Do you have the same setup for the receiver? How far is the receiver from your transmitter? The NRFs have some trouble if they are to close to one another. – Gerben Jul 8 '18 at 18:14
  • Same setup, about 2 / 3 meters away. However, this more likely seems like a problem of transmitting rather than receiving because this says that transmitting is not even working right? – Mart Jul 8 '18 at 18:15
  • Sorry, you're correct. The timeout message threw me off. It seems like the Arduino is unable to communicate with the NRF. Try wiggling all the connections, to make sure they make good contact. Try calling the printDetails function. – Gerben Jul 8 '18 at 18:32
  • hmm the connections seem fine... especially because both devices give the same error. (same setup). I have a small issue implementing the printDetails. when I add the line radio.printDetails(); anywhere, I don't see any response in my monitor? – Mart Jul 8 '18 at 18:36
  • 1
    Looking at the pictures, I'm sure this issue is caused by too weak power supply. Try soldering a large decoupling capacitor to the module's VCC and GND pins directly, if that doesn't improve the situation use an external 3.3V regulator. – Avamander Jul 10 '18 at 18:41
1

I'm currently writing a driver (for fun) and noticed that if the clock line is not at the correct idle logic level when the CS pin goes low, the chip freaks out and gives me issues when reading/writing registers. This may or may not help you, but figured it would be worth a shot to mention it.

Edit: The chip expects CPOL 0, so I used a pull down resistor on the clock line. So it will by default idle low.

  • Rewrite your answer as an actual solution, if it is one. Presently, it appears more of a comment. – MichaelT Nov 25 '18 at 19:51
  • Thanks, i'll try asap and post the result. Did you place a resistor between sck pin and ground? (assuming this layout: tmrh20.github.io/RF24 ) – Mart Nov 26 '18 at 15:20
  • I didn't need to physically place a resistor due to my MCU having them internally, but that should work fine. Maybe 10k? – Brandon Braun Nov 26 '18 at 15:24
0

See how/whether Arduino actually communicates with the master nRF, before tackling the problem of the tx/rx.

Use the code given below to print out the tx and rx radio registers (no libraries required except SPI). You will need to use the right values for CE and CSN pins. Post the data in your question, there are many several people on stack exchange who will be able to help you find the solution.

#include <SPI.h>
#define CE_pin 4
#define CSN_pin 5
#define MOSI_pin 11
#define MISO_pin 12
#define SCK_pin 13
byte data_in;

byte radio1_tx_addr[5] = {0xC5, 0xC5, 0xC5, 0xC5, 0xC5};
byte radio2_tx_addr[5] = {0x31, 0x31, 0x31, 0x31, 0x31};

void setup() {
  Serial.begin(115200);
  pinMode(CE_pin, OUTPUT);//chip enable set as output
  pinMode(CSN_pin, OUTPUT);//chip select pin as output
  pinMode(MOSI_pin, OUTPUT);//SPI data out
  pinMode(MISO_pin, INPUT); //SPI data in
  pinMode(SCK_pin, OUTPUT);//SPI clock out
  SPI.setBitOrder(MSBFIRST);//SPI Most Significant Bit First
  SPI.setDataMode(SPI_MODE0);// Mode 0 Rising edge of data, keep clock low
  SPI.setClockDivider(SPI_CLOCK_DIV2);//Run the data in at 16MHz/2 - 8MHz
  digitalWrite(CE_pin, HIGH);//RX mode
  digitalWrite(CSN_pin, HIGH);//SPI idle
  SPI.begin();//start up the SPI library
  delay(100);

  nrf_set_TX_ADDR(radio1_tx_addr); // set TX/RX addresses
  nrf_set_RX_ADDR_P1(radio2_tx_addr); 

  Serial.print("CONFIG");
  nrf_read_register(0x00);
  Serial.print("EN_AA");
  nrf_read_register(0x01);
  Serial.print("EN_RXADDR");
  nrf_read_register(0x02);
  Serial.print("SETUP_AW");
  nrf_read_register(0x03);
  Serial.print("SETUP_RETR");
  nrf_read_register(0x04);
  Serial.print("RF_CH");
  nrf_read_register(0x05);
  Serial.print("RF_SETUP");
  nrf_read_register(0x06);
  Serial.print("STATUS");
  nrf_read_register(0x07);
  Serial.print("OBSERVE_TX");
  nrf_read_register(0x08);
  Serial.print("RPD");
  nrf_read_register(0x09);
  Serial.print("RX_ADDR_P0");
  nrf_read_register(0x0A);
  Serial.print("RX_ADDR_P1");
  nrf_read_register(0x0B);
  Serial.print("RX_ADDR_P2");
  nrf_read_register(0x0C);
  Serial.print("RX_ADDR_P3");
  nrf_read_register(0x0D);
  Serial.print("RX_ADDR_P4");
  nrf_read_register(0x0E);
  Serial.print("RX_ADDR_P5");
  nrf_read_register(0x0F);
  Serial.print("TX_ADDR");
  nrf_read_register(0x10);
  Serial.print("RX_PW_P0");
  nrf_read_register(0x11);
  Serial.print("RX_PW_P1");
  nrf_read_register(0x12);
  Serial.print("RX_PW_P2");
  nrf_read_register(0x13);
  Serial.print("RX_PW_P3");
  nrf_read_register(0x14);
  Serial.print("RX_PW_P4");
  nrf_read_register(0x15);
  Serial.print("RX_PW_P5");
  nrf_read_register(0x16);
  Serial.print("FIFO_STATUS");
  nrf_read_register(0x17);
  Serial.print("DYNPD");
  nrf_read_register(0x1C);
  Serial.print("FEATURE");
  nrf_read_register(0x1D);  
}

void loop() {
}

void nrf_read_register(byte reg) {
  digitalWrite(CSN_pin, LOW);
  SPI.transfer(reg);
  data_in = SPI.transfer(0x00);
  digitalWrite(CSN_pin, HIGH);
  Serial.print(": 0x");
  Serial.print(reg,HEX);
  Serial.print(" => 0x");
  Serial.println(data_in,HEX);
  delay(10);
}

void nrf_set_TX_ADDR(byte x) {
  digitalWrite(CSN_pin, LOW);
  SPI.transfer(0x30);
  SPI.transfer(x[0]);
  SPI.transfer(x[1]);
  SPI.transfer(x[2]);
  SPI.transfer(x[3]);
  SPI.transfer(x[4]);
  digitalWrite(CSN_pin, HIGH);
  delay(10);
}

void nrf_set_RX_ADDR_P1(byte x) {
  digitalWrite(CSN_pin, LOW);
  SPI.transfer(0x2B);
  SPI.transfer(x[0]);
  SPI.transfer(x[1]);
  SPI.transfer(x[2]);
  SPI.transfer(x[3]);
  SPI.transfer(x[4]);
  digitalWrite(CSN_pin, HIGH);
  delay(10);
}
  • CONFIG: 0x0 => 0xF EN_AA: 0x1 => 0x3F EN_RXADDR: 0x2 => 0x2 SETUP_AW: 0x3 => 0x3 SETUP_RETR: 0x4 => 0x5F RF_CH: 0x5 => 0x4C RF_SETUP: 0x6 => 0x3 STATUS: 0x7 => 0xE OBSERVE_TX: 0x8 => 0x0 RPD: 0x9 => 0x0 RX_ADDR_P0: 0xA => 0x31 RX_ADDR_P1: 0xB => 0x32 RX_ADDR_P2: 0xC => 0xC3 RX_ADDR_P3: 0xD => 0xC4 RX_ADDR_P4: 0xE => 0xC5 RX_ADDR_P5: 0xF => 0xC6 TX_ADDR: 0x10 => 0x31 RX_PW_P0: 0x11 => 0x20 RX_PW_P1: 0x12 => 0x20 RX_PW_P2: 0x13 => 0x0 RX_PW_P3: 0x14 => 0x0 RX_PW_P4: 0x15 => 0x0 RX_PW_P5: 0x16 => 0x0 FIFO_STATUS: 0x17 => 0x11 DYNPD: 0x1C => 0x0 FEATURE: 0x1D => 0x0 – Mart Jul 8 '18 at 23:17
  • You are at least talking to the radio. All settings are default except CONFIG: 0x0 => 0xF (PRX mode, powered up, crc=2 enabled) SETUP_RETR: 0x4 => 0x5F (up to 15 retransmit attempts) RF_CH: 0x5 => 0x4C (channel 2476 MHz) RX_PW_P0: 0x11 => 0x20 (32-byte payload) RX_PW_P1: 0x12 => 0x20 (32-byte payload). See section 9 of the nRF data sheet for index of the register values. – MichaelT Jul 8 '18 at 23:34
  • One of the radios needs to be PTX (primary transmitter), the data you posted above show the radio is set to PRX (primary receiver). Make sure receiver and transmitters have common pipe addresses and use the same radio frequency. Upvote answer, please, if it is helpful to you. – MichaelT Jul 8 '18 at 23:35
  • Okay, thanks! so if I'm able to talk to the radio, why will the writing result in a fail? Are these settings incorrect? I just took them out of the box like this and started working with them like described above without editing settings. – Mart Jul 9 '18 at 6:36
  • For each Arduino controlling the TX/RX radios, put my code into your program at the end of setup section and copy here what the output is. There are many things which can be wrong. Also check one of the radios has bool radioNumber = 0; and the other bool radioNumber = 1; – MichaelT Jul 9 '18 at 6:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.