NRF communication not stable

Hello,

I earlier posted something about the nrf24l01+ but that was because there was no communication between them. Since i got that working, I noticed that the communication isn't realy stable. I check if there is a sensor and if there is it has to display the measured temperature on the screen. this can be 1 sensor or 2 sensors. And in the future I want to measure more values and display them.

I don't know where to look to get this stable. in the code:
RX

// --------------- llibrary's voor receiver ---------------------------------
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include "printf.h"
#include <SPI.h>

// ---------------------------------- Variabelen voor receiver ---------------------------------
float             temp1, temp2;

// LET OP WELKE CE - CSN PIN JE GEBRUIKT!!
RF24            radio(46, 48);
const uint64_t pipes[6] = { 0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL, 0xE8E8F0F0E3LL, 0xE8E8F0F0E4LL, 0xE8E8F0F0E5LL, 0xE8E8F0F0E6LL };
// ---------------------- setup ------------------------------
void setup() {

  Serial.begin(115200);

  //--------------SETUP nRF24L01------------------------
  Serial.println("start ontvanger");
  radio.begin();                      // start the radio
  radio.openReadingPipe(1, pipes[1]);
  radio.openReadingPipe(2, pipes[2]);
  radio.startListening();
}

// ------------------------------------- loop ---------------------------

void loop() {

  uint8_t pipeNum;
  if (radio.available(&pipeNum)) {
     
    if(pipeNum == 1)
    {
      radio.read(&temp1, sizeof(temp1));
      Serial.println(temp1);
      Serial.print("temp1");
    }
    if(pipeNum == 2)
    {
      radio.read(&temp2, sizeof(temp2));
      Serial.println(temp2);
      Serial.print("temp2");
    }
  }
}

TX1 (the values are hardcoded for easier testing)

#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include "printf.h"                     // comment this out if no radio info on serial
#include <SPI.h>


float             temp2;

// LET OP WELKE CE - CSN PIN JE GEBRUIKT!!
RF24            radio(9, 10);
const uint64_t pipes[6] = { 0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL, 0xE8E8F0F0E3LL, 0xE8E8F0F0E4LL, 0xE8E8F0F0E5LL, 0xE8E8F0F0E6LL };

// ---------------------- setup ------------------------------
void setup(void) {
  Serial.begin(115200);               // start the serial
  Serial.println("Start zender");
  radio.begin();                      // start the radio
  radio.openWritingPipe(pipes[2]);        // open our pipe for communication
  radio.setRetries(15, 15);
}

// ------------------------------------- loop ---------------------------

void loop(void) {

  temp2 = 22.22;
  radio.write(&temp2, sizeof(temp2));

}

TX2 (also hard coded value)

#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include "printf.h"                     // comment this out if no radio info on serial
#include <SPI.h>


float             temp1;


RF24            radio(9, 10);
const uint64_t pipes[6] = { 0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL, 0xE8E8F0F0E3LL, 0xE8E8F0F0E4LL, 0xE8E8F0F0E5LL, 0xE8E8F0F0E6LL };

// ---------------------- setup ------------------------------
void setup(void) {
  Serial.begin(115200);               // start the serial
  Serial.println("Start zender");
  radio.begin();                      // start the radio
  radio.openWritingPipe(pipes[1]);        // open our pipe for communication
  radio.setRetries(15, 15);
}

// ------------------------------------- loop ---------------------------

void loop(void) {

  temp1 = 11.11;
  radio.write(&temp1, sizeof(temp1));

}

There is communication between the modules and the values it receives are correct but they aren't "seeing" each other every time it has to..

can someone explain to me what i am doing wrong?? this sketch is without screen because every one has different screens

Your TX loops are very tight. Try putting a delay of a few seconds in and see what happens.

Yes I know I thought this was easier to test but if a delay can help I can better go on with the original plan..
because:
when everything is done... it has to measure every 5 minutes and transmit this

but what is more stable.. start reading every 5 minutes or start transmitting every 5 minutes?

The receiver must be in a continuous loop otherwise it will miss the sporadic transmissions.
If the transmitters transmit too often, the receiver my be flooded.
If your transmitters are powered by battery, you'll anyway be thinking of methods to prolong battery life, which may include putting the transmitter to sleep from time to time.

THANKS!

I am going to try this and post the result

If that was my project I would turn things on their head and use the "Receiver" as Master to poll the other 2 Slaves. That way the timing is all under control.

The pair of programs in this link was designed for that approach. You can easily extend it to several slaves. Note that all the comms happens on the same pipe.

...R

A delay didn't work

I gues the only option to do this, is the way Robin said.. so i am going to try that

Robin2:
If that was my project I would turn things on their head and use the "Receiver" as Master to poll the other 2 Slaves. That way the timing is all under control.

The pair of programs in this link was designed for that approach. You can easily extend it to several slaves. Note that all the comms happens on the same pipe.

...R

I can't get this working correct.. If I try this there is sometimes a value that I don't receive...
Do you have any other examples?

How are the RF24 radios powered?

I have those modules where u can put the nrf24l01 on and those modules need to be powered with 5v and that is what I do

Tim-:
I can't get this working correct.

Post the exact code (both programs) that YOU used.

I have just completed testing 4 pairs of them including a range test on one pair which worked at 110 metres - I could not try a longer distance as I could not see if the motor was turning. :slight_smile:

...R

I used the code where you linked me to

master

// TrackControl - the master or the transmitter

 // http://tmrh20.github.io/RF24/

 //~ - CONNECTIONS: nRF24L01 Modules See:
 //~ http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
 //~ 1 - GND
 //~ 2 - VCC 3.3V !!! NOT 5V
 //~ 3 - CE to Arduino pin 9
 //~ 4 - CSN to Arduino pin 10
 //~ 5 - SCK to Arduino pin 13
 //~ 6 - MOSI to Arduino pin 11
 //~ 7 - MISO to Arduino pin 12
 //~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>


#define CE_PIN   46
#define CSN_PIN 48

// NOTE: the "LL" at the end of the constant is "LongLong" type
// These are the IDs of each of the slaves
const uint64_t slaveID[3] = {0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL, 0xE8E8F0F0E3LL } ;

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

int dataToSend[2];

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000;
int txVal = 0;
int ackMessg[6];
byte ackMessgLen = 4; // NB this 4 is the number of bytes in the 2 ints that will be recieved


void setup() {

    Serial.begin(9600);
    Serial.println("Track Control Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.enableAckPayload();
    radio.setRetries(3,5); // delay, count
}

//====================

void loop() {

    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {

    radio.openWritingPipe(slaveID[0]); // calls the first slave
                                        // there could be a FOR loop to call several slaves in turn
    dataToSend[0] = txVal; // this gets incremented so you can see that new data is being sent
    txVal += 1;
    dataToSend[1] = txVal;
    txVal += 1;
    bool rslt;
    rslt = radio.write( dataToSend, sizeof(dataToSend) );
    Serial.print("\nRSLT (1 = success) ");
    Serial.println(rslt);
    Serial.print("Data Sent ");
    Serial.print(dataToSend[0]);
    Serial.print("  ");
    Serial.println(dataToSend[1]);
    if ( radio.isAckPayloadAvailable() ) {
        radio.read(ackMessg,ackMessgLen);
        Serial.print("Acknowledge received: ");
        Serial.print(ackMessg[0]);
        Serial.print("  ");
        Serial.println(ackMessg[1]);
    }
    prevMillis = millis();
 }
}

slave

// HandController - the slave or the receiver

    // http://tmrh20.github.io/RF24/

    //~ - CONNECTIONS: nRF24L01 Modules See:
    //~ http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
    //~ 1 - GND
    //~ 2 - VCC 3.3V !!! NOT 5V
    //~ 3 - CE to Arduino pin 9
    //~ 4 - CSN to Arduino pin 10
    //~ 5 - SCK to Arduino pin 13
    //~ 6 - MOSI to Arduino pin 11
    //~ 7 - MISO to Arduino pin 12
    //~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

// NOTE: the "LL" at the end of the constant is "LongLong" type

const uint64_t   deviceID = 0xE8E8F0F0E1LL; // Define the ID for this slave

int valChange = 1;

RF24 radio(CE_PIN, CSN_PIN);

int dataReceived[2];
int ackData[2] = {12,23};

void setup() {

    Serial.begin(9600);
    delay(1000);
    Serial.println("Hand Controller Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1,deviceID);
    radio.enableAckPayload();
    radio.writeAckPayload(1, ackData, sizeof(ackData));
    radio.startListening();
}

void loop() {

    if ( radio.available() ) {
        radio.read( dataReceived, sizeof(dataReceived) );
        Serial.print("Data received Number0 ");
        Serial.print(dataReceived[0]);
        Serial.print(" Number1 ");
        Serial.println(dataReceived[1]);
        radio.writeAckPayload(1, ackData, sizeof(ackData));
        ackData[0] += valChange; // this just increments so you can see that new data is being sent
    }
}

slave2

// HandController - the slave or the receiver

    // http://tmrh20.github.io/RF24/

    //~ - CONNECTIONS: nRF24L01 Modules See:
    //~ http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
    //~ 1 - GND
    //~ 2 - VCC 3.3V !!! NOT 5V
    //~ 3 - CE to Arduino pin 9
    //~ 4 - CSN to Arduino pin 10
    //~ 5 - SCK to Arduino pin 13
    //~ 6 - MOSI to Arduino pin 11
    //~ 7 - MISO to Arduino pin 12
    //~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

// NOTE: the "LL" at the end of the constant is "LongLong" type

const uint64_t   deviceID = 0xE8E8F0F0E1LL; // Define the ID for this slave

int valChange = 1;

RF24 radio(CE_PIN, CSN_PIN);

int dataReceived[2];
int ackData[2] = {12,23};

void setup() {

    Serial.begin(9600);
    delay(1000);
    Serial.println("Hand Controller Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1,deviceID);
    radio.enableAckPayload();
    radio.writeAckPayload(1, ackData, sizeof(ackData));
    radio.startListening();
}

void loop() {

    if ( radio.available() ) {
        radio.read( dataReceived, sizeof(dataReceived) );
        Serial.print("Data received Number0 ");
        Serial.print(dataReceived[0]);
        Serial.print(" Number1 ");
        Serial.println(dataReceived[1]);
        radio.writeAckPayload(1, ackData, sizeof(ackData));
        ackData[0] += valChange; // this just increments so you can see that new data is being sent
    }
}

I didn't change anything except the ce csn pin
master is arduino mega
slave 1 is uno
slave 2 is pro mini

in the end it should send measured values from different sensors so i have to change the payload also but first the communication has to be as stable as possible

when i use 1 master and 1 slave it works (with the same code)
master is mega
slave is uno

this is the serial monitor master

RSLT (1 = success) 0
Data Sent 26  27

RSLT (1 = success) 1
Data Sent 28  29
Acknowledge received: 19  23

RSLT (1 = success) 0
Data Sent 30  31

RSLT (1 = success) 1
Data Sent 32  33
Acknowledge received: 16  23

RSLT (1 = success) 0
Data Sent 34  35

RSLT (1 = success) 1
Data Sent 36  37
Acknowledge received: 17  23

RSLT (1 = success) 1
Data Sent 38  39
Acknowledge received: 18  23

RSLT (1 = success) 0
Data Sent 40  41

serial ouput slave1

Hand Controller Starting
Data received Number0 16 Number1 23
Data received Number0 17 Number1 23
Data received Number0 24 Number1 25
Data received Number0 28 Number1 29
Data received Number0 19 Number1 23
Data received Number0 32 Number1 33
Data received Number0 36 Number1 37
Data received Number0 38 Number1 39
Data received Number0 44 Number1 45

there are some failures but with this speed of measurement that doesn't matter I only need to add more slaves in the end there should be 5 (or 6?) slaves that sends measured values from sensors

Let's keep things simple and forget about slave2 until you have master and slave1 working perfectly.

And please note that, as written, the master demo code only works with one slave and that is noted in the comments.

Are you using the correct SPI pins on the Mega? The easiest thing may be to use the ICSP header because its pins are the same on all Arduinos.

Just for general information you can use any convenient I/O pins for CE and CSN. It is only MOSI, MISO and SCK that need dedicated pins.

I am unlikely to have time today to try your code on my Mega and Uno, and tomorrow is doubtful also. And I am not sure if I have 2 spare nRF24s. I was making stuff and one new device was a dud so I had to use one of my own. However I will bookmark this in case I have a few minutes spare.

...R

Oops didn't saw that.. Is it possible to make the sketch work for multiple slaves? If I add pipes it should work shouldn't it?

I would like to forget about more slaves but.. I need to have more slaves.. I had multiple examples where it worked perfect with only one slave but there also was a problem by adding more slaves...

The pins on the mega are correct it is the master in the case I only have 1 slave and that works fine.

Thanks for keeping this in mind I hope you can help me

I run groups of nRFs without a rigid master/slave role allocation.

I use common channels (pipes without ack) for broadcasts and notifications,
and each node has a personal channel (with ack).

I use a common prefix for the pipe addresses, and one byte for the node id (placed in EEPROM).

All nodes normally listen, and switch to transmit only if needed.

I use a small packet header (3 bytes: typ, to, from) to identify packets.

Keeping the types and the node ids in the printable range, it is easy to debug and manage.
(A command from node 'A' to node 'B' results in "!BA" plus rest of packet,
setting the node id can be done (via Serial, packet, ..) without any conversions.)

I found the above arrangement very versatile, handy and rock solid.

Tim-:
Oops didn't saw that.. Is it possible to make the sketch work for multiple slaves?

Did you not read the comment in the code?

You just need to build a FOR loop to iterate through the array of slave IDs. There is no need for extra pipes.

I know you need more slaves. But start by getting 1 to work properly. Programs should be developed in small steps.

The pins on the mega are correct it is the master in the case I only have 1 slave and that works fine

What pins are you using?

If the master and a single slave are working perfectly (please confirm) then you just need to add the FOR loop to work with others. I suggest you try each slave separately on a 1 to 1 basis first. That way you will be sure each slave works.

...R

hi everybody , i'm working on this nrf24L01 i want to sent from a tranciever to a transmitter
transmitter code :

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "printf.h"



#define ONE_WIRE_BUS 2

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

float temp1;

RF24 radio(9, 10);
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };

void setup(void) {
Serial.begin(9600);
sensors.begin();
printf_begin();
radio.begin();
radio.setRetries(15,15);
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipes[1]);
radio.startListening();
radio.printDetails();
}

void loop(void)
{
sensors.requestTemperatures();
temp1 = sensors.getTempCByIndex(0);
Serial.println(temp1) ;

 radio.stopListening();
  if (!radio.available()) {
    Serial.println("OK");
    
  }else
    {
      Serial.println("Failed");
    }
   
    Serial.println(temp);
    bool ok = radio.write( &temp1, sizeof(temp1) );
    
    if (ok)
      printf("ok...");
    else
      printf("failed.\n\r");
      radio.startListening();
      delay(1000);
}

reciever Code :

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//Create Object



float temp1  ;


RF24 radio(9, 10);
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL };
// initialisierung der 3 pipes // 



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

radio.openReadingPipe(1,pipes[1]);
radio.startListening();
radio.printDetails();
}
  void loop(void)
{
 
    
    // if there is data ready
    if ( radio.available() )
    {
      // Dump the payloads until we've gotten everything
      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
        done = radio.read(&temp1, sizeof(temp1) );
        Serial.println(done);

        // Spew it
        Serial.println(temp1);

  // Delay just a little bit to let the other unit
  // make the transition to receiver
  delay(1000);
       }
       }

i don't know where is my mistake , wenn i try to sent a normal data ( unsigned long ) it' working and
but with temperature data ( float ) it doesnt's working . can someone help me ?

Robin2:
Did you not read the comment in the code?

i did but I haven't seen that..

You just need to build a FOR loop to iterate through the array of slave IDs. There is no need for extra pipes.

okay I will try that

I know you need more slaves. But start by getting 1 to work properly. Programs should be developed in small steps.

That was what i am trying to do. There is an acceptable communication between master and slave. Now I wanted to add 1 more

What pins are you using?

i use ce: 46
csn 48

miso 50
mosi 51
sck 52

If the master and a single slave are working perfectly (please confirm) then you just need to add the FOR loop to work with others. I suggest you try each slave separately on a 1 to 1 basis first. That way you will be sure each slave works.

just confirmed above :smiley:

Whandall:
I run groups of nRFs without a rigid master/slave role allocation.

I use common channels (pipes without ack) for broadcasts and notifications,
and each node has a personal channel (with ack).

I use a common prefix for the pipe addresses, and one byte for the node id (placed in EEPROM).

All nodes normally listen, and switch to transmit only if needed.

I use a small packet header (3 bytes: typ, to, from) to identify packets.

Keeping the types and the node ids in the printable range, it is easy to debug and manage.
(A command from node 'A' to node 'B' results in "!BA" plus rest of packet,
setting the node id can be done (via Serial, packet, ..) without any conversions.)

I found the above arrangement very versatile, handy and rock solid.

I used channels before but the values where different and sometimes mixed.. Do you have a stable connection AND are the values seperate?? so yes could you please send me an example how you managed to do that?

@Eric

Did you try to communicate with an easier sketch first?

Check wiring i wired it wrong the first two times..
Make sure that you have to power them with 3.3V