nRF24L01 receive from 2 transmitters?

I have a few Arduino boards with nRF24L01 transceivers on them. I have 2 boards sending sensor values and one to receive them and putting it in a PLX-DAQ spreadasheet. I am able to get either one to work at a time, but I have not been able to get both to send data and the other one to pick them both up at the same time.

This is what I have for one of my sending (I used the library by TMRh20)

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

RF24 myRadio (7, 8);
byte addresses[][6] = {"0"};

struct package
{
  int id=1;
  float moisture;
};


typedef struct package Package;
Package data;


void setup()
{
  Serial.begin(9600);
  delay(1000);
  myRadio.begin();  
  myRadio.setChannel(115); 
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.setDataRate( RF24_250KBPS ) ; 
  myRadio.openWritingPipe( addresses[0]);
  delay(1000);
}

void loop()
{
  myRadio.write(&data, sizeof(data)); 

  Serial.println(analogRead(A0));
  data.moisture = analogRead(A0);
  delay(1000);

}

and the respective receive:

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

RF24 myRadio (7, 8); 
struct package
{
  int id=0;
  float moisture;
};

byte addresses[][6] = {"0"}; 



typedef struct package Package;
Package data;
int row = 0;
int x = 0;
void setup() 
{
  Serial.begin(9600);
  delay(1000);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Time,Moisture");
  Serial.println("RESETTIMER");
  myRadio.begin(); 
  myRadio.setChannel(115); 
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.setDataRate( RF24_250KBPS ) ; 
  myRadio.openReadingPipe(1, addresses[0]);
  myRadio.startListening();
}


void loop()  
{

  if ( myRadio.available()) 
  {
    while (myRadio.available())
    {
      myRadio.read( &data, sizeof(data) );
    }
     Serial.print("DATA,TIME,");
  Serial.println((-10.32 * (log(data.moisture) / log(2.718)) + 72.66));
  row++;
  x++;
  if (row > 60)
  {Serial.println("CLEARDATA");
  Serial.println("ROW,SET,2");  
  row = 0;}
  }

}

then the other send

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

RF24 myRadio (7, 8);
byte addresses[][6] = {"0"};

struct package2
{
  int id=1;
  float psi;
};


typedef struct package2 Package2;
Package2 datas;


void setup()
{
  Serial.begin(9600);
  delay(1000);
  myRadio.begin();  
  myRadio.setChannel(115); 
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.setDataRate( RF24_250KBPS ) ; 
  myRadio.openWritingPipe( addresses[0]);
  delay(1000);
}

void loop()
{
  myRadio.write(&datas, sizeof(datas)); 

  Serial.println(analogRead(A0));
  datas.psi = analogRead(A0);
  delay(1000);

}

and the receive for that

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

RF24 myRadio (7, 8); 
struct package2
{
  int id=0;
  float psi;
};

byte addresses[][6] = {"0"}; 



typedef struct package2 Package2;
Package2 datas;
int row = 0;
int x = 0;
void setup() 
{
  Serial.begin(9600);
  delay(1000);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Time,Moisture");
  Serial.println("RESETTIMER");
  myRadio.begin(); 
  myRadio.setChannel(115); 
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.setDataRate( RF24_250KBPS ) ; 
  myRadio.openReadingPipe(1, addresses[0]);
  myRadio.startListening();
}


void loop()  
{

  if ( myRadio.available()) 
  {
    while (myRadio.available())
    {
      myRadio.read( &datas, sizeof(datas) );
    }
     Serial.print("DATA,TIME,");
  Serial.println(0.29325513196*datas.psi);
  row++;
  x++;
  if (row > 60)
  {Serial.println("CLEARDATA");
  Serial.println("ROW,SET,2");  
  row = 0;}
  }

}

this all works fine, but I am having trouble getting both of them. I guess to start off with, is it possible in the first place? I tried something like this:

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

RF24 myRadio (7, 8); 
struct package
{
  int id=0;
  float moisture;
};



struct package2
{
  int id=0;
  float psi;
};
byte addresses[][6] = {"0"}; 
typedef struct package Package;
Package data;
int row = 0;
int x = 0;
typedef struct package2 Package2;
Package2 datas;
void setup() 
{
  Serial.begin(9600);
  delay(1000);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Time,Moisture,Air Pressure");
  Serial.println("RESETTIMER");
  myRadio.begin(); 
  myRadio.setChannel(115); 
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.setDataRate( RF24_250KBPS ) ; 
  myRadio.openReadingPipe(1, addresses[0]);
   myRadio.setChannel(95); 
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.setDataRate( RF24_250KBPS ) ; 
  myRadio.openReadingPipe(1, addresses[0]);
  myRadio.startListening();
}


void loop()  
{

  if ( myRadio.available()) 
  {
    while (myRadio.available())
    {
  myRadio.setChannel(115);
      myRadio.read( &data, sizeof(data) );
    
     Serial.print("DATA,TIME,");
  Serial.print((-10.32 * (log(data.moisture) / log(2.718)) + 72.66));
  Serial.print(",");
  
  myRadio.setChannel(95);
  myRadio.read( &datas, sizeof(datas) );
  Serial.println(0.29325513196*datas.psi);
  row++;
  x++;}
  if (row > 60)
  {Serial.println("CLEARDATA");
  Serial.println("ROW,SET,2");  
  row = 0;}
  }

}

obviously, I changed the channel on the second sender to match. I did this because I figured they would interfere with each other if they were sending on the same channel. Anyway, I don’t 100% get how they work, so any help would be appreciated.

It's been a while since I did anything useful with NFR2400's, but aren't you supposed to set a 'sender' ID somewhere?

Well first of all:
Having 2 transmitters and 1 receiver is like having 2 keyboards on one PC and 2 people who don’t know from each other try to write a text that make sense…
You can’t send at the same time two different things on the same frequency. If you split the transmission and let each one send at a time it might work. The other thing is to open up the bandwidth and receiving from 2 close-by channels (but I don’t think the receiver is able to do that). Therefore you need a separation of the input in order for the receiver to know what came from whom.

But that might be all to difficoult. Can you connect your two sensors and send both data from one device? Or use 2 receivers on different channels. Third option: if you have a transceiver, a transmitter and a receiver you can send from sensor 1 to sensor 2 bundel the information and transmitt on a different frequency to the receiverstation. But that would implicate modulating the bandwidth and might come to interferences because they might be to close…

Well I would go with 2 receivers it’s the easiest.

Best regards
MajorProb

Major,

Pipes ring a bell?

You cannot have the two transmitters sending at the same time - they will just make garbage of each other's signal.

That said, I think the simplest solution is to put the "receive" Arduino in charge by getting it to request data from each of the others in turn.

The pair of programs in this link are derived from a model train control system that is intended to work like that. The code in the master program can easily be adapted to talk to several slaves. (They use the TMRh20 library).

Note that I am using the ackPayload facility which makes it very easy for the slaves to send data - assuming the data will fit in a single 32 byte packet. By using ackPayload there is no need for your program to make the devices switch between listening and writing. The master is always in write mode and the slaves are always in listen mode. The process of sending the ackPayload is completely invisible to your code.

Also there is no need to use multiple pipes. In any case multiple pipes do not get around the problem of simultaneous transmissions on the same frequency interfering with each other.

...R

While true that the radio can only receive on xmit at any one point in time,,, if you set up the senders to poll and wait for acknowledgment (NACK/ACK) and do re-xmit on NACK, you can get what seems like (in human terms) simultaneous multi-receives by using pipes on a single freq channel.

123Splat:
While true that the radio can only receive on xmit at any one point in time, if you set up the senders to poll and wait for acknowledgment (NACK/ACK) and do re-xmit on NACK, you can get what seems like (in human terms) simultaneous multi-receives by using pipes on a single freq channel.

I agree. But it seems more complex and I doubt if it performs any better than a polling system because the polling system guarantees that there will be no data collisions.

…R

after some consideration, I agree. It actually is a more complex way to do the same thing. Oh well. I think I just got caught up in the capabilities of the Nordic system and forgot practicality.