RF24Network, multiple nrf24l01+ and DS18B20

Hi all,

My first post here, been testing stuff with Arduino for a couple of weeks now. The idea is to build a network of sensors in the house.

So, the hardware and the sketches i’m working on.

The UNO, which is the base who’s recieving data.

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <Wire.h>

RF24 radio(5,6); 
RF24Network network(radio);
const uint16_t this_node = 00;
const uint16_t other_node = 01;

struct payload_t
{
/*unsigned long temp1;
unsigned long temp2;
*/
float temp1;
float temp2;
}; 

void setup(void)
{
Serial.begin(9600);
Serial.println("RF24 Network Rx-DS18B20");
SPI.begin();
radio.begin();
network.begin(/*channel*/ 88, /*node address*/ this_node); 
}
void loop(void)
{
network.update();
while ( network.available())
{
RF24NetworkHeader header;
payload_t payload;
network.read(header,&payload,sizeof(payload)); 
Serial.print("Temp1= "); 
Serial.print(payload.temp1);
Serial.println(" C");
Serial.print("Temp2= "); 
Serial.print(payload.temp2);
Serial.println(" C");
}}

One of the TX is a NANO with this sketch

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h> 
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>

#define ONE_WIRE_BUS 4

int numbers[6];///16

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Sonda0 = { 0x28, 0xFF, 0x32, 0xD0, 0x4C, 0x04, 0x00, 0xFF };

RF24 radio(9,10);
RF24Network network(radio);
const uint16_t this_node = 01;
const uint16_t other_node = 00;

const unsigned long interval = 2000; //ms
unsigned long last_sent;
unsigned long packets_sent;

struct payload_t
{
//unsigned long temp1;
float temp1;
}; 

void setup() 
{
Serial.begin(9600);

sensors.begin();
sensors.setResolution(Sonda0, 12);
Serial.println("RF24 Network Tx-DS18B20"); 
SPI.begin();
radio.begin();
network.begin(/*channel*/ 88, /*node address*/ this_node);
}

void loop(void) {
sensors.requestTemperatures(); 
delay(5000); 
Serial.print("DS18B20 = ");
Serial.print(" ");
Serial.print(sensors.getTempC(Sonda0)); 
Serial.println(" C");

float sizeofpayload;
network.update();

unsigned long now = millis();

if ( now - last_sent >= interval )
{
last_sent = now;

float sens1 = (sensors.getTempC(Sonda0));
float temp1 = {sens1};
payload_t payload = {sens1};
RF24NetworkHeader header(/*to node*/ other_node);
bool ok1 = network.write(header,&payload,sizeof(payload)); 
}
}

And the final and last is a ProMini with this sketch

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h> 
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>

#define ONE_WIRE_BUS 2

int numbers[6];///16

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Sonda0 = { 0x28, 0xFF, 0xF9, 0x36, 0x4B, 0x04, 0x00, 0x97 };

RF24 radio(9,10);
RF24Network network(radio);
const uint16_t this_node = 01;
const uint16_t other_node = 00;

const unsigned long interval = 2000; //ms
unsigned long last_sent;
unsigned long packets_sent;

struct payload_t
{
//unsigned long temp2;
float temp2;
}; 

void setup() 
{
Serial.begin(9600);

sensors.begin();
sensors.setResolution(Sonda0, 12);
Serial.println("RF24 Network Tx-DS18B20"); 
SPI.begin();
radio.begin();
network.begin(/*channel*/ 88, /*node address*/ this_node);
}

void loop(void) {
sensors.requestTemperatures(); 
delay(5000); 
Serial.print("DS18B20 = ");
Serial.print(" ");
Serial.print(sensors.getTempC(Sonda0)); 
Serial.println(" C");

float sizeofpayload;
network.update();

unsigned long now = millis();

if ( now - last_sent >= interval )
{
last_sent = now;

float sens0 = (sensors.getTempC(Sonda0));
float temp2 = {sens0};
payload_t payload = {sens0};
RF24NetworkHeader header(/*to node*/ other_node);
bool ok1 = network.write(header,&payload,sizeof(payload)); 
}
}

Both the Nano and the ProMini is each equipt with a DS18B20 and sending readings fine to the Uno. However I want to separate the readings so the Nano is Temp1 and the ProMini is Temp2.

How to go about this?

The result i get is:

Temp1= 27.06 C
Temp2= 0.00 C
Temp1= 26.25 C
Temp2= 0.00 C
Temp1= 27.06 C
Temp2= 0.00 C
Temp1= 26.25 C
Temp2= 0.00 C
Temp1= 27.06 C
Temp2= 0.00 C
Temp1= 26.25 C
Temp2= 0.00 C

anyone?

To clarify...

Temp1= 27.06 C (coming from the Nano)
Temp2= 0.00 C
Temp1= 26.25 C (coming from the ProMini)

Should be...

Temp1= 27.06 C (coming from the Nano)
Temp2= 26.25 C (coming from the ProMini)

struct payload_t
{
/*unsigned long temp1;
unsigned long temp2;
*/
float temp1;
float temp2;
};
struct payload_t
{
//unsigned long temp1;
float temp1;
};
struct payload_t
{
//unsigned long temp2;
float temp2;
};

The receive and send payload structures don't match. The receiver will get one payload at a time and put it into the first variable in the struct. The program then prints out what it gets, which explains what you are seeing. It is not waiting around for a second payload to arrive.

I believe you will need to have only one sender's data in the RX struct at a time. Give the two senders different node numbers (they are now both 01), and analyse the information in the headers of the received payloads. Then you will sort the data into two streams.

Thanks cattledog, really appreciate your help.

Being new to this, i'm happy that I've come this far at all. However, I understand what you say and I understand the principle. But how to code it?
All examples I read everywhere explains this very well, but only with a base and a node, not three or more nrf24's in a network.

My best guess would be that i replace the 'float temp1' and try something like this?

TX1:

float temp[3] 
...
...
temp[0] = sensors.getTempC(Sonda0)
payload_t payload = {temp[0]};
RF24NetworkHeader header(/*to node*/ other_node);
bool ok1 = network.write(header,&payload,sizeof(payload));

TX2:

float temp[3] 
...
...
temp[1] = sensors.getTempC(Sonda0)
payload_t payload = {temp[1]};
RF24NetworkHeader header(/*to node*/ other_node);
bool ok1 = network.write(header,&payload,sizeof(payload));

RX:

float temp[3]
...
...      
Serial.print("Temp1:");
Serial.println(payload.temp[0]);
Serial.print("Temp2:");
Serial.println(payload.temp[1]);

Am I completely going in the wrong track?
Thanks for any support!

Am I completely going in the wrong track?

I believe so. I think the first thing you can do is to work with one node and a base and learn to work with the header file. Once you see how to use the header information to identify the node, then expand to a base and two nodes.

Mr Google may be of more help than I can be. I found this at http://maniacbug.wordpress.com/2012/03/30/rf24network/ and I can see that the desired output is going to be something like this

1733003: APP Received #16 24.23C / 3.21V from 053
1733709: APP Received #37 23.82C / 2.70V from 043
1734297: APP Received #109 24.46C / 3.06V from 013
1735108: APP Received #55 25.16C / 3.06V from 033
1735224: APP Received #134 22.66C / 2.71V from 031
1735286: APP Received #287 25.10C / 3.24V from 01
1735565: APP Received #299 24.79C / 3.36V from 03
1736871: APP Received #71 25.78C / 3.07V from 023
1737094: APP Received #137 22.89C / 3.01V from 041
1737119: APP Received #120 23.69C / 2.98V from 011
1737247: APP Received #17 24.23C / 3.21V from 053
1738025: APP Received #38 23.82C / 2.70V from 043

gadu:
Am I completely going in the wrong track?
Thanks for any support!

you should check out mySensors.org

There is probably a simple work around if you don't want to get into reading headers and setting up multiple node id's. It's not going to help you make much progress in understanding RF24Network.h but I think you could do something like this. Add a specific senderID in the TX and all the payload structs will look like

struct payload_t
{
byte senderID;
float temp;
};

and your loop and print out will look like this

void loop(void)
{
network.update();
while ( network.available())
{

RF24NetworkHeader header;
payload_t payload;
network.read(header,&payload,sizeof(payload)); 
Serial.print("Sender= "); 
Serial.println(payload.senderID);
Serial.print("Temp= "); 
Serial.print(payload.temp);
Serial.println(" C");
}
}

You can even add time stamps and message numbers, and all the other stuff which is included in the header :wink:

@BulldogLowell
Thanks, I'm very well aware of MySensor and Hek's incredible work he has done. However, I want to understand this. :wink:

@cattledog Big thanks! Just before bedtime I read something similar. I'll try it first thing, just have to some actual work a couple of hours. I'll report on the progress.

Well, I finally got it to present the data in a format. Don’t think it’s correct way of doing it, but it works for me.

Thanks for the tips and support @cattledog, I added a specific senderID in the TX for the Nano and ProMini. Although, I had to add it in the payload as well which I don’t think was the purpose.
Also I’m not sure if I needed to add…

struct payload_t
{
  byte senderID;
  float sens1;
};

…in the RX, but i did anyway. It presents the data like this…

Sensor: 1 Temp: 27.56 C
Sensor: 2 Temp: 27.19 C
Sensor: 1 Temp: 27.56 C
Sensor: 2 Temp: 27.19 C
Sensor: 1 Temp: 27.56 C
Sensor: 2 Temp: 27.19 C

…which is fine by me and a SQL. :slight_smile:

Attaching the sketches as a zip if someone is interested.

Again, thanks @cattledog!

UnoNanoProMini_DS18B20.zip (1.98 KB)