Go Down

Topic: NRF24L01 master requests data from slave. (Read 503 times) previous topic - next topic

steliosp

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
Code: [Select]

#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
Code: [Select]

#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);
  }   
   


   
  }
}

Robin2

#1
Sep 12, 2018, 06:38 pm Last Edit: Sep 12, 2018, 06:40 pm by Robin2
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
Code: [Select]
char text = 'U';
and
Code: [Select]
if (text == 'S') {

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

steliosp

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...

Robin2

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.

Quote
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
Two or three hours spent thinking and reading documentation solves most programming problems.

steliosp

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.




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

Well this is as simple as it gets:

Transmiter

Code: [Select]

#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

Code: [Select]

#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.



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

Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up