NRF24L01 + 3 Arduinos

Hi!
Please help me with following problem:
I have 3 arduinos and NRF24L01 modules. One arduino is connected do PC and peridically sends requests to another modules: first sends command do first arduino - it should answer with data from IMU, then module connected to PC sends the same command to third module (the same type of data). I've been trying to use two pipes - one pipe to one transmission pair. In the receiver I have only data from one pipe, but requests are visible in both modules. I display data from imu-they are correct, and requests are also visible in both modules. What I'm doing wrong that ony one pipe is received?

Ardiuno UNO - connected to PC (data sink)

#include <SPI.h> //rx ARDUINO UNO
#include "nRF24L01.h"
#include "RF24.h"
#define button 7
#define led_pin 5
RF24 radio(10, 9);

int ax1, ay1, az1;
int a1[3];
int g1[3];
int m1[3];
int s1[9];
const uint64_t  addresses[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL };
const int command[] = {1 , 2};
byte rx_command;

byte pipeNum1 = 0;
byte pipeNum2 = 1;
int buttonState = 0;
boolean bu = 0;

void setup() {
  pinMode(led_pin, OUTPUT);
  pinMode(button, INPUT);
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(addresses[0]);
  
  radio.openReadingPipe(2, addresses[2]);
  radio.openReadingPipe(1, addresses[1]);
  radio.setPALevel(RF24_PA_MIN);
  radio.setRetries(1, 1);
  radio.setAutoAck(true);
  //radio.startListening();
  radio.stopListening();
}
void loop() {
  delay(5);
  radio.stopListening();
  radio.write(&command[0], sizeof(command[0]));
  radio.startListening();

  if (radio.available(&pipeNum1)) {
    if (pipeNum1 == 1)
    {
      radio.read(&s1, sizeof(s1));
      Serial.print("#1: ");
      Serial.print(s1[0]);
      Serial.print(", ");
      Serial.print(s1[1]);
      Serial.print(", ");
      Serial.print(s1[2]);
      Serial.print(", ");
      Serial.print(s1[3]);
      Serial.print(", ");
      Serial.print(s1[4]);
      Serial.print(", ");
      Serial.print(s1[5]);
      Serial.print(", ");
      Serial.print(s1[6]);
      Serial.print(", ");
      Serial.print(s1[7]);
      Serial.print(", ");
      Serial.print(s1[8]);
      Serial.println(" #END");
    }
  }
  delay(5);
  radio.stopListening();
  radio.write(&command[1], sizeof(command[1]));
  radio.startListening();
  if (radio.available(&pipeNum2)) {
    if (pipeNum2 == 2)
    {
      radio.read(&s1, sizeof(s1));
      Serial.print("#2: ");
      Serial.print(s1[0]);
      Serial.print(", ");
      Serial.print(s1[1]);
      Serial.print(", ");
      Serial.print(s1[2]);
      Serial.print(", ");
      Serial.print(s1[3]);
      Serial.print(", ");
      Serial.print(s1[4]);
      Serial.print(", ");
      Serial.print(s1[5]);
      Serial.print(", ");
      Serial.print(s1[6]);
      Serial.print(", ");
      Serial.print(s1[7]);
      Serial.print(", ");
      Serial.print(s1[8]);
      Serial.println(" #END");
    }
  }

}

First module with imu

#include <SPI.h> //tx ARDUINO MICRO 1
#include "nRF24L01.h"
#include "RF24.h"
#include "SFE_LSM9DS0.h"

#define LSM9DS0_XM  0x1D
#define LSM9DS0_G   0x6B

LSM9DS0 dof(MODE_I2C, LSM9DS0_G, LSM9DS0_XM);
RF24 radio(10, 9);

const uint64_t  pipes[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL };
int rx_command;
int s1[9];
unsigned char pipe_num;
void setup()
{
  Serial.begin(9600);
  radio.begin();

  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1, pipes[0]);
  uint16_t status = dof.begin();
  radio.setRetries(1, 1);
  radio.setAutoAck(true);
  radio.setPALevel(RF24_PA_MIN);
  //uint16_t status = dof.begin(dof.G_SCALE_2000DPS,
  //                            dof.A_SCALE_6G, dof.M_SCALE_2GS);
  Serial.print("LSM9DS0 WHO_AM_I's returned: 0x");
  Serial.println(status, HEX);
  Serial.println("Should be 0x49D4");
  Serial.println();
  radio.stopListening();
}

void loop(void)
{
  radio.startListening();
  while (!radio.available());

  radio.read(&rx_command, sizeof(rx_command));
  if (rx_command == 1)
  {
    dof.readAccel();
    dof.readGyro();
    dof.readMag();
    radio.stopListening();
    s1[0] = dof.ax;
    s1[1] = dof.ay;
    s1[2] = dof.az;
    s1[3] = dof.gx;
    s1[4] = dof.gy;
    s1[5] = dof.gz;
    s1[6] = dof.mx;
    s1[7] = dof.my;
    s1[8] = dof.mz;

    radio.write(&s1, sizeof(s1));
    Serial.print(s1[0]);
    Serial.print(", ");
    Serial.print(s1[1]);
    Serial.print(", ");
    Serial.print(s1[2]);
    Serial.print(", ");
    Serial.print(s1[3]);
    Serial.print(", ");
    Serial.print(s1[4]);
    Serial.print(", ");
    Serial.print(s1[5]);
    Serial.print(", ");
    Serial.print(s1[6]);
    Serial.print(", ");
    Serial.print(s1[7]);
    Serial.print(", ");
    Serial.println(s1[8]);

  }

}

Second module with imu

#include <SPI.h> //tx ARDUINO MICRO 2
#include "nRF24L01.h"
#include "RF24.h"
#include "SFE_LSM9DS0.h"

#define LSM9DS0_XM  0x1D
#define LSM9DS0_G   0x6B

LSM9DS0 dof(MODE_I2C, LSM9DS0_G, LSM9DS0_XM);
RF24 radio(10, 9);

const uint64_t  pipes[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL };
int rx_command;
int s1[9];
unsigned char pipe_num;
void setup()
{
  Serial.begin(9600);
  radio.begin();

  radio.openWritingPipe(pipes[2]);
  radio.openReadingPipe(2, pipes[0]);
  uint16_t status = dof.begin();
  radio.setRetries(1, 1);
  radio.setAutoAck(true);
  radio.setPALevel(RF24_PA_MIN);
  //uint16_t status = dof.begin(dof.G_SCALE_2000DPS,
  //                            dof.A_SCALE_6G, dof.M_SCALE_2GS);
  Serial.print("LSM9DS0 WHO_AM_I's returned: 0x");
  Serial.println(status, HEX);
  Serial.println("Should be 0x49D4");
  Serial.println();
  radio.stopListening();
}

void loop(void)
{

  radio.startListening();
  while (!radio.available(&pipe_num));

  radio.read(&rx_command, sizeof(rx_command));
  if (rx_command == 2)
  {
    dof.readAccel();
    dof.readGyro();
    dof.readMag();
    radio.stopListening();
    s1[0] = dof.ax;
    s1[1] = dof.ay;
    s1[2] = dof.az;
    s1[3] = dof.gx;
    s1[4] = dof.gy;
    s1[5] = dof.gz;
    s1[6] = dof.mx;
    s1[7] = dof.my;
    s1[8] = dof.mz;

    radio.write(&s1, sizeof(s1));
    Serial.print(s1[0]);
    Serial.print(", ");
    Serial.print(s1[1]);
    Serial.print(", ");
    Serial.print(s1[2]);
    Serial.print(", ");
    Serial.print(s1[3]);
    Serial.print(", ");
    Serial.print(s1[4]);
    Serial.print(", ");
    Serial.print(s1[5]);
    Serial.print(", ");
    Serial.print(s1[6]);
    Serial.print(", ");
    Serial.print(s1[7]);
    Serial.print(", ");
    Serial.println(s1[8]);
  }

}

Have a look at this Simple nRF24L01+ Tutorial. It includes an example with a master communicating with 2 slaves.

...R

Thank you!
I'm afraid it's not sufficient for me. First I've worked with only two modules with changing functionalities: it works perfectly. Problem occured when I started with 3.

karol_abratkiewicz:
I'm afraid it's not sufficient for me.

You have not said why not - knowing that will help me to help you.

First I've worked with only two modules with changing functionalities: it works perfectly. Problem occured when I started with 3.

Do you mean a master and 3 slaves or a master and 2 slaves?

...R

Dear Robin,
example that you mentioned covers only communication between two nodes. As I said, it works good in my case. I need solution for my case, where master asks first or second slave .

Robin2:
Do you mean a master and 3 slaves or a master and 2 slaves?

I mean master and two slaves.

karol_abratkiewicz:
I mean master and two slaves.

My Tutorial has an example that does that and the concept could be extended to a much larger number of slaves.

...R

Dear Robin!
Maybe I'm wrong, but I suppose you code doesn't work.
I've found only this code:

// MultiTxAckPayload - the master or the transmitter
// works with two Arduinos as slaves
// each slave should the SimpleRxAckPayload program
// one with the adress {'R','x','A','A','A'}
// and the other with {'R','x','A','A','B'}
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte numSlaves = 2;
const byte slaveAddress[numSlaves][5] = {
** // each slave needs a different address**
** {'R','x','A','A','A'},**
** {'R','x','A','A','B'}**
** };**
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
//~ char dataToSend[10] = "Message 0";
char dataToSend[10] = "ToSlvN 0";
char txNum = '0';
int ackData[2] = {-1, -1}; // to hold the two values coming from the slave
bool newData = false;
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second
//===============
void setup() {
** Serial.begin(9600);**
** Serial.println(F("Source File = /mnt/SGT/SGT-Prog/Arduino/ForumDemos/nRF24Tutorial/MultiTxAckPayload.ino "));**
** Serial.println("SimpleTxAckPayload Starting");**
** radio.begin();**
** radio.setDataRate( RF24_250KBPS );**
** radio.enableAckPayload();**
** radio.setRetries(3,5); // delay, count**
** // radio.openWritingPipe(slaveAddress); -- moved to loop()**
}
//=============
void loop() {
** currentMillis = millis();**
** if (currentMillis - prevMillis >= txIntervalMillis) {**
** send();**
** }**
** // showData(); -- moved into send()**
}
//================
void send() {
** // call each slave in turn**
** for (byte n = 0; n < numSlaves; n++){**
** // open the writing pipe with the address of a slave**
** radio.openWritingPipe(slaveAddress[n]);**
** // include the slave number in the message**
** dataToSend[5] = n + '0';**
** bool rslt;**
** rslt = radio.write( &dataToSend, sizeof(dataToSend) );**
** // Always use sizeof() as it gives the size as the number of bytes.**
** // For example if dataToSend was an int sizeof() would correctly return 2**
** Serial.print(" ======== For Slave ");**
** Serial.print(n);**
** Serial.println(" ========");**
** Serial.print(" Data Sent ");**
** Serial.print(dataToSend);**
** if (rslt) {**
** if ( radio.isAckPayloadAvailable() ) {**
** radio.read(&ackData, sizeof(ackData));**
** newData = true;**
** }**
** else {**
** Serial.println(" Acknowledge but no data ");**
** }**
** updateMessage();**
** }**
** else {**
** Serial.println(" Tx failed");**
** }**
** showData();**
** Serial.print("\n");**
** }**
** prevMillis = millis();**
}
//=================
void showData() {
** if (newData == true) {**
** Serial.print(" Acknowledge data ");**
** Serial.print(ackData[0]);**
** Serial.print(", ");**
** Serial.println(ackData[1]);**
** Serial.println();**
** newData = false;**
** }**
}
//================
void updateMessage() {
** // so you can see that new data is being sent**
** txNum += 1;**
** if (txNum > '9') {**
** txNum = '0';**
** }**
** dataToSend[8] = txNum;**
}
but I don't see any startListening or stopListening functions. I've tried to initialize every time writing pipe using openWritingPipe but it still doesn't work.

karol_abratkiewicz:
but I don't see any startListening or stopListening functions.

That's because it does not need them - that is the beauty of the idea. All that complexity is handled automatically by the nRF24.

The code you posted (please use the code button </> for posting code) is designed to work with the example in the SimpleRxAckPayload program.

I suggest you start by getting the pair of SimpleRxAckPayload and SimpleTxAckPayload to work and so you understand what is happening. Then the multi- version will make more sense.

...R