NRF24L01 master requests data from slave.

Hi

I’ve recently started working on a small RC project with NRF modules.
I’m using two nanos and two generic NRF24L01 modules. They are set up correctly and they are indeed communicating.

I have a master controlling a slave by sending simple chars. Every few seconds i need the slave to send back some sensor data to the master.
I’m trying to do this by sending a special character (“S”), that when the slave receives, stops listening and starts transmitting momentarily. But unfortunately that doesn’t seem to work .

I’m attaching the small crude sketches. No sensor data in them, just the slave trying to send the char back to the master, and the master trying to acknowledge that.

Transmitter

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

RF24 radio(7, 8);

byte addresses[][6] = {"1Node", "2Node"};
unsigned long prevmillis=0;
void setup()
{
  pinMode(A1,INPUT_PULLUP);
  pinMode(A2,INPUT_PULLUP);
  pinMode(A3,INPUT_PULLUP);
  pinMode(A4,INPUT_PULLUP);

 
  Serial.begin(9600);
  
  radio.begin();
  radio.setRetries(15, 15);
  radio.openWritingPipe(addresses[0]);
  radio.openReadingPipe(1, addresses[1]);
  radio.setDataRate(RF24_250KBPS);
  radio.stopListening();
}

void loop()
{
  int up = digitalRead(A1);
  int down = digitalRead(A2);
  int left = digitalRead(A3);
  int right = digitalRead(A4);

  if (up==LOW){ 
    char text[]="u";
    radio.write(&text, sizeof(text));
    }
  else if (down==LOW){ 
    char text[]="d";
    radio.write(&text, sizeof(text));
    }
  else if (right==LOW){ 
    char text[]="r";
    radio.write(&text, sizeof(text));
    }
  else if (left==LOW){ 
    char text[]="l";
    radio.write(&text, sizeof(text));
    }
   else{
    char text[]="n";
    radio.write(&text, sizeof(text));
    }



   unsigned long currentmillis=millis();
if (currentmillis-prevmillis >=2000){
  prevmillis=currentmillis;
  char text[]="S";
  radio.write(&text, sizeof(text));
  radio.startListening();
  
 if(radio.available())  {  
      Serial.print("OK");
      radio.stopListening();
      }
   
}
  
}

Receiver

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

RF24 radio(7, 8);

byte addresses[][6] = {"1Node", "2Node"};
 
void setup()
{
  
  Serial.begin(9600);
  
  radio.begin();
  radio.setRetries(15, 15);
  radio.openWritingPipe(addresses[1]);
  radio.openReadingPipe(1, addresses[0]);
  radio.setDataRate(RF24_250KBPS);
  radio.startListening();
}

void loop()
{
  if (radio.available())
  {
    char text[] = {0};
    radio.read(&text, sizeof(text));
     Serial.println(text);

    if (strcmp(text, "u")  == 0)  {
//    Serial.println(text);

  }    
  else if (strcmp(text, "d")  == 0) {
//    Serial.println(text);

  }    
    
  else if (strcmp(text, "l")  == 0) {
//    Serial.println(text);
    
    }   
else if (strcmp(text, "r")  == 0) {
//    Serial.println(text);
    }   

else if (strcmp(text, "S")  == 0) {
    radio.stopListening();
    radio.write(&text,sizeof(text));
    radio.startListening();
    

//    Serial.println(text);
    } 
   
  else {
    digitalWrite(A1, LOW);
    digitalWrite(A2, LOW);
    digitalWrite(A3, LOW);
    digitalWrite(A4, LOW);
//    Serial.println(text);
  }    
    


   
  }
}

Have a look at this Simple nRF24L01+ Tutorial.

If the slave must act in response to a message from the master then have a look at the third example. However you should also look at the second example as it could make life a lot simpler if your project can be adapted to it.

If you are dealing with single characters use single quotes 'S' rather than "S" and then lots of things are easier. For example you can have

char text = 'U';

and

if (text == 'S') {

...R

Yes i've already looked at your examples. I'm really grateful you took the time to make them.

The second one with the ackpayloads doesn't want to play nice though, all i i get is 'tx failed', always.

The role switching one works perfect every time but i'm not able to implement it's logic in my sketches for some reason. I must be missing something rudimentary...

steliosp:
The second one with the ackpayloads doesn't want to play nice though, all i i get is 'tx failed', always.

The role switching one works perfect every time

If you have the role-switching example working perfectly between your two nRF24s then I can think of no reason why the ackpayload example would not work.

It is a good idea to depower the Arduino after uploading a program to make sure the nRF24 resets. The normal Arduino reset does not reset the nRF24.

but i'm not able to implement it's logic in my sketches for some reason. I must be missing something rudimentary...

If you post your best attempt I will have a look at it.

...R

Robin2:
If you have the role-switching example working perfectly between your two nRF24s then I can think of no reason why the ackpayload example would not work.

I can think of no reason too, but it doesn’t.I should also note that i’m using the libraby that you’re proposing.

If you post your best attempt I will have a look at it.

Well this is as simple as it gets:

Transmiter

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

RF24 radio(7, 8);

byte addresses[][6] = {"1Node", "2Node"};
unsigned long prevmillis=0;
void setup()
{ 
  Serial.begin(9600);
  
  radio.begin();
  radio.setPALevel(RF24_PA_MIN);
  radio.setRetries(0, 15);
  radio.openWritingPipe(addresses[1]);
  radio.openReadingPipe(1, addresses[0]);
  radio.setDataRate(RF24_250KBPS);
  radio.stopListening();
}


void loop(){
  
char text[]="A";
    radio.write(&text, sizeof(text));


// Sending 'B' char every 4 seconds  

unsigned long currentmillis=millis();
if (currentmillis-prevmillis >=4000){
  prevmillis=currentmillis;
  char text[]="B";
  radio.write(&text, sizeof(text));
  
  radio.startListening();  //Trying to listen after sending 'B'
  
     while (!radio.available()){  //Keep trying.
        Serial.println("retrying");

     }
     
  radio.stopListening();
  
  Serial.println("received");
  
  
    
} 


  
}

Receiver

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

RF24 radio(7, 8);
byte addresses[][6] = {"1Node", "2Node"};
char text;
void setup()
{
  Serial.begin(9600);
  

  radio.begin();
  radio.setPALevel(RF24_PA_MIN);
  radio.setRetries(0, 15);
  radio.openWritingPipe(addresses[0]);
  radio.openReadingPipe(1, addresses[1]);
  radio.setDataRate(RF24_250KBPS);
  radio.startListening();
}

void loop(){


  if (radio.available())
  {
    radio.read(&text, sizeof(text));
         Serial.println(text);

   }  

// Checking if the character we received is B so we could a response

if (text == 'B'){
  Serial.println("B received");
  radio.stopListening();
  
  while( !radio.write(&text, sizeof(text)));   // Keep trying with generic response
 
 radio.startListening(); 
}

 

  
}

The point is that the transmitter is always sending the character ‘A’ and every few seconds it will send the character ‘B’, then it will enter a "listening"state untill it gets a response.

The receiver, upon receiving the character ‘B’ will stop listening and will send back some data. After the data is sent it’s supposed to return to it’s listening state.

hi everyone, i have trying and trying to send a “request” from a master to one specific slave in order to resend a data back. i don’t know where is the problem. please help me

sketch_apr21a.ino (842 Bytes)

sketch_apr21b.ino (1.09 KB)

farouk95:
hi everyone, i have trying and trying to send a "request" from a master to one specific slave in order to resend a data back. i don't know where is the problem. please help me

Have you tried the examples in my Tutorial? (Link in Reply #1)

...R