three NRF24L01 nodes

Hello all,

I’ve had problems for several weeks with RF24 Library (enhanced fork). I know very well different documentation, and I read a lot on different forums. But It doesn’t work anymore !!

My goal is to have a master which communicate with two slaves. Each have different adress and different pipes.

I have a lot of loss (only 60 % works)

Here is master software :

#include <Arduino.h>
#include <SPI.h>
#include "nRF24L01.h"    //Définition des registres et espace adresse du nrf24l01
#include "RF24.h"        //Définition des fonctions utiles au nrf24l01
#include "printf.h"      //Définition du printf façon C
#ifndef CONFIG_H
#define CONFIG_H
#pragma once
#include "config.h"           //Définition des constantes pour le projet DomoFab
#endif

RF24 radio(CE, CSN);

const uint64_t talking_pipes[5] = { 0xF0F0F0F0D2LL, 0xF0F0F0F0C3LL, 0xF0F0F0F0B4LL, 0xF0F0F0F0A5LL, 0xF0F0F0F096LL };
const uint64_t listening_pipes[5] = { 0x3A3A3A3AD2LL, 0x3A3A3A3AC3LL, 0x3A3A3A3AB4LL, 0x3A3A3A3AA5LL, 0x3A3A3A3A96LL };

byte nbSlave = 2;
uint8_t value[2] = {0, 0};
uint32_t timeRead; 
uint16_t nbAnswer[2];
uint16_t nbAsk[2];
boolean valueChange = false;
byte askMess[][6]={{6, 0, 100, 0, 0, 19},{6, 1, 100, 0, 0, 19}};
byte answerMess[32];

// the setup routine runs once when you press reset:
void setup() {                
  Serial.begin(57600);
  printf_begin();
  printf("DomoFab rRF24 MASTER start\n\n\r");  
// Setup and configure rf radio
  radio.begin();                          // Start up the radio
  radio.setCRCLength(RF24_CRC_8);
  radio.setAutoAck(true);                    // Ensure autoACK is enabled
  radio.setRetries(15,15);                // Max delay between retries & number of retries
  radio.startListening();                 // Start listening
  radio.printDetails();                   // Dump the configuration of the rf unit for debugging
  //radio.enableDynamicAck();

  printf ("\nConfiguration : MASTER\n\r");
  radio.openReadingPipe(1,talking_pipes[0]);
  radio.openReadingPipe(2,talking_pipes[1]);
  radio.openReadingPipe(3,talking_pipes[2]);
  radio.openReadingPipe(4,talking_pipes[3]);
  radio.openReadingPipe(5,talking_pipes[4]);
  timeRead = millis();
}

// the loop routine runs over and over again forever:
void loop() {
  
/****************** MASTER Role ***************************/
  if (abs(millis()-timeRead) > 500){
    timeRead = millis();
    for (byte slave = 0; slave < 2; slave++){           // Je scrutte tous les esclaves

      radio.openWritingPipe(listening_pipes[slave]);
      radio.stopListening();                                    // First, stop listening so we can talk.

      if (!radio.write(askMess[slave], 32)){
        printf("fail to send.\n\r");
      }
      nbAsk[slave]++;
      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
      
      uint8_t pipe_num;      
      while ( ! radio.available(&pipe_num) ){                    // 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
        printf("Failed, response timed out Slave %u\n", slave);
      }else{
        radio.read(answerMess, 32 );
        nbAnswer[slave]++;
      }
    }
    printf("slave 1 : %u/%u   slave 2 : %u/%u\n", nbAnswer[0], nbAsk[0], nbAnswer[1], nbAsk[1]);
  }
}

and slaves software :

#include <Arduino.h>
#include <SPI.h>
#include "nRF24L01.h"    //Définition des registres et espace adresse du nrf24l01
#include "RF24.h"        //Définition des fonctions utiles au nrf24l01
#include "printf.h"      //Définition du printf façon C
#ifndef CONFIG_H
#define CONFIG_H
#pragma once
#include "config.h"           //Définition des constantes pour le projet DomoFab
#endif

RF24 radio(CE, CSN);

const uint64_t talking_pipes[5] = { 0xF0F0F0F0D2LL, 0xF0F0F0F0C3LL, 0xF0F0F0F0B4LL, 0xF0F0F0F0A5LL, 0xF0F0F0F096LL };
const uint64_t listening_pipes[5] = { 0x3A3A3A3AD2LL, 0x3A3A3A3AC3LL, 0x3A3A3A3AB4LL, 0x3A3A3A3AA5LL, 0x3A3A3A3A96LL };
byte askMess[32];
byte answerMess[][24]= {{24, 100, 0, 0, 19, 255, 255, 255, 255, 255, 253, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{24, 100, 1, 0, 19, 255, 255, 255, 255, 255, 253, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};

// ???????????????????????????  Who am I ?????????????????????????????????????????????????????????????????????????????????????????????????????????????
//byte role = 0;
byte role = 1;
// ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

// the setup routine runs once when you press reset:
void setup() {

  Serial.begin(57600);
  printf_begin();
  printf("DomoFab rRF24 Slave n°: %u start\n\n\r", role);

  // initialize the digital pin as an output.
  radio.begin();                          // Start up the radio
  radio.setCRCLength(RF24_CRC_8);
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.setRetries(15, 15);               // Max delay between retries & number of retries
  radio.printDetails();                   // Dump the configuration of the rf unit for debugging

  printf ("\nConfiguration : SLAVE\n\r");
  radio.openWritingPipe(talking_pipes[role]);
  radio.openReadingPipe(1, listening_pipes[role]);
  
  radio.startListening();                 // Start listening
}

// the loop routine runs over and over again forever:
void loop() {

/****************** Slave Role ***************************/
  if ( radio.available()) {
    while (radio.available()) {                                   // While there is data ready
      radio.read(askMess, 32);                     // Get the payload
    }
    //printf("Message reçu : ");
    //printMess(askMess);
    radio.stopListening();                                             // First, stop listening so we can talk
    while (!radio.write( answerMess[role], 32)){                         // Send NBMAXVALUE + HEAD + CRC.
      printf("fail to send.\n\r");
    }
    radio.startListening();                                            // Now, resume listening so we catch the next packets.
  }
}

actually nothing complicated!

but I have this result:

DomoFab rRF24 MASTER start


STATUS		 = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1	 = 0x3a3a3a3ad2 0xf0f0f0f0d2
RX_ADDR_P2-5	 = 0xc3 0xb4 0xa5 0x96
TX_ADDR		 = 0x3a3a3a3ad2
RX_PW_P0-6	 = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA		 = 0x3f
EN_RXADDR	 = 0x3e
RF_CH		 = 0x4c
RF_SETUP	 = 0x07
CONFIG		 = 0x0b
DYNPD/FEATURE	 = 0x00 0x00
Data Rate	 = 1MBPS
Model		 = nRF24L01+
CRC Length	 = 8 bits
PA Power	 = PA_MAX

Configuration : MASTER

slave 1 : 1/1   slave 2 : 1/1
Failed, response timed out Slave 0
slave 1 : 1/2   slave 2 : 2/2
Failed, response timed out Slave 1
slave 1 : 2/3   slave 2 : 2/3
slave 1 : 3/4   slave 2 : 3/4
Failed, response timed out Slave 0
slave 1 : 3/5   slave 2 : 4/5
Failed, response timed out Slave 1
slave 1 : 4/6   slave 2 : 4/6
slave 1 : 5/7   slave 2 : 5/7
slave 1 : 6/8   slave 2 : 6/8
Failed, response timed out Slave 0
slave 1 : 6/9   slave 2 : 7/9
Failed, response timed out Slave 1
slave 1 : 7/10   slave 2 : 7/10
slave 1 : 8/11   slave 2 : 8/11
Failed, response timed out Slave 0
slave 1 : 8/12   slave 2 : 9/12
Failed, response timed out Slave 0
Failed, response timed out Slave 1
slave 1 : 8/13   slave 2 : 9/13
Failed, response timed out Slave 0
slave 1 : 8/14   slave 2 : 10/14
Failed, response timed out Slave 0
slave 1 : 8/15   slave 2 : 11/15
Failed, response timed out Slave 1
slave 1 : 9/16   slave 2 : 11/16
Failed, response timed out Slave 1
slave 1 : 10/17   slave 2 : 11/17
Failed, response timed out Slave 0
slave 1 : 10/18   slave 2 : 12/18
Failed, response timed out Slave 1
slave 1 : 11/19   slave 2 : 12/19
slave 1 : 12/20   slave 2 : 13/20
Failed, response timed out Slave 0

have you an idea ?

regards

am I the only one who have this problem ??

up ?

I don't know the answer to your problem - I have never used an NRF24. But I did get a Cypress 2.4GHz system working for my model trains. They all work on the same frequency - so all the slaves hear all the messages from the master. But a slave only responds to a message that contains the ID number I assigned to it.

Debugging wireless is tricky.

What happens if you only have one of your slaves powered up - does that improve things?

I don't understand NRF "pipes" - does that mean different frequencies? If so, are you allowing enough time for switching from one to the other.

It may be worth writing code that is just intended for 1 to 1 communication and getting that to work perfectly.

...R

Hi,
Have you tried to program just one on one first and that way you can check that your master and slaves are functioning properly?

Tom... :slight_smile:

Thanks for your replies.

I tried to switch off one of slaves, and everything is ok in this case ! So I guess that slaves interferes each others, but I can't understand the way ?

Pipes mechanism doesn't use different frequency but different address, so in my case I put different address and only the right slave answer the master.

Here is my 3cents worth - mostly just wild guesses

In this Master code

     radio.openWritingPipe(listening_pipes[slave]);
      radio.stopListening();

I wonder if the stopListening() should come before the openWritingPipe

In this Slave code

 radio.setAutoAck(1);

what does that do? Is it possible both Slaves acknowledge at the same time?

Have you tried one-at-a-time with both slaves - to test out the correct selection of different pipes?

The following may only be muddying the water so ignore it if you wish ...
In my Cypress 2.4GHz system I have not used different pipes - all the communication is in the same pipe. But each slave has a program contant that identifies it and the master includes that number in a message intended for that slave. It means all the slaves hear all the messages but each can figure out when it is its turn to reply.

...R

Hi,

Robin2:
I wonder if the stopListening() should come before the openWritingPipe

I tried to reverse lines, nothing better.

Robin2:
what does that do? Is it possible both Slaves acknowledge at the same time?

I asked myself this question, but ask only one slave one a different address as the aother. If the second answer too, It's a manufacturer hardware issue !

Robin2:
Have you tried one-at-a-time with both slaves - to test out the correct selection of different pipes?

Yes, and each have a differente address, and each run perfecly when it is alone !

???

flylowgofastturnleft:
It's a manufacturer hardware issue !

Maybe - but you are the guy with the immediate problem :slight_smile:

What happens if you don't use autoAck ?
Can you post a link to the documentation ?

...R

Big minds meet each other (hazardous French translation !)(great minds think alike)

A couple of hour I optained a good result :

slave 1 : 6338/6338 slave 2 : 6336/6338 : messages ok / total messages

I changed autoAck(true) with autoAck(false) on each sketches
I used channel 0x70 to stay far from noisy channels
And I set radio.setPALevel(RF24_PA_MIN); because my boards are very close to each other !

Thanks again for your help