Multiple NFR24L01 nodes

Hi,

I’m posting this question into this part of the forum instead of the networking, because the main problem is my poor programming skills. But I’m trying. Little of the background: I bought a house and planning to throw several Arduino Nano + NFR24L01 + 1Wire temp sensors around the premises and single Uno is constantly receiving the data from these nodes. I have already this working between one TX and RX (code below). Next I need to add compatibility for more TXs. After that I have to figure out how to communicate these temperature readings from Uno to Raspberry Pi. Then I need to find some IoT cloud or something to form an online chart. And reason I’m doing this by myself is because already spent all my money into the house and I need to build this temperature system as low cost as possible :slight_smile:

If I may ask, it would be great if someone could help me adding the extra TX into this code. I have spent several evenings for exploring similar projects, but they all tend to have some kind of an exception which cant fit in to my project (I cant combine the code into mine). There seems to be several ways to form the addresses. I think my TX doesn’t have any address? How do I know which TX is sending? Is there any easy way to add the id or address without building the whole system from a scratch (even it’s one of the simpliest right now :slight_smile: )

TX

#include <DallasTemperature.h>

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


#define CE_PIN   9
#define CSN_PIN 10
#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float temp1;

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


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

float dataToSend;

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


void setup() {

    Serial.begin(9600);

    Serial.println("SimpleTx Starting");

    sensors.begin();
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}


void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
}

void send() {
    sensors.requestTemperatures();
    temp1 = sensors.getTempCByIndex(0);
    radio.write(&temp1, sizeof(temp1));
    Serial.print(temp1);
    delay(10);

RX

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

#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]; 
bool newData = false;

float temp1;

void setup() {

    Serial.begin(9600);

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

void loop() {
    getData();
}


void getData() {
    if ( radio.available() ) {
      delay(50);
      radio.read(&temp1, sizeof(temp1));
      Serial.print("Temp 1: ");
      Serial.print(temp1);
      Serial.print(" C");
      Serial.println(" ");
    }
}

That looks like you are using one of the examples from my Simple nRF24L01+ Tutorial.

The way I would deal with the multiple nRF24s is to use one as Master and treat the others as Slaves. The Master will probably be the one that is now the receiver.

Give each slave a different address and have the master call each of them in turn using the style of the second example. Each slave will put its data into the ackPayload and it will automatically go to the master when the slave recieves a message from the master. The content of the message from the master is irrelevant - its only purpose is to stimulate the acknowledgement. Doing it that way ensures that there is no risk of two slaves talking at the same time and also the master will know exactly which slave the data comes from.

In the example the address for calling the slave is in setup() and that part of the process needs to move into loop() so that all the slaves can be called. The code would be something like this

for (byte n = 0; n < numSlaves; n++) {
    radio.openWritingPipe(slaveAddress[n]);
    send();
    // code to save the response from each slave to appropriate variables
}

…R

You could have the sensor nodes send their information once a second (for instance),
and add information to the sended information that identifies the sender.
All nodes could send to the same address/pipe.

struct Packet {
  byte NodeId;
  float NodeData;
} pack;

  pack.NodeId = 'A';
...
  pack.NodeData = getValueFromSensor();
  radio.write(&pack, sizeof(pack));
...
  radio.read(&pack, sizeof(pack));
  switch (pack.NodeId) {
  case 'A':
...
    break;
  }