nRF24l01+ one base station (RPi) broadcasts to multiple receivers (Arduino)

Hello all,

I am relatively new to Arduino and programming. I have successfully connected my RPi and Arduino Nano (clone) with two nRF24l01+. I am working on a home automation project and would like to switch on/off a few delays on Arduino. I am now introducing and second Arduino Nano (clone) with the third nRF24l01+. The idea is as follows. Either my RPi is going to broadcast it to both Arduinos or RPi is going to talk to each Arduino separately (is it possible?). I have been struggling with the code. This is either only one of two Arduinos (nodes) working or none. All the wiring is correct and has been double checked (the code below works on both Arduinos).

Here is the original code I have used communicating RPi-Arduino

/*

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */
/*
 Hack.lenotta.com
 Modified code of Getting Started RF24 Library
 It will switch a relay on if receive a message with text 1,
 turn it off otherwise.
 Edo
*/

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

int relay1 = 8;
int relay2 = 7;


//
// Hardware conf
//

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

RF24 radio(9, 10);
bool radioNumber = 0;

//
// Topology
//

// Radio pipe addresses for the 2 nodes to communicate.
//const uint64_t pipes[2] = { 0x65646f4e32, 0x65646f4e31 };
//const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
const uint8_t pipes[][6] = {"1Node", "2Node"};

char * convertNumberIntoArray(unsigned short number, unsigned short length) {

  char * arr = (char *) malloc(length * sizeof(char)), * curr = arr;
  do {
    *curr++ = number % 10;
    number /= 10;
  } while (number != 0);
  return arr;
}

unsigned short getId(char * rawMessage, unsigned short length) {
  unsigned short i = 0;
  unsigned short id = 0;
  for ( i = 1; i < length; i++) {
    id += rawMessage[i] * pow( 10, i - 1 );
  }
  return id;
}


unsigned short getMessage( char * rawMessage) {
  unsigned short message = rawMessage[0];
  return (unsigned short)message;
}
unsigned short getLength( unsigned int rudeMessage) {
  unsigned short length = (unsigned short)(log10((float)rudeMessage)) + 1;
  return length;
}

void setup(void)
{
  //
  // Print preamble
  //

  Serial.begin(57600);
  pinMode(relay1, OUTPUT);
  digitalWrite(relay1, HIGH);
  pinMode(relay2, OUTPUT);
  digitalWrite(relay2, HIGH);
  printf_begin();
  printf("\nRemote Switch Arduino\n\r");

  //
  // Setup and configure rf radio
  //

  radio.begin();
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.setRetries(15, 15);
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1, pipes[0]);
  radio.startListening();
  radio.printDetails();
}

int getState(unsigned short pin) {
  boolean state = digitalRead(pin);
  return state == true ? 0 : 1;
}

void doAction(unsigned short id, unsigned short action) {

  
 if ( action == 0 ) {
   digitalWrite(id, HIGH);
  } else if (id == 7) {
    digitalWrite(id, LOW);
    delay (200);
    digitalWrite(id, HIGH);
  } else {
    digitalWrite(id,LOW);
  }
 }


void sendCallback(unsigned short callback) {
  // First, stop listening so we can talk
  radio.stopListening();

  // Send the final one back.
  radio.write( &callback, sizeof(unsigned short) );
  printf("Sent response.\n\r");

  // Now, resume listening so we catch the next packets.
  radio.startListening();
}

void performAction(unsigned short rawMessage) {
  unsigned short action, id, length, callback;
  char * castedMessage;

  length = getLength(rawMessage);
  castedMessage = convertNumberIntoArray(rawMessage, length);
  action = getMessage(castedMessage);
  id = getId(castedMessage, length);

  if (action == 0 || action == 1) {
    callback = action;
    doAction(id, action);
  } else if (action == 2) {
    callback = getState(id);
  }
  sendCallback(callback);



}
void loop(void)
{

  // if there is data ready
  if ( radio.available() )
  {
    // Dump the payloads until we've gotten everything
    unsigned short message;
    bool done;
    //      char * new;
    unsigned short rawMessage;
    done = false;
    while ( radio.available() )
    {
      // Fetch the payload, and see if this was the last one.
      radio.read( &rawMessage, sizeof(unsigned long) );

      // Spew it
      printf("Got message %d...", rawMessage);

      performAction(rawMessage);

      delay(10);
    }


  }

}

Ideally, I would like to utilise the same pins on Arduinos so I need the RPi to talk to each Arduino individually. I also understand that if I want to broadcast, I need to use

radio.enableDynamicPayloads() ;
  radio.enableDynamicAck();
  //radio.setAutoAck( false ) ;

However, if I insert the above code, the communication stops.
I am using the latest TMRh20 library on all Arduinos and RPi.

Your help is highly appreciated.

Basically, the idea is that if I issue a command on the master node (RPi):

sudo ./remote -m 61 relay1

This will put D6 of Arduino (node 01) into on state (1 is on, 0 is off) and not broadcast it to all Arduinos.
Any help is appreciated

There are two main ways to manage communication via nrf24l01 modules:

  1. Using auto-ack: Each device must have a unique address. Each device must open a writing pipe with the appropriate recipient address in order to communicate with individual devices.

  2. Using no-acknowledgement/multicast: Each device must NOT use auto-ack, OR each payload must be sent using multicast. See the documentation for info.

Note: #2 generally requires some way to identify which node the payload is intended for.

This requires an understanding of the low-level radio driver and general radio operation including auto-ack, multicast, addressing etc. The RF24Network library includes all of the required features, and can make this type of thing much easier to manage.

Many thanks TMRh20

I have managed to establish communication between three nodes using your RF24Network library, but need to re-write / debug the above code as it has been written on the RF24 library.