Notifications
Clear all

NRF24L01 - Two way communication traffic demo

14 Posts
3 Users
0 Reactions
7,492 Views
(@pugwash)
Sorcerers' Apprentice
Joined: 6 years ago
Posts: 923
Topic starter  

The two sketches I have published below have no real practical value except as a jumping-off point for further development. But the sketches have been thoroughly tested, nevertheless!

 

Hardware requirements:

  • 2 Arduinos
  • 2NRF24L01
  • 2 LEDs

 

The two LEDs are connected to D5 and D6 pins of the Arduino with the receive sketch and the NRF24L01 modules are connected to pins D9 to D13 on each Arduino. The Arduino with the transmit sketch I will call the remote and it is battery powered, the receive(local) Arduino is connected to the computer by USB, as the Serial Monitor is required. Once both Arduinos are running, the LEDs should be flashing alternately twice per second.

This frequency can be altered by entering the millisecond delay (10 for really fast or 5000 for really slow) in the input field of the Serial Monitor. The input delay time in milliseconds will then be displayed on the Serial Monitor.

 

The receiver sketch:

 

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

RF24 radio(10,9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 01; // Address of our node in Octal format ( 04,031, etc)
const uint16_t node00 = 00;

void setup() {
  
  Serial.begin(9600);
  Serial.println("NRF24L01_receive.ino");
  Serial.println("Input number of milliseconds delay for remote transmitter");
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); //(channel, node address)
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop() {
  
  network.update();
  
  while (network.available()) { // Is there any incoming data?
    RF24NetworkHeader header;
    int incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data
    if(incomingData > 0){
      digitalWrite(5, HIGH);
      digitalWrite(6, LOW);
      }
    else{
      digitalWrite(5, LOW);
      digitalWrite(6, HIGH);
      }
    }

    if(Serial.available() != 0){
      int mData = Serial.parseInt();
      Serial.println(mData);
      sendMyData(mData);  
      }
}

void sendMyData(int outgoingData){
  RF24NetworkHeader header(node00); // (Address where the data is going)
  bool ok = network.write(header, &outgoingData, sizeof(outgoingData)); // Send the data
    
 }

 

The transmitter sketch:

 

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

RF24 radio(10,9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 00; // Address of this node in Octal format ( 04,031, etc)
const uint16_t node01 = 01;

unsigned long currentTime;
unsigned long previousTime;
unsigned long delayTime = 250;

bool transmit = true;

void setup() {

  Serial.begin(9600);
  Serial.println("NRF24L01_transmit.ino");

  pinMode(LED_BUILTIN, OUTPUT);
  
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); //(channel, node address)

  previousTime = millis();

}

void loop() {
  
  network.update();
  
  currentTime = millis();
  
  if(currentTime >= previousTime + delayTime){
    if(transmit){      
      sendMyData(255);
      transmit =!transmit; // set transmit to false
      }else{      
      sendMyData(-255);
      transmit =!transmit; // set transmit to true
      }
  previousTime = millis();

  }

  while (network.available()) { // Is there any incoming data?
    RF24NetworkHeader header;
    int incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data
    delayTime = incomingData;
    }
}

void sendMyData(int outgoingData){
  RF24NetworkHeader header(node01); // (Address where the data is going)
  bool ok = network.write(header, &outgoingData, sizeof(outgoingData)); // Send the data
    
 }

I hope you have fun testing this out and adapting these sketches to your own needs!

Now here are the files for download:

 


   
Quote
frogandtoad
(@frogandtoad)
Member
Joined: 6 years ago
Posts: 1458
 

@Pugwash

Just out of curiosity, what's the difference between using radio or network to do the reading or writing?  I've been experimenting with radio read/write previously, and it seems to work in quite a similar fashion.


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 6 years ago
Posts: 923
Topic starter  

@frogandtoad

What do you mean by "network"?


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 6 years ago
Posts: 1458
 

@pugwash

What do you mean by "network"?

Ok, just to clarify... I've seen the use of different libraries, using similar code:

network.read/write(...) vs radio.read/write(...)

What exactly is the difference, when it appears (at least in my testing), that they look to offer the same outcome... what am I missing?


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 6 years ago
Posts: 923
Topic starter  

@frogandtoad

network.read/write(...) vs radio.read/write(...)

"network" and "radio" are just the names of the declared objects, found above the setup() loop

frogandtoad.write would be perfectly valid if "frogandtoad" was declared as the object.

And in the above code, "radio" is an object within the "network" object.

I also believe that the "radio" object inherits properties from the "network" object.

radio.begin();
network.begin(90, this_node); //(channel, node address)

Note that radio is initiated before network, if the order was reversed this would not work.

I hope that clears it up!!


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 6 years ago
Posts: 1458
 

@pugwash

Yes, I do understand they are objects... no problems there, and I have also seen that radio is passed to the network constructor, and this is what I wanted to know... are they essentially doing the same work, but just different libraries?  Is there a case where one of these implementations should be used over the other?  IOW... do they have different applications?

 


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 6 years ago
Posts: 923
Topic starter  

@frogandtoad

Is there a case where one of these implementations should be used over the other? 

No, they are not interchangeable! Network object needs the radio object to function.

To understand this better you should take a look at the RF24.cpp and RF24Network.cpp files in the Arduino/libraries/RF24 &  Arduino/libraries/RF24Network folders.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 6 years ago
Posts: 1458
 

@pugwash

Thanks, I can look at the files, but that won't tell me when to use one library over the other.  Like I said in my original post, I have been able to communicate with radio.read() and radio.write(), and quite successfully... However, I'm still not sure under which circumstances I would user network.read() or network.write(), because from the examples I've seen posted here so far, I don't see what one can do better than the other?

Does that make sense?


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

From what i read in the doc, the RF24Network (using the underlying "optimized" RF24) introduces an OSI Layer 3 with message acknowledgement and routing (equivalent of IP in the TCP/IP network stack) :

http://tmrh20.github.io/RF24Network/

So RadioA could send messages to RadioC via RadioB for example (see the RF24Mesh for much more complex examples, it is built on top of RF24Network which itself relies on "optimized" RF24)

Eric


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 6 years ago
Posts: 923
Topic starter  

@frogandtoad

I haven't used radio.read or radio.write in my code. In my code above, the radio object is initialised for use by the network object, and in the loop(), only the network object addressed. So if you have seen this usage, it may be in conjunction with other libraries.

All I know is that my code functions 100%, without radio.read or radio.write!

Thus, a comparison of these object.functions is a complete waste of time.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 6 years ago
Posts: 1458
 

@pugwash

Ok, maybe not your code specifically, but some code you have helped with perhaps?.  I wasn't questioning whether your code worked or not, but if you haven't used radio.read() or radio.write() to communicate with these transceivers before then that's fine.

A waste of time?... not if you want to learn!

 


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 6 years ago
Posts: 1458
 

@zeferby

Sorry, I missed this post earlier.

Ok, that makes some sense, if it offers more functionality, specifically for dealing with the OSI model.

Thanks for the information, I will read up on it further.


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 6 years ago
Posts: 923
Topic starter  
Posted by: @frogandtoad

@Pugwash

Just out of curiosity, what's the difference between using radio or network to do the reading or writing?  I've been experimenting with radio read/write previously, and it seems to work in quite a similar fashion.

I think I have got the answer now.

Both are simplex communications but network does not have to be explicitly told that it is the transmitter or receiver during setup, whereas radio does need to be set to transmitter or receiver programmatically.

radio.stopListening(); & radio.startListening(); are not required by the network station to change its status.

Once set up:

RF24NetworkHeader header;
int incomingData;
network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data

is all that is required to receive data and:

RF24NetworkHeader header(node01); // (Address where the data is going)
bool ok = network.write(header, &outgoingData, sizeof(outgoingData)); // Send the data

is all that is required to send data.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 6 years ago
Posts: 1458
 

@pugwash

Nice!


   
ReplyQuote