Trying to establish one master multiple slaves nrf24 communication

Hello,
Im working on a project where I want to put multiple devices in the same room and turn them on/off from a single control panel that would be placed somewhere in that room. I want to use nrf24l01 for this and my plan is to use one of them as a master and others as slaves. I would connect master on arduino board where I would also connect some buttons or touch sensors and the goal is when I press a certain button it sends message to all slaves in that room so they can turn on/off function that is associated with that button (each function would be differentiated with different message). Also I would like to get feedback from slaves if they received the message and if they didnt master should send message to that slave until it receives it. Wanting to go one step at a time I used Robin2 tutorial code and tried to send message between one master and 2 slaves. On the master side I put in code to send message to both slaves every 2 seconds and connected 1 led to each of them so every time slave receives that message the led should go on/off/on/off. Ive tried couple of different "versions" of code but most I could do is to be able to turn on and off on one slave while other didnt respond. Here is my latest version of code for master:

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

#define CE_PIN   7
#define CSN_PIN 8

const byte numSlaves = 2;
const byte slaveAddress[numSlaves][5] = {
        // each slave needs a different address
                            {'S','L','V','0','1'},
                            {'S','L','V','0','2'}
                        };

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

char msg[7] = "on/off";
int ackData[2] = {-1, -1}; // to hold the two values coming from the slave
bool newData = false;

void setup() {

    Serial.begin(9600);
    radio.begin();
    radio.setDataRate( RF24_250KBPS );

    radio.enableAckPayload();

    radio.setRetries(3,5); // delay, count
}


void loop() {
  for (byte n = 0; n < numSlaves; n++){
       
        radio.openWritingPipe(slaveAddress[n]);

        bool rslt;
        rslt = radio.write(&msg,sizeof(msg));
        
        if (rslt) {
            if (radio.isAckPayloadAvailable()) {
                radio.read(&ackData, sizeof(ackData));
                newData = true;
            }
            else {
                Serial.println("  Acknowledge but no data ");
            }
            
        }
        else {
            Serial.println("  Tx failed");
        } 
        
    }
    delay(2000);  
}

and for one of slaves, other slave jsut has different address and led pin:

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

#define CE_PIN   7
#define CSN_PIN 8

const byte thisSlaveAddress[5] = {'S','L','V','0','2'};

RF24 radio(CE_PIN, CSN_PIN);

char msg[7]; 
int ackData[2] = {0, 2}; 
char comp[7] = "on/off";
int led = 9;
int state = LOW;

void setup() {

    Serial.begin(9600);
    pinMode(led, OUTPUT);
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.enableAckPayload();
    radio.startListening();
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data
}

void loop() {
    if (radio.available()) {
        radio.read(&msg,sizeof(msg));
    }
    if(strcmp(msg,comp) == 0)
    {
      state= !state;
      digitalWrite(led,state);
    }
    delay(200);
}

tuadru:
Wanting to go one step at a time I used Robin2 tutorial code and tried to send message between one master and 2 slaves.

Did you try the code from my Tutorial without making any changes to it - it is much easier to help when you use code I am familiar with.

Did you notice the comment I recently added at the the Top of the Thread about the need to use an appropriate version of the RF24 library.

...R

I actually used your basic tutorial code but its only for 1 master and 1 slave so I tried adding one more address but it didnt work. Also in your code the message is updated every time and I need it to stay the same for every button every time. I downloaded library from the link you put in original post.

tuadru:
I actually used your basic tutorial code but its only for 1 master and 1 slave

There is also an example for a master communicating with two slaves.

Also in your code the message is updated every time and I need it to stay the same for every button every time.

It is best to get a basic system working before adding extra features.

I downloaded library from the link you put in original post.

That probably gets you the latest version of the library - at the time I wrote the Tutorial I did not know the library was being updated and I certainly did not expect an update that would not be backwards compatible.

If you use the Arduino IDE Library manager you can easily choose any older version. OR, on the Github page if you click on Releases you can get access to the earlier versions.

...R

Ok i installed 1.1.7. version of library and now I see the code for master for 2 slaves and I figured its literally the code I used I just made some changes to suit my needs and changed addresses. Ill try your default code with old library version, just to see if it works and if it does I dont know what changes to implement to do what I want cause I thought I already did that but it didnt work. Ill keep you updated.

tuadru:
and if it does I dont know what changes to implement to do what I want

Start with the working code and add a small amount and then test it again. If it works then add some another little bit and test that.

...R

Okey so I have started with your code for test and I get code on slave 1 but slave 0 isnt responding:

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


#define CE_PIN   7
#define CSN_PIN 8

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.stopListening();
        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;
}

slave code is the same just changed last character of address for slave 0 is A for slave 1 is B

// SimpleRxAckPayload- the slave or the receiver

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

#define CE_PIN 7
#define CSN_PIN 8

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
int ackData[2] = {109, -4000}; // the two values to be sent to the master
bool newData = false;

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

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRxAckPayload Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);

    radio.enableAckPayload();
    
    radio.startListening();

    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data
}

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

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

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

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

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

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        Serial.print(" ackPayload sent ");
        Serial.print(ackData[0]);
        Serial.print(", ");
        Serial.println(ackData[1]);
        newData = false;
    }
}

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

void updateReplyData() {
    ackData[0] -= 1;
    ackData[1] -= 1;
    if (ackData[0] < 100) {
        ackData[0] = 109;
    }
    if (ackData[1] < -4009) {
        ackData[1] = -4000;
    }
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}

Serial output on master side:
======== For Slave 0 ========
Data Sent ToSlv0 0 Tx failed

======== For Slave 1 ========
Data Sent ToSlv1 0 Acknowledge data 103, -4006

======== For Slave 0 ========
Data Sent ToSlv0 1 Tx failed

======== For Slave 1 ========
Data Sent ToSlv1 1 Acknowledge data 102, -4007

======== For Slave 0 ========
Data Sent ToSlv0 2 Tx failed

======== For Slave 1 ========
Data Sent ToSlv1 2 Acknowledge data 101, -4008

tuadru:
Okey so I have started with your code for test and I get code on slave 1 but slave 0 isnt responding:

Have you tested both slaves separately with the version of the master that just works with one slave?

...R

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.