How coding 1 NRF24L01 as a Tx and Rx ???

The problem is TX Code sent data to RX Code,in the RX Code should be get data from TX and sent them to SINK node

TX1 to RX1
TX2 to RX2
RX1 & RX2 to SINK (multinodes)

I have been succesfull when sent data from TX1 and 2 to RX1 and 2 by using difference pipe,when I want to sent that data to SINK node i added 3 pipe from RX1,RX2 and SINK and failed to sent data to SINK Node,anybody can help me?

this TX code

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

#define DHT1TYPE DHT11   
#define DHT1PIN A0     
#define DHT2TYPE DHT11
#define DHT2PIN A1
#define DHT3TYPE DHT11
#define DHT3PIN A2
#define DHT4TYPE DHT11
#define DHT4PIN A3
//#define DHT5TYPE DHT11
//#define DHT5PIN A4
//#define DHT6TYPE DHT11
//#define DHT6PIN A5


RF24 radio(9,10);                    
const uint64_t pipe = 0xE8E8F0F0E1LL;      
      
float t1;
float t2;
float t3;
float t4;


DHT dht1(DHT1PIN, DHT1TYPE);
DHT dht2(DHT2PIN, DHT2TYPE);
DHT dht3(DHT3PIN, DHT3TYPE);
DHT dht4(DHT4PIN, DHT4TYPE);


void setup(void)
{
  Serial.begin(9600);
  SPI.begin();
  radio.begin();
  radio.openWritingPipe(pipe); 
  dht1.begin();
  dht2.begin();
  dht3.begin(); 
  dht4.begin();
}

void loop(void) {                 
float t1 = dht1.readTemperature();
float t2 = dht2.readTemperature();
float t3 = dht3.readTemperature();
float t4 = dht4.readTemperature();

radio.write(&t1, sizeof(float));
radio.write(&t2, sizeof(float));
radio.write(&t3, sizeof(float));
radio.write(&t4, sizeof(float));
delay(1000);


Serial.print("Temp1: ");
Serial.println(t1);
delay(500);

Serial.print("Temp2: ");
Serial.println(t2);
delay(500);

Serial.print("Temp3: ");
Serial.println(t3);
delay(500);

Serial.print("Temp4: ");
Serial.println(t4);
delay(500);


}

this RX Code

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

RF24 radio(9,10);
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };

float t1;
float t2;
float t3;
float t4;

void setup(void) {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1, pipes[1]);
  radio.startListening();
  delay(1000);

  Serial.begin(9600);
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(pipes[1]);
  radio.startListening();
}

void loop(void)
{
if ( radio.available() ) {

radio.read(&t1, sizeof(t1));
Serial.print("Temp1: ");
Serial.println(t1);
delay(500);

radio.read(&t2, sizeof(t2));
Serial.print("Temp2: ");
Serial.println(t2);
delay(500);


radio.read(&t3, sizeof(t3));
Serial.print("Temp3: ");
Serial.println(t3);
delay(500);


radio.read(&t4, sizeof(t4));
Serial.print("Temp4: ");
Serial.println(t4);
delay(500);

//radio.read(&t5, sizeof(t5));
//Serial.print("Temp5: ");
//Serial.println(t5);
//delay(500);

radio.write(&t1, sizeof(float));
radio.write(&t2, sizeof(float));
radio.write(&t3, sizeof(float));
radio.write(&t4, sizeof(float));
delay(1000);

}
}

this SINK node

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

RF24 radio(9,10);
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };

float t1,t2,t3,t4;
float h1,h2,h3,h4;

void setup(void) {
Serial.begin(9600);
radio.begin();
radio.setDataRate(RF24_250KBPS);
radio.openReadingPipe(1, pipes[1]);
radio.openReadingPipe(2, pipes[2]);
radio.startListening();
delay(1000);
}

void loop(void) {
if ( radio.available() )
{
  
delay(50);
radio.read(&t1, sizeof(t1));
Serial.print("T1: ");
Serial.println(t1);

radio.read(&t2, sizeof(t2));
Serial.print("T2: ");
Serial.println(t2);

radio.read(&t3, sizeof(t3));
Serial.print("T3: ");
Serial.println(t3);

radio.read(&t4, sizeof(t4));
Serial.print("T4: ");
Serial.println(t4);

delay(500);

radio.read(&h1, sizeof(h1));
Serial.print("H1: ");
Serial.println(h1);

radio.read(&h2, sizeof(h2));
Serial.print("H2: ");
Serial.println(h2);

radio.read(&h3, sizeof(h3));
Serial.print("H3: ");
Serial.println(h3);

radio.read(&h4, sizeof(h4));
Serial.print("H4: ");
Serial.println(h4);
}
else
{
Serial.println("No radio available");
}
delay(1000);
}

Have a look at this Simple nRF24L01+ Tutorial

Get the communication working reliably before you introduce other features such as sensors.

...R

I have read that,and I still cant understand how to solve my problem :frowning:

tumanggeryoel:
I have read that,and I still cant understand how to solve my problem :frowning:

If you explain what part of my tutorial you don’t understand I will try to help.

Have you tried any of my examples? Did it work?

…R

I have tried the two way communication both of them,the problem is for my project what kind of our example that can solve my problem sir?

You need to tell me how you want your communication to work - I can't figure that out from your Original Post. Describe the requirement in English - not code. Pretend you are explaining it to your grandmother.

Also give some examples of the data you want to send.

...R

Hi guys i have some trouble when try to sent data sensor by multinodes method using nfr4l01
Here is the Tx code

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

#define DHT2TYPE DHT11   
#define DHT2PIN A1    



RF24 radio(9,10);                    
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };     
DHT dht2(DHT2PIN, DHT2TYPE);

float t2; 

struct payload{
  float temp;
};


void setup(void) {
  Serial.begin(9600);
  dht2.begin(); 
  SPI.begin();
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(pipes[2]);
  radio.startListening();
}

void loop(void) { 
  
Serial.println("Sending...");

float t2 = dht2.readTemperature();



Serial.print("Temp2: ");
Serial.println(t2);
delay(500);


payload data = {t2};
radio.write(&t2, sizeof(data));
delay(600);

//bool ok = radio.write(&t2, sizeof(float)); 
  
}  


//bool mantap = radio.write(&t1, sizeof(t1)); 
  // if (mantap)
      //Serial.println("ok.");
    //else
      //Serial.println("failed.");
  //delay(500);

the RX code

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

RF24 radio(9,10);
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };    

float t2;
struct payload{
  float temp;
};


void setup(void) {
  Serial.begin(9600);
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(1, pipes[1]);
  radio.openReadingPipe(2, pipes[2]);
  radio.startListening();
  delay(50);
}

void loop(void)
{
if ( radio.available() ) {
  delay(50);
  payload dataREV;
  radio.read(&t2, sizeof(dataREV));

t2 = dataREV.temp;
Serial.print("Temp: ");
Serial.println(t2);
delay(50);
}

else 
{
Serial.println("No radio available");
}
delay(500);  
}

And the display of RX serial monitor is No Radio Available,while when I’m using just 1 pipe that’s work to sent data :frowning:

I want to make large farming monitoring system like this :

1.SENSOR

1A = 2 Sensor (DHT11) + Arduino Uno + NRF24L01
1B = 2 Sensor (DHT11) + Arduino Uno + NRF24L01

2.NODE

2A = 1 Arduino Uno + NRF24L01
2B = 1 Arduino Uno + NRF24L01

  1. SINK NODE

Arduino Uno + NRF24L01

my goal from this project is :
1A connected to 2A by multinodes (3 pipes)
1B connected to 2B by multinodes (3 pipes)

2A and 2B connected to 3 (SINK NODE) by multinodes and in the final,SINK NODE displayed data that sent by 1A and B in the serial monitor

Thats it Sir,pardon me for my bad english,i hope u can understand and help me

Thankss

That is somewhat clearer but I still have some questions.

Am I correct to interpret what you are saying like this.
There are 5 Arduinos (1A, 1B, 2A, 2B and S). 1A sends to 2A. 1B sends to 2B. And both 2A and 2B send to S.
If that is not right, please tell me the correct version.

Assuming I have understood correctly, here are my questions

  • How far apart is each Arduino from its nearest neighbour?
  • How often do the Arduinos 1A and 1B need to send data? (how many times per second or per minute).
  • Do the Arduinos 2A and 2B collect data from sensors as well as receiving data from 1A and 1B?
  • How often do Arduinos 2A and 2B send data to Arduino S?
  • Does Arduino S need to send data to 2A or 2B?
  • Do Arduinos 2A and 2B need to send data to 1A or 1B?

...R

@tumanggeryoel, please do not cross-post. Threads merged.

Robin2:
That is somewhat clearer but I still have some questions.

Am I correct to interpret what you are saying like this.
There are 5 Arduinos (1A, 1B, 2A, 2B and S). 1A sends to 2A. 1B sends to 2B. And both 2A and 2B send to S.
If that is not right, please tell me the correct version.

Assuming I have understood correctly, here are my questions

  • How far apart is each Arduino from its nearest neighbour?
  • How often do the Arduinos 1A and 1B need to send data? (how many times per second or per minute).
  • Do the Arduinos 2A and 2B collect data from sensors as well as receiving data from 1A and 1B?
  • How often do Arduinos 2A and 2B send data to Arduino S?
  • Does Arduino S need to send data to 2A or 2B?
  • Do Arduinos 2A and 2B need to send data to 1A or 1B?

...R

Yes that's correct sir like that
1.The distance of each arduinos is about 10 cm till 50 cm
2. Sent data per minute
3. Yes like the data that get from 1A and B
4.About 30 seconds sent to SINK
5. In my thought so far that in the SINK doesn't have to sent data back to 2A or B,if can't like that,it doesnt matter to sent response back for the system work
6. The answer same like above answer above,the better choices for this system (doesnt matter if sent data back or not)

tumanggeryoel:
1.The distance of each arduinos is about 10 cm till 50 cm

With a short distance like that you will make life a lot easier for yourself if all the Arduinos 1A, 1B, 2A and 2B communicate directly with S. That may also allow the same program to be used on 1A, 1B, 2A and 2B.

I forgot to ask you how is each Arduino powered. If it is practical to have them all powered up all of the time then the system in the second example in my Simple nRF24L01+ Tutorial will be suitable and simple. The Arduino S will act as Master and communicate with each of the others in turn and receive data from each of them.

If it is necessary for each of the "slaves" (1A, 1B, 2A and 2B) to sleep to save energy then that won't work. The Master will need to listen all the time and there will be a risk of data collisions where 2 slaves try to send at the same time. If you use different Pipes on the Master to save the data from each slave in different buffers it will slightly improve performance because that way it can store a few messages before your program reads them. Another option is to use a single Pipe and include an ID in each message that identifies which slave it comes from. Note that the nRF24 has only 1 wireless receiver so using multiple Pipes does not reduce the risk of data collisions.

I don't understand from your point 5 whether you do, or do not want to send data from the Master to the slaves.

...R

Thanks for the information.

I have a problem with Internet conection and I have already solved it.

Robin2:
With a short distance like that you will make life a lot easier for yourself if all the Arduinos 1A, 1B, 2A and 2B communicate directly with S. That may also allow the same program to be used on 1A, 1B, 2A and 2B.

I forgot to ask you how is each Arduino powered. If it is practical to have them all powered up all of the time then the system in the second example in my Simple nRF24L01+ Tutorial will be suitable and simple. The Arduino S will act as Master and communicate with each of the others in turn and receive data from each of them.

If it is necessary for each of the "slaves" (1A, 1B, 2A and 2B) to sleep to save energy then that won't work. The Master will need to listen all the time and there will be a risk of data collisions where 2 slaves try to send at the same time. If you use different Pipes on the Master to save the data from each slave in different buffers it will slightly improve performance because that way it can store a few messages before your program reads them. Another option is to use a single Pipe and include an ID in each message that identifies which slave it comes from. Note that the nRF24 has only 1 wireless receiver so using multiple Pipes does not reduce the risk of data collisions.

I don't understand from your point 5 whether you do, or do not want to send data from the Master to the slaves.

...R

in point 5 i thinks its necessary to sent back to 2A/B and 1A/B not the data but just a command like if Master want A to sent the data there so only A that can sent data at the time

So what is your advice and step to do for my project sir?

Thanks

asepsukandar:
So what is your advice and step to do for my project sir?

I know nothing about your project. You should start your own Thread with a description of your problem and the code you are using,

In this Thread I am trying to help @tumanggeryoel

...R

My problem is when using your MultiTXPayload two transmission example and added sensor data as value and the Master doesn’t received that value sent by slave

MultiTXCode

// MultiTxAckPayload - the master or the transmitter
//   works with two Arduinos as slaves
//     each slave should the SimpleRxAckPayload program
//       one with the adress {'R','x','A','A','A'}
//         and the other with {'R','x','A','A','B'}

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


#define CE_PIN   9
#define CSN_PIN 10

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';

float t1;
float h1;
float t2;
float h2;   // to hold the two values coming from the slave

struct payload{
  float temp1;
  float hum1; 
  float temp2;
  float hum2;   
  };
  
bool newData = false;

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

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

void setup() {

    Serial.begin(9600);
    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.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);
        
        payload dataREV;
        if (rslt) {
            if ( radio.isAckPayloadAvailable() ) {
                radio.read(&dataREV, sizeof(dataREV));
                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) {

       if (byte n = 0) {

        
       payload dataREV; 
          
       t1 = dataREV.temp1;        
        Serial.print("Temperature: ");
        Serial.println(t1);
        delay(500);

       h1 = dataREV.hum1;
       Serial.print("Humidity: ");
       Serial.println(h1);
       delay(500);
       }

       else  {

        
       payload dataREV; 

       t2 = dataREV.temp2;        
        Serial.print("Temperature: ");
        Serial.println(t2);
        delay(500);

       h2 = dataREV.hum2;
        Serial.print("Humidity: ");
        Serial.println(h2);
        delay(500);
       }
        
        newData = false;
        delay(1000);
       
    }
}

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

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

RX1 code

// SimpleRx - the slave or the receiver

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

#define DHT1TYPE DHT11   
#define DHT1PIN A0

#define CE_PIN   9
#define CSN_PIN 10

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
float t1;
float h1;

bool newData = false;

DHT dht1(DHT1PIN, DHT1TYPE);

struct payload{
  float temp1;
  float hum1;  
  };

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

void setup() {

    Serial.begin(9600);

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

    dht1.begin();

    radio.enableAckPayload();
    payload data = {t1,h1};
    radio.writeAckPayload(1, &data, sizeof(data)); // pre-load data

    radio.startListening();
}

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

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

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

void getData() {


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

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

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

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

void updateReplyData() {

  float t1 = dht1.readTemperature();
  float h1 = dht1.readHumidity();

  Serial.print("Temperature: ");
        Serial.println(t1);
        delay(500);

        Serial.print("Humidity: ");
        Serial.println(h1);
        delay(500);

  
  payload data = {t1,h1};

  radio.writeAckPayload(1, &data, sizeof(data)); // load the payload for the next time
}

RX2 Code

// SimpleRx - the slave or the receiver

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

#define DHT1TYPE DHT11   
#define DHT1PIN A0

#define CE_PIN   9
#define CSN_PIN 10

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

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
float t2;
float h2;

bool newData = false;

DHT dht1(DHT1PIN, DHT1TYPE);

struct payload{
  float temp2;
  float hum2;  
  };

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

void setup() {

    Serial.begin(9600);

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

    dht1.begin();

    radio.enableAckPayload();
    payload data = {t2,h2};
    radio.writeAckPayload(1, &data, sizeof(data)); // pre-load data

    radio.startListening();
}

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

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

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

void getData() {


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

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

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

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

void updateReplyData() {

  float t2 = dht1.readTemperature();
  float h2 = dht1.readHumidity();

      
        Serial.print("Temperature: ");
        Serial.println(t2);
        delay(500);

        Serial.print("Humidity: ");
        Serial.println(h2);
        delay(500);

 
  payload data = {t2,h2};

  radio.writeAckPayload(1, &data, sizeof(data)); // load the payload for the next time
}
    payload data = {t1,h1};
    radio.writeAckPayload(1, &data, sizeof(data)); // pre-load data
    radio.startListening();

Have a look at the sourcecode of startListening, it the TX fifos,
so your preload is removed before it can be sent.

void RF24::startListening(void)
  697 {
  698  #if !defined (RF24_TINY) && ! defined(LITTLEWIRE)
  699   powerUp();
  700  #endif
  701   write_register(NRF_CONFIG, read_register(NRF_CONFIG) | _BV(PRIM_RX));
  702   write_register(NRF_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
  703   ce(HIGH);
  704   // Restore the pipe0 adddress, if exists
  705   if (pipe0_reading_address[0] > 0){
  706     write_register(RX_ADDR_P0, pipe0_reading_address, addr_width);  
  707   }else{
  708     closeReadingPipe(0);
  709   }
  710 
  711   // Flush buffers
  712   //flush_rx();
  713   if(read_register(FEATURE) & _BV(EN_ACK_PAY)){
  714     flush_tx();
  715   }
  716 
  717   // Go!
  718   //delayMicroseconds(100);
  719 }

You have made a lot of changes to my code so I can't say for sure if you have broken it or not

One thing I have noticed is that you have a different sized payload in the master compared to the slaves. What you read from the payload must match the size (in bytes) of what was loaded in at the other end.

I don't think @Whandall's comment in Reply #16 is relevant because it only happens in setup() and at worst it would mean that the first item is lost.

...R

Robin2:
I don't think @Whandall's comment in Reply #16 is relevant because it only happens in setup() and at worst it would mean that the first item is lost.

You can drop the "at worst", because that behaviour is guaranteed.

Whandall:
You can drop the "at worst", because that behaviour is guaranteed.

I haven't had time to study the documentation but I presume you mean that the startListening() should come before the writeAckPayload() ?

...R