RF24network don't route the message from 011 to 00

Hi... trying to explain my issue

I'm working to rf24network based security alarm system

actually i have 6 sensors with pir and switch contact for door on board that send their bool values to the base.

due to the limitation of 5 child to communicate directly with the base i have the necessity of route some grandchild message...

node 01,02,03 etc are ok and communicate successfully every event to 00 base.

but 011 don't communicate with the base...

maybe something wrong in my code....

i will report only 3 of my devices.. the base 00 the child 01 and the grandchild 011

this is the sketch of the base 00

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

// Constants that identify nodes
const uint16_t pi_node = 0;
const uint16_t sensor_node1 = 1;
const uint16_t sensor_node2 = 011;


// CE Pin, CSN Pin, SPI Speed

RF24 radio(9, 10);
RF24Network network(radio);

// Time between checking for packets (in ms)
const unsigned long interval = 100;

int ledpin1 = 6;
int ledpin2 = 7;
int ledpin3 = 4;
int ledpin4 = 5;

// Structure of our messages

struct message_sensor {
  bool motion;
  bool dooropen;
};
message_sensor message;
void setup ()
{
// Initialize all radio related modules
  Serial.begin(115200);
  radio.begin();
  delay(5);
  network.begin(90, pi_node);

  pinMode (ledpin1, OUTPUT);
  pinMode (ledpin2, OUTPUT);
  pinMode (ledpin3, OUTPUT);
  pinMode (ledpin4, OUTPUT);
  radio.setPALevel(RF24_PA_LOW);
  Serial.println("ready"); 
 
  
  network.update();
}
  void loop()
  {
network.update();
    // Enter this loop if there is data available to be read,
    // and continue it as long as there is more data to read
    while ( network.available() ) {
      RF24NetworkHeader header;
      message_sensor sensormessage;
      // Have a peek at the data to see the header type
       network.read(header, &sensormessage, sizeof(sensormessage));
      network.peek(header);
        Serial.println ("Data received from node ");
        Serial.println(header.from_node);
        
      if (header.type == '1') {
        // Read the message
        network.read(header, &sensormessage, sizeof(sensormessage));
        // Print the node wich sent the message
       // Serial.println ("Data received from node ");
      // Serial.println(header.from_node);
        char buffer [50];
        switch (header.from_node) {
          case sensor_node1:
            system(buffer);
            digitalWrite(ledpin1,sensormessage.motion ? 1 : 0);
            system(buffer);
            digitalWrite(ledpin2,sensormessage.dooropen ? 1 : 0);
            system(buffer);
            break;
            // read other sensor data from node 2 here
            case sensor_node2:
            system(buffer);
            digitalWrite(ledpin3,sensormessage.motion ? 1 : 0);
            system(buffer);           
            digitalWrite(ledpin4,sensormessage.dooropen ? 1 : 0);
            system(buffer);
            break;
 
          default:
            printf ("Unknown node %i\n", header.from_node);
            break;
        }
      } else {
        // This is not a type we recognize
        network.read(header, &sensormessage, sizeof(sensormessage));
        printf("Unknown message received from node %i\n", header.from_node);
      }
    }
    

  }

This is the sketch of 01 node

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <avr/sleep.h>
#include <avr/power.h>


// PIR variables
byte pirPin = 7;
int pirCalibrationTime = 30;

int PIRWake = 3;
int ContactWake = 2;

// Magnetic Door Sensor variable
byte switchPin = 6;

// Radio with CE & CSN connected
RF24 radio(9, 10);
RF24Network network(radio);

// Constants that identify this node and the node to send data to
uint16_t this_node = 01;
uint16_t parent_node = 0;

// Time between packets (in ms)
const unsigned long interval = 100;  // every sec

// Structure of our message
struct message_1 {
  bool motion;
  bool dooropen;
};
message_1 message;

// The network header initialized for this node
RF24NetworkHeader header(parent_node);

void setup(void)
{
  // Set up the Serial Monitor
  Serial.begin(115200);

  // Initialize all radio related modules
  SPI.begin();
  radio.begin();
  delay(5);
  network.begin(90, this_node);
  radio.setPALevel(RF24_PA_LOW);
  radio.setRetries(8,15);
  network.txTimeout = 553;
  
  pinMode(switchPin, INPUT);
  pinMode(ContactWake, INPUT_PULLUP);
  pinMode(PIRWake,INPUT);
  pinMode(pirPin, INPUT);
  digitalWrite(pirPin, LOW);
  Serial.println(" done");
  delay(50);
  network.update();
}

void loop() {

  // Update network data
  network.update();

  // Read door sensor: HIGH means door is open (the magnet is far enough from the switch)
  bool d = (digitalRead(switchPin) == HIGH);
  
  // Read motion: HIGH means motion is detected
  bool m = (digitalRead(pirPin) == HIGH);
   // Headers will always be type 1 for this node
  // We set it again each loop iteration because fragmentation of the messages might change this between loops
  header.type = '1';

  // Only send values if any of them are different enough from the last time we sent:
  if (m != message.motion ||
      d != message.dooropen) {
    // Construct the message we'll send
    message = (message_1){m, d };

    // Writing the message to the network means sending it
    if (network.write(header, &message, sizeof(message))) {
      Serial.print("Message sent\n"); 
    } else {
      Serial.print("Could not send message\n"); 
    }
  }

  // Wait a bit before we start over again
  delay(interval);
 // }
}

and finally This is the sketch of 011 node

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <avr/sleep.h>
#include <avr/power.h>


// PIR variables
byte pirPin = 7;
int pirCalibrationTime = 30;

int PIRWake = 3;
int ContactWake = 2;

// Magnetic Door Sensor variable
byte switchPin = 6;

// Radio with CE & CSN connected
RF24 radio(9, 10);
RF24Network network(radio);

// Constants that identify this node and the node to send data to
uint16_t this_node = 011;
uint16_t parent_node = 0;

// Time between packets (in ms)
const unsigned long interval = 100;  // every sec

// Structure of our message
struct message_1 {
  bool motion;
  bool dooropen;
};
message_1 message;

// The network header initialized for this node
RF24NetworkHeader header(parent_node);

void setup(void)
{
  // Set up the Serial Monitor
  Serial.begin(115200);

  // Initialize all radio related modules
  SPI.begin();
  radio.begin();
  delay(5);
  network.begin(90, this_node);
  radio.setPALevel(RF24_PA_LOW);
  radio.setRetries(8,15);
  network.txTimeout = 553;
  
  pinMode(switchPin, INPUT);
  pinMode(ContactWake, INPUT_PULLUP);
  pinMode(PIRWake,INPUT);
  pinMode(pirPin, INPUT);
  digitalWrite(pirPin, LOW);
  Serial.println(" done");
  delay(50);
  network.update();
}

void loop() {

  // Update network data
  network.update();

  // Read door sensor: HIGH means door is open (the magnet is far enough from the switch)
  bool d = (digitalRead(switchPin) == HIGH);
  
  // Read motion: HIGH means motion is detected
  bool m = (digitalRead(pirPin) == HIGH);
   // Headers will always be type 1 for this node
  // We set it again each loop iteration because fragmentation of the messages might change this between loops
  header.type = '1';

  // Only send values if any of them are different enough from the last time we sent:
  if (m != message.motion ||
      d != message.dooropen) {
    // Construct the message we'll send
    message = (message_1){m, d };

    // Writing the message to the network means sending it
    if (network.write(header, &message, sizeof(message))) {
      Serial.print("Message sent\n"); 
    } else {
      Serial.print("Could not send message\n"); 
    }
  }

  // Wait a bit before we start over again
  delay(interval);
 // }
}

connected to the serial monitor of receiver mode i can see the headers data received from 01 node....

i cannot see the data received from 011 node. really after i try to switch on and off the contact sensor of 011 it appears on RX but is very very very rare. one time of 50 switch....

where is the error in your opinion?

thank you

You might be surprised if you try to do a small program which does

void setup()
{
   Serial.begin(115200);
   Serial.println(011); // <---- guess what is printed ?? 
}

void loop() {}

Try guessing what this program does before running it and if it did not do what you expected try to understand why, that's probably your issue. (May be)


Here is a hint

If all of your nRF24s are within in range of the base station there is probably no need to use the Network feature OR multiple pipes. Just have the base unit query each of the others in turn.

The master code in the second example in this Simple nRF24L01+ Tutorial can easily be adapted to talk to several slaves.

...R

@J-M-L yes you'right but if i put the wrong number... why sometimes the communication succeeds?

@Robin2
thank you for the reply for now your solution should be ok. its very interesting i ll try to adapt the code.

not all of my modules will be in range in the future.

my idea is to have a Base00:

a bridge 01 for internal sensors Always on and Always in range to base
a bridge 02 for external sensors Always on and Always in range to base

a series of sensors (e.g. 011 021 012 022) Always in sleep except for interrupt triggers sometimes out of range of base but in range (obviously) with parents.

so its the reason for im trying to run the network feature.

i tryng to delete the part of code of 011 that stops send message if the sensor signal doesn't change.

So my avr 011 send ever the message to base 00 without interruption.

i noticed that the base see the message from 011. but the delay is very high... 20 second... or sometimes never seen.

this is the problem.

in normal situation the message is Always lost in the air.

where can be the problem?

deejayr:
@J-M-L yes you'right but if i put the wrong number... why sometimes the communication succeeds?

so when you write 011 in a number, you are using octal notation. So octal 011 is decimal 9 (and not decimal 11). if you have another unit labeled 013 then that one is unit 11 (in decimal)

There are Only 3 nodes.... 00 01 011 ... Maybe an RF collision issue?

How rf24 handle the collisions?

deejayr:
There are Only 3 nodes.... 00 01 011 ... Maybe an RF collision issue?

How rf24 handle the collisions?

You need to study the TMRh20 network documentation carefully.

Maybe you are sending messages too often? The Network library adds a considerable overhead on top of the basic RF24 library.

...R

my nodes send message every second,only if triggered and once time only. in my sketches i decreased the time for test only. If i set again to 1000 receiver never works

the 01 node also is with all trigger to false. (all sensor off) so the only node which transmit is 011 to 00.

i also tried to set in the void loop only network update but no luck.

i guess my self if i have to set something for the routing process except the number of node. In documentation is written all the routes are automated.
also in documentation is advised to set the retries and the timeout time on the envolved nodes. as you can see from the code i set it but the message still not arrived
i have not found anything about the collisions

maybe the problem is in the set.retries value or in timeout value

how can i ensure the write function is complete before continue to the next call?

thank you again for your help

deejayr:
my nodes send message every second,only if triggered and once time only. in my sketches i decreased the time for test only. If i set again to 1000 receiver never works

I may be misunderstanding this but while you should have time intervals between your transmissions, you should be listening for messages constantly. In other words there should be no time interval between "listens".

If the problem is that they all try to send at the same instant (and collide) (even if it is only once per second), then if a node does not get a proper acknowledgement it should try again after a short random interval. The purpose of random is to prevent the colliding nodes from re-trying at the same instant.

...R

is the ack system automatic? in the document don't use it.

thank you for your advice.

i have modified the codes of my transmitter node like this.

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <avr/sleep.h>
#include <avr/power.h>
#define interval 1000

// PIR variables
byte pirPin = 7;
int pirCalibrationTime = 30;

long previousMillis = 0;

int PIRWake = 3;
int ContactWake = 2;

// Magnetic Door Sensor variable
byte switchPin = 6;

// Radio with CE & CSN connected
RF24 radio(9, 10);
RF24Network network(radio);

// Constants that identify this node and the node to send data to
uint16_t this_node = 011;
uint16_t parent_node = 0;

// Time between packets (in ms)
//const unsigned long interval = 1000;  // every sec
unsigned long timestart = millis() ;
// Structure of our message
struct message_1 {
  bool motion;
  bool dooropen;
};
message_1 message;

// The network header initialized for this node
RF24NetworkHeader header(parent_node);

void setup(void)
{
  // Set up the Serial Monitor
  Serial.begin(115200);

  // Initialize all radio related modules
  SPI.begin();
  radio.begin();
  delay(5);
  network.begin(90, this_node);
  radio.setPALevel(RF24_PA_LOW);
  //radio.setRetries(8,15);
  //network.txTimeout = 560;
  
  pinMode(switchPin, INPUT);
  pinMode(ContactWake, INPUT_PULLUP);
  pinMode(PIRWake,INPUT);
  pinMode(pirPin, INPUT);
  digitalWrite(pirPin, LOW);
  Serial.println(" done");
  delay(50);
  network.update();
}

void loop() {

  // Update network data
  network.update();

  // Read door sensor: HIGH means door is open (the magnet is far enough from the switch)
  bool d = (digitalRead(switchPin) == HIGH);
  
  // Read motion: HIGH means motion is detected
  bool m = (digitalRead(pirPin) == HIGH);
   // Headers will always be type 1 for this node
  // We set it again each loop iteration because fragmentation of the messages might change this between loops
  header.type = '1';

  // Only send values if any of them are different enough from the last time we sent:
  if (m != message.motion ||
      d != message.dooropen) {
    // Construct the message we'll send
    message = (message_1){m, d };

    // Writing the message to the network means sending it
    if (network.write(header, &message, sizeof(message))) {
      Serial.print("Message sent\n"); 
    } else {
      Serial.print("Could not send message\n"); 
    }
 }Serial.println ("Reading...");
 while (millis()-timestart < interval)                         // update in loop the network for the rest of the time
   { network.update();
   } 
  // Wait a bit before we start over again
  timestart = millis() ;
 // delay(interval);
  
 // }

 
}

is it wath you mean?

didn't work again.

now i removed delay and swap it with a while cyce only with network update.

i have a little bit of confusion now

is the routing done when i call network.update?

This combination seems rather pointless because network.update() is called in every iteration of loop()

void loop() {

  // Update network data
  network.update();

// other stuff removed for clarity

 while (millis()-timestart < interval)  // update in loop the network for the rest of the time
   { network.update();
   }
  // Wait a bit before we start over again
  timestart = millis() ;
 // delay(interval);
}

and if you are using millis() it should be like this

 if (millis()-timestart >= interval) 
   { timestart = millis() ;
     network.update();
   }

However you MUST rely on the TMRh20 documentation for the correct use of network.update()

All I intended by the comment in Reply #8 is that you should not put time intervals in the listening part of a program.

I have never had a reason to use the Network version of the RF24 library so I don't know how it deals with acknowledgements. With the regular RF24 library (on which the Network version is based) acknowledgements are automatic.

...R

When i read the documentation it didn t say too much about nerwork.update.

Only to call it often because it allow the routing of the headers.

Maybe the problem is as you said in the delays.

Do some more work to see if you can find a solution and, if not, post the latest version of your program.

I assume you are familiar with TMRh20's example programs?

...R

All examples also in RF 24 give me Time out and send fail but i can see the receiver got the message because when i tried only RF24 (no network)the system (only one pipe) worked well and the test led on my circuit worked when i simulated door opening or pir presence.

i didn't mind it. i suppose this timeout and fail is due to my atmega328 which i use at 8 mhz. I forgot to tell you this part.
sorry.

your sketches for example work for me without problem.

in the examples of RF24Network there is a network ping sketch. every node send the time to the other nodes. and the other node reply.

In this situation i can see node 00 receive from serial the time from 02 but not from 012 (in the case of the sketch the node are 00 02 and 012). Node 02 says failed to send. as usually...

can be this a common issue for 8 mhz avrs?

i read in the forum you use 8 mhz clock....

very thanks for your time Robin

If my programs work it suggests that your nRF24's are all working properly.

I can't imagine that it matters whether the Arduino runs at 16MHz or 8mHz - I have never seen any difference. My normal setup uses a 16MHz Uno to communicate with an 8MHz Atmega 328 or Attiny 1634

I have no experience with the Network library and I don't have time now to set up one for test purposes. I have been avoiding my current project for too long and I must make progress on it.

If the PING examples work maybe you can experiment by extending their code a little. Maybe you can discover what breaks it.

...R

UPDATE.

i decided to came back of one step to be sure of RF24 library works properly. so i uploaded your sketch and removed RF24 Network library

in my opinion the issue is in RF24 not RF24network..

i extended the time of my tests with your sketch to several hours. and i had some issues of packet loss.

you use 256K speed. i changed to 2mps and 1mps, dont work anymore.

then i come back again to 256 and the response in the serial monitor of reciever was only the payload 0.

it means the transmitter dont receive the acknowledgement

which cap do you have on RF24 component? i use 100uF electrolitic on the power supply pin.

When my nRF24 is powered from the 3.3v pin on my Uno or Mega I have not found it necessary to use any capacitor between 3.3v and GND. But on all my breadboard projects I use a 10µF capacitor as at least one of them would not work without it.

Going back to basics is always a sound strategy for debugging.

As you have a few nRF24s you can try each of them in different roles. I have only had a problem with one of mine and it had a dead short circuit between its Vcc and GND pins so it made other things rather hot rather obviously :slight_smile:

...R

UPDATE:

Solved!

Very useful the sketch of Transfer.

my transfer speed was 1k/s at 1Mbps
too low.

So i add a 10uF electrolitic capacitor on the connector which connect nrf to the board.

added again another capacitor on main power (100uF)

speed at 46k

at this point every sketch start to works and the modules finally worked.

So. For experience ADD CAPACITOR EVERYWHERE ON CONNECTORS and check the speed every time with the transfer sketch in example

at 1Mbps the speed must be something like 45 K/sec

Thank you for all for the support

RF24Network acks are only automatic when you use a header type of 65-127. You're using the character '1' which is 49 on the ascii table.

so you mean i have to put header.type "C"?

this stuff of header.type is still obscured for me....

i try to to change to 67 in RX and TX but didnt work anymore