One Transmitter and Multiple Receivers nRF24l01+

Hello all,

I am using this code example to activate relay, but it only works for a single receiver, can anyone help me to change the code so that I have a single transmitter and several receivers?

My code is this

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10


int node = 0;
const byte slaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};
char state = 1;

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "1";
char txNum = '0';
int addr = 0;

void setup() {
  lcd.begin(16, 2);
  Serial.begin(9600);
  
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.setRetries(3, 5);
  radio.openWritingPipe(slaveAddress);
  //radio.enableDynamicPayloads() ;
  //radio.setAutoAck( false ) ;
  //radio.powerUp() ;
  radio.startListening();
  }

//====================

  
void send() {
  if (myRTC.hours < Hora_ON && myRTC.hours > Hora_OFF && myRTC.minutes < Min_ON  && myRTC.minutes > Min_OFF  && node == 1) {
    bool rslt1;
    rslt1 = radio.write( &dataToSend, sizeof(dataToSend) );
  }
  else if (myRTC.hours < Hora_ON && myRTC.hours > Hora_OFF && myRTC.minutes < Min_ON  && myRTC.minutes > Min_OFF  && node == 2) {
    bool rslt2;
    rslt2 = radio.write( &dataToSend1, sizeof(dataToSend) );
  }
  else if (myRTC.hours < Hora_ON && myRTC.hours > Hora_OFF && myRTC.minutes < Min_ON  && myRTC.minutes > Min_OFF  && node == 3) {
    bool rslt3;
    rslt3 = radio.write( &dataToSend2, sizeof(dataToSend) );
  }
  else if (myRTC.hours < Hora_ON && myRTC.hours > Hora_OFF && myRTC.minutes < Min_ON  && myRTC.minutes > Min_OFF && node == 4) {
    bool rslt4;
    rslt4 = radio.write( &dataToSend3, sizeof(dataToSend) );
  }
}

At the moment, your code doesn't look like proper arduino code. Where is the loop segment?

That looks like it started life as my Simple nRF24L01+ Tutorial

You have not posted a complete program and your code in the send() function does not make any sense because you have no variable called dataToSend1 and even if you had it makes no sense to use the size of a different variable. Always post a complete program.

If you want to send data to several slaves in turn and get an acknowledgment from each then you need to give each slave a different address and the master must send a message to each different address.

If you just want to send one message and have it received by several slaves at the same time then you must give each slave the same address and you must turn off the acknowledgement feature so they don't all reply and confuse the master. Note that you can have simple acknowledgements without a payload and they must also be switched off using radio.setAutoAck( false ) ;

...R

AutoAck can be disabled/enabled individually for each pipe.

There could be one pipe that all node listen to, but none acks,
beside other pipes that ack, or ack with payload.

Thank you Robin and all. The code has exceeded the maximum number of characters for this was so, sorry.

I can to do so?

// continue
const byte slaveAddress1[5] = {'R','x','A','A','A'};
const byte slaveAddress2[5] = {'R','x','B','B','B'};
const byte slaveAddress3[5] = {'R','x','C','C','C'};
const byte masterAddress[5] = {'T','X','a','a','a'};
// continue

radio.openWritingPipe(slaveAddress1);
radio.openWritingPipe(slaveAddress2);
radio.openWritingPipe(slaveAddress3);
radio.openReadingPipe(1, masterAddress);

There is only 1 writing pipe so you must do this one at a time

radio.openWritingPipe(slaveAddress1);
radio.openWritingPipe(slaveAddress2);
radio.openWritingPipe(slaveAddress3);

something like

radio.openWritingPipe(slaveAddress1);
// send to slave 1
radio.openWritingPipe(slaveAddress2);
// send to slave 2
radio.openWritingPipe(slaveAddress3);
// send to slave 3

If you create a 2D array for the addresses it will be easier - I think you do it like this

const byte slaveAddress[4][] = {{'R','x','A','A','A'},
                                                         {'R','x','A','A','B'},
                                                         {'R','x','A','A','C'},
                                                         {'R','x','A','A','D'}};

then you can do something like

for (byte n = 0, n < numSlaves; n++) {
   radio.openWritingPipe(slaveAddress[n]);
   // send data to slave N
}

…R

Hi friend, thanks so much!!

Is the new code…

Slave1

// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[4][]= {{'R', 'x', 'A', 'A', 'A'}, {'R', 'x', 'A', 'A', 'B'},
  {'R', 'x', 'A', 'A', 'C'}, {'R', 'x', 'A', 'A', 'D'}};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate(RF24_250KBPS);
    radio.openReadingPipe(slaveAddress[1]);
    radio.startListening();
    radio.enableDynamicPayloads() ;
    radio.setAutoAck(false); 
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

Master

// SimpleTx - the master or the transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[4][] = {{'R', 'x', 'A', 'A', 'A'}, {'R', 'x', 'A', 'A', 'B'},
  {'R', 'x', 'A', 'A', 'C'}, {'R', 'x', 'A', 'A', 'D'}};

const byte masterAddress = {'T', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "Message 0";
char txNum = '0';

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second


void setup() {

  Serial.begin(9600);
  Serial.println("SimpleTx Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.setRetries(3, 5); // delay, count
  int numSlaves[4];
  for (byte n = 0; n < numSlaves; n++)
  {
  radio.openWritingPipe(slaveAddress[n]);
    // send data to slave N
  }
  radio.openReadingPipe(1,masterAddress),
  radio.enableDynamicPayloads() ;
  radio.setAutoAck( false ) ;
}

//====================

void loop() {
  currentMillis = millis();
  if (currentMillis - prevMillis >= txIntervalMillis) {
    send();
    prevMillis = millis();
  }
}

//====================

void send() {

  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("Data Sent ");
  Serial.print(dataToSend);
  if (rslt) {
    Serial.println("  Acknowledge received");
    updateMessage();
  }
  else {
    Serial.println("  Tx failed");
  }
}

//================

void updateMessage() {
  // so you can see that new data is being sent
  txNum += 1;
  if (txNum > '9') {
    txNum = '0';
  }
  dataToSend[8] = txNum;
}

but

Erro compiling

SlaveAddress1.ino:12:28: error: declaration of 'slaveAddress' as multidimensional array must have bounds for all dimensions except the first
SlaveAddress1.ino: In function 'void setup()':
SlaveAddress1.ino:29:27: error: 'slaveAddress' was not declared in this scope
Error compiling.

I got my array definition mixed up. It should be

const byte slaveAddress[][5] = {{'R','x','A','A','A'}, //etc

...R

Thanks!

Slave 2

void setup() {

  Serial.begin(9600);

  Serial.println("SimpleRx Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.openReadingPipe(slaveAddress[][2]);
  radio.startListening();
  radio.enableDynamicPayloads() ;
  radio.setAutoAck(false);
}

Error

SlaveAddress2.ino: In function 'void setup()':
SlaveAddress2.ino:29:38: error: expected primary-expression before ']' token
Error compiling.

Master

void setup() {

  Serial.begin(9600);
  Serial.println("SimpleTx Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.setRetries(3, 5); // delay, count
  int numSlaves=4;
  byte n = 0;
  radio.openReadingPipe(1,masterAddress);
  for(n < numSlaves; n++;)
  {
  radio.openWritingPipe(slaveAddress[n]);
    // send data to slave N
  }
  
  radio.enableDynamicPayloads() ;
  radio.setAutoAck( false ) ;
}

Error

Arduino: 1.6.0 (Windows 8), Board: "Arduino Nano, ATmega328"

MasterAddress.ino:14:52: error: scalar object 'masterAddress' requires one element in initializer
Error compiling.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

Slave 1

// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[][5]= {{'R', 'x', 'A', 'A', 'A'}, {'R', 'x', 'A', 'A', 'B'},
  {'R', 'x', 'A', 'A', 'C'}, {'R', 'x', 'A', 'A', 'D'}};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate(RF24_250KBPS);
    radio.openReadingPipe(1,slaveAddress[1]);
    radio.startListening();
    radio.enableDynamicPayloads() ;
    radio.setAutoAck(false); 
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

Slave 2

// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[][5] = {{'R', 'x', 'A', 'A', 'A'}, {'R', 'x', 'A', 'A', 'B'},
  {'R', 'x', 'A', 'A', 'C'}, {'R', 'x', 'A', 'A', 'D'}};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

  Serial.begin(9600);

  Serial.println("SimpleRx1 Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.openReadingPipe(2,slaveAddress[2]);
  radio.startListening();
  radio.enableDynamicPayloads() ;
  radio.setAutoAck(false);
}

//=============

void loop() {
  getData();
  showData();
}

//==============

void getData() {
  if ( radio.available() ) {
    radio.read( &dataReceived, sizeof(dataReceived) );
    newData = true;
  }
}

void showData() {
  if (newData == true) {
    Serial.print("Data received ");
    Serial.println(dataReceived);
    newData = false;
  }
}

Master

// SimpleTx - the master or the transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[][5] = {{'R', 'x', 'A', 'A', 'A'}, {'R', 'x', 'A', 'A', 'B'},
  {'R', 'x', 'A', 'A', 'C'}, {'R', 'x', 'A', 'A', 'D'}};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "Message 0";
char txNum = '0';

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second


void setup() {

  Serial.begin(9600);
  Serial.println("SimpleTx Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.setRetries(3, 5); // delay, count
  int numSlaves=4;
  byte n = 0;
  //radio.openReadingPipe(1,masterAddress);
  for(n < numSlaves; n++;)
  {
  radio.openWritingPipe(slaveAddress[n]);
    // send data to slave N
  }
  
  radio.enableDynamicPayloads() ;
  radio.setAutoAck( false ) ;
}

//====================

void loop() {
  currentMillis = millis();
  if (currentMillis - prevMillis >= txIntervalMillis) {
    send();
    prevMillis = millis();
  }
}

//====================

void send() {

  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("Data Sent ");
  Serial.print(dataToSend);
  if (rslt) {
    Serial.println("  Acknowledge received");
    updateMessage();
  }
  else {
    Serial.println("  Tx failed");
  }
}

//================

void updateMessage() {
  // so you can see that new data is being sent
  txNum += 1;
  if (txNum > '9') {
    txNum = '0';
  }
  dataToSend[8] = txNum;
}

Image from Reply #9 so we don’t have to download it. See this Image Guide

e1118e24c055b357a5c91c25ecd0e5fb9e07e07e.jpg

…R

Sorry, I can't read that image. Please post the output as text.

If you are sending a message separately to each slave (which is what Reply #4 implies) why have you turned off the acknowledgement in the code in Reply #9?

Please edit Reply #9 and add code tags.

...R

  for(n < numSlaves; n++;)
  {
  radio.openWritingPipe(slaveAddress[n]);
    // send data to slave N
  }

This does not send any data to any node.

The code in Reply #9

Serial Print (Slave1) Serial Print (Slave2) Master
SimpleRx Starting SimpleRx Starting
Data received Data received SimpleTx Starting
Data received Data received
Data received Data received
Data received Data received

Data received
Data received

Yes, in the master ex-snippet setup. Which was the only code in the original master-code.

Do not change posted code.
Adding code tags and a new post with the complete code would have been better. IMHO

Do not enable dynamic payloads if you do not want to use the feature.

I feel disabling acknowledges globally just to have a broadcast channel is too crude.

In the setup for the slaves startListening should be called after all static configurations.

You are only sending to the last address in your table, the two slaves should not receive any packet.

The slaves should listen to the same address anyway (for a broadcast channel),
there is no sense in using distict addresses and no acknowledgements.

Whandall:

  for(n < numSlaves; n++;)

{
  radio.openWritingPipe(slaveAddress[n]);
    // send data to slave N
  }



This does not send any data to any node.

Why not, what is missing?

…R

radio.write(dataToSend, dataLen);

the code does not work :frowning:

Your Master output does not show any sign of a send, so there is an additional problem.

Edit: the presented code should not/can not produce the shown output.