Problem with nRF24L01

Hi!!

I’m trying to creat a bidireccional conection.

My idea is:

  • Arduino 1 send a number to Arduino 2 to turn on Led

  • Arduino 2 read number and turn on Led, when an object is near than 15cm Arduino 2 turn off Led

  • Arduino 2 send “signal” to Arduino 1 “saying” Led is turn off" and Arduino 1 send a new number to Arduino 2.

At moment, the only problem is that Arduino 2 doesn’t send “signal” to Arduino 1 “saying” Led is turn off"

That’s my code.

Arduino 1

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


RF24 radio(9,10);
const byte canales[][6] = {"00001", "00002", "00003"};

int estado = 7;

void setup(void){
  Serial.begin(9600);
  radio.begin();
  radio.setRetries(15,15);
  radio.openWritingPipe(canales[0]);
  radio.openReadingPipe(1, canales[1]);
}

void loop(void){
  radio.stopListening();
 
    int luz = 3;
    radio.write(&luz, sizeof(luz));
    Serial.println(luz);

  radio.startListening();
  if (radio.available()){
    radio.read(&estado, sizeof(estado));
    Serial.print("Estado: ");
    Serial.println(estado);
  }
}

Arduino 2

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

int luz = 0;
int estado = 0;
// Definicion Echo, Trig y variables Ultrasonido
#define echoPinVerde 6
#define trigPinVerde 7
long duracion, distanciaVerde;

//Definición nRF
RF24 radio(9,10);
const byte canales[][6] = {"00001", "00002", "00003"};

//Led
int LED1 = 3;

void setup(void){
  Serial.begin(9600);
  radio.begin();
  radio.setRetries(15,15);
  radio.openWritingPipe(canales[1]);
  radio.openReadingPipe(1, canales[0]);
  radio.startListening();
  pinMode(LED1, OUTPUT);
  //Sensor de proximidad
  pinMode(trigPinVerde, OUTPUT);
  pinMode(echoPinVerde, INPUT);
  }
 
void loop(void){

if (radio.available()){
  radio.read(&luz, sizeof(luz));
  Serial.println(luz);
  digitalWrite(luz, HIGH);
  radio.stopListening();

 while (luz == 3) {
    digitalWrite(trigPinVerde, LOW);   
    delayMicroseconds(2);           
    digitalWrite(trigPinVerde, HIGH);   
    delayMicroseconds(10);         
    digitalWrite(trigPinVerde, LOW);
     
    duracion = pulseIn(echoPinVerde, HIGH);
    distanciaVerde = (duracion/2)/29;
    Serial.print(double(distanciaVerde)); 
    Serial.println(" cm.");
    
    if (distanciaVerde <=15) {
      digitalWrite(luz, LOW); 
      luz = 0;
      estado = 1;
      Serial.println(estado);
    }
  radio.write(&estado, sizeof(estado));
  Serial.print("Estado: ");
  Serial.println(estado);
  estado = 0;
  radio.startListening();
  }
}
}

Can you help me, please?

Thanks!!

Have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

There is also a connection test program to check that the Arduino can talk to the nRF24 it is connected to.

A common problem with nRF24 modules is insufficient 3.3v current from the Arduino 3.3v pin. This seems to be a particular problem with the nano. The high-power nRF24s (with the external antenna) will definitely need an external power supply. At least for testing try powering the nRF24 with a pair of AA alkaline cells (3v) with the battery GND connected to the Arduino GND.

...R

Thank you!

I read this tutorial but isn't bidireccional, no?

I'll try again with this code and adding a new pipe

g22: I read this tutorial but isn't bidireccional, no?

It seems like you did not read all of it carefully.

It includes three examples and two of them provide bi-directional communication.

...R

Perfect! I'll read again carefully

Thank you very much!!

Moderator: Please don´t cross post threads!! Spanish Forum: Problema con nRF24L01

Give a new reading to how to use this forum. Specially item 13. Don't cross-post![/right]

I started again with a “new” code with TMRh20 but now the Slave don’t recive nothing and I don’t know why…

I’m doing something bad?

Master:

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


RF24 radio(9,10);

const byte Verde[5] = {'R','x','A','A','A'};
const byte Master[5] = {'T','X','a','a','a'};

void setup(void){
  Serial.begin(115200);
  radio.begin();
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.enableAckPayload();               // Allow optional ack payloads
  radio.setRetries(0, 15);                // Smallest time between retries, max no. of retries
  radio.setPayloadSize(1);                // Here we are sending 1-byte payloads to test the call-response speed
  radio.openWritingPipe(Master[0]);        // Both radios listen on the same pipes by default, and switch when writing
  radio.openReadingPipe(1, Verde[1]);
  radio.startListening();                 // Start listening
}

void loop(void){
  radio.stopListening();

    int luz = 3;
    radio.write(&luz, sizeof(luz));
    //Serial.print (number [0]);
    Serial.println(luz);
}

Slave (Verde):

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


int luz = 0;



//Definición nRF24
RF24 radio(9,10);

const byte Verde[5] = {'R','x','A','A','A'};
const byte Master[5] = {'T','X','a','a','a'};


void setup(void){
  Serial.begin(115200);
  radio.begin();
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.enableAckPayload();               // Allow optional ack payloads
  radio.setRetries(0, 15);                // Smallest time between retries, max no. of retries
  radio.setPayloadSize(1);                // Here we are sending 1-byte payloads to test the call-response speed
  radio.openWritingPipe(Verde[0]);        // Both radios listen on the same pipes by default, and switch when writing
  radio.openReadingPipe(1, Master[1]);
  radio.startListening();                 // Start listening
  
  }
 
void loop(void){

if (radio.available()){
  radio.read(&luz, sizeof(luz));
  Serial.println(luz);
  digitalWrite(luz, HIGH);
  radio.stopListening();
}
}

Sorry, i’m new on this…

g22:
I’m doing something bad?

Two things.

First, and most important, start with one of the examples from my Tutorial with absolutely no changes to the code. If that does not work there is no point trying anything more complex.

Second, this is wrong

radio.openWritingPipe(Master[0]);

because Master[0] is the byte ‘T’ when what you actually need is all 5 bytes. Do it the same way as it is done in my Tutorial.

…R

Ok! I'll try again!

Ty!!

Hi!

It’s working!!

Now I have 3 Arduino. 1 master and 2 slaves and all is working find but I generate a random number and I want to stop the generation of numbers. I try with “while” ut I don’t know why doesn’t stop.

Master:

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


#define CE_PIN   9
#define CSN_PIN 10

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

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

char dataToSend[10] = "Message 0";
char txNum = '0';

int ackData = 0;
bool newData = false;

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

int randNumber = 0;
//===============

void setup() {

    Serial.begin(115200);
    Serial.println(F("Source File /mnt/sdb1/SGT-Prog/Arduino/ForumDemos/nRF24Tutorial/SimpleTxAckPayload.ino"));
    Serial.println("SimpleTxAckPayload Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );

    radio.enableAckPayload();

    radio.setRetries(5,5); // delay, count
                                       // 5 gives a 1500 µsec delay which is needed for a 32 byte ackPayload
    
}

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

void loop() {

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

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

void send() {
randNumber = random(2,4);
Serial.print("RANDOM: ");
Serial.println(randNumber);
  while (randNumber == 2){
    radio.openWritingPipe(slaveAddressVerde);
  int luz = 2;
    bool rslt;
    rslt = radio.write( &luz, sizeof(luz) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(luz);
    if (rslt) {
        if ( radio.isAckPayloadAvailable() ) {
            radio.read(&ackData, sizeof(ackData));
            newData = true;
        }
        else {
            Serial.println("  Acknowledge but no data ");
        }
        if (ackData = 1){
          randNumber = 0;
        }

    }
    else {
        Serial.println("  Tx failed");
    }
  }

  while (randNumber == 3){
    radio.openWritingPipe(slaveAddressRojo);
  int luz = 3;
    bool rslt;
    rslt = radio.write( &luz, sizeof(luz) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(luz);
    if (rslt) {
        if ( radio.isAckPayloadAvailable() ) {
            radio.read(&ackData, sizeof(ackData));
            newData = true;
            //randNumber = 0;
        }
        else {
            Serial.println("  Acknowledge but no data ");
        }
        if (ackData = 1){
          randNumber = 0;
        }

    }
    else {
        Serial.println("  Tx failed");
    }
  }
    prevMillis = millis();
 }


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

void showData() {
    if (newData == true) {
        Serial.print("  Acknowledge data ");
        Serial.print(ackData);
        Serial.print(", ");
       // Serial.println(ackData[1]);
        Serial.println();
        newData = false;
    }
}

Slave “Verde”

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

#define CE_PIN   9
#define CSN_PIN 10

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

RF24 radio(CE_PIN, CSN_PIN);

int ackData = 0;
bool newData = false;

int luz = 0;
int LED = 2;

#define echoPin 6
#define trigPin 7
long duracion, distancia;
//==============

void setup() {

    Serial.begin(115200);

    Serial.println("SimpleRxAckPayload Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddressVerde);

    radio.enableAckPayload();
    
    radio.startListening();

    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data

    pinMode(LED, OUTPUT);
    //Sensor de proximidad
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
}

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

void loop() {
    getData();
    showData();
}

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

void getData() {
    if ( radio.available() ) {
        radio.read( &luz, sizeof(luz) );
        updateReplyData();
        newData = true;
        digitalWrite(luz, HIGH);
    }
}

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

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(luz);
        Serial.print(" ackPayload sent ");
        Serial.print(ackData);
        Serial.print(", ");
        newData = false;
    }
}

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

void updateReplyData() {

   while (luz == 2) {
    digitalWrite(luz, HIGH);
    //Serial.println(luz);
    digitalWrite(trigPin, LOW);   
    delayMicroseconds(2);           
    digitalWrite(trigPin, HIGH);   
    delayMicroseconds(10);         
    digitalWrite(trigPin, LOW);
     
    duracion = pulseIn(echoPin, HIGH);
    distancia = (duracion/2)/29;
    Serial.print(double(distancia)); 
    Serial.println(" cm.");
    
    if (distancia <=15) {
      digitalWrite(luz, LOW); 
      luz = 0;
      Serial.println(luz);
      ackData = 1;
    
      radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
    }
}
}

Slave “Rojo”

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

#define CE_PIN   9
#define CSN_PIN 10

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

RF24 radio(CE_PIN, CSN_PIN);

int ackData = 0;
bool newData = false;

int luz = 0;
int LED = 2;

#define echoPin 6
#define trigPin 7
long duracion, distancia;
//==============

void setup() {

    Serial.begin(115200);

    Serial.println("SimpleRxAckPayload Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddressRojo);

    radio.enableAckPayload();
    
    radio.startListening();

    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data

    pinMode(LED, OUTPUT);
    //Sensor de proximidad
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
}

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

void loop() {
    getData();
    showData();
}

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

void getData() {
    if ( radio.available() ) {
        radio.read( &luz, sizeof(luz) );
        updateReplyData();
        newData = true;
        digitalWrite(luz, HIGH);
    }
}

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

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(luz);
        Serial.print(" ackPayload sent ");
        Serial.print(ackData);
        Serial.print(", ");
        newData = false;
    }
}

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

void updateReplyData() {

   while (luz == 3) {
    digitalWrite(luz, HIGH);
    //Serial.println(luz);
    digitalWrite(trigPin, LOW);   
    delayMicroseconds(2);           
    digitalWrite(trigPin, HIGH);   
    delayMicroseconds(10);         
    digitalWrite(trigPin, LOW);
     
    duracion = pulseIn(echoPin, HIGH);
    distancia = (duracion/2)/29;
    Serial.print(double(distancia)); 
    Serial.println(" cm.");
    
    if (distancia <=15) {
      digitalWrite(luz, LOW); 
      luz = 0;
      Serial.println(luz);
      ackData = 1;
    
      radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
    }
}
}

In other sketch without nRF24L01 when I use random number and “while” the program generate only one number till while end

I think the problem isn't random number. Is ack problem?

Monitor Serie:

Source File /mnt/sdb1/SGT-Prog/Arduino/ForumDemos/nRF24Tutorial/SimpleTxAckPayload.ino
SimpleTxAckPayload Starting
RANDOM: 3
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Tx failed
Data Sent 3  Acknowledge data 1, 
RANDOM: 3
Data Sent 3  Acknowledge data 1, 
RANDOM: 3
Data Sent 3  Acknowledge data 1, 
RANDOM: 2
Data Sent 2  Acknowledge but no data 
RANDOM: 2
Data Sent 2  Acknowledge data 1, 
RANDOM: 2
Data Sent 2  Acknowledge data 1, 
RANDOM: 2
Data Sent 2  Acknowledge data 1, 
RANDOM: 2
Data Sent 2  Tx failed
Data Sent 2  Tx failed
Data Sent 2  Tx failed
Data Sent 2  Tx failed
Data Sent 2  Tx failed
Data Sent 2  Tx failed

g22: Now I have 3 Arduino. 1 master and 2 slaves and all is working find but I generate a random number and I want to stop the generation of numbers. I try with "while" ut I don't know why doesn't stop.

You have posted 3 programs. Which of them is generating the random numbers?

What is the purpose of the random numbers?

In what circumstances do you want to stop generating random numbers?

...R

Robin2:
You have posted 3 programs. Which of them is generating the random numbers?

Master

Robin2:
What is the purpose of the random numbers?

If number is 2, Master send this number to Slave “Verde” to turn on LED and when Slave “Verde” turn off LED send a singal to Master to generate a new number.

If number is 3 Master send this number to Slave “Red” and do the same

Robin2:
In what circumstances do you want to stop generating random numbers?

When LEDs is on

g22:

In what circumstances do you want to stop generating random numbers?

When LEDs is on

The first thing you should do is organize your program into separate single-purpose functions. At the moment you have a send() function that seems to do all sorts of things when all it should be doing is sending a wireless message and getting the acknowledgement.

Also, don't duplicate code - that just creates scope for errors. You can use the same code to send data to either of the slaves.

And don't use WHILE - use IF. Allow loop() to do the repetition.

How is the master going to know when an LED is ON or OFF?

...R

Robin2: When LEDs is on

The first thing you should do is organize your program into separate single-purpose functions. At the moment you have a send() function that seems to do all sorts of things when all it should be doing is sending a wireless message and getting the acknowledgement.

Also, don't duplicate code - that just creates scope for errors. You can use the same code to send data to either of the slaves.

And don't use WHILE - use IF. Allow loop() to do the repetition.

Ok!

Robin2: How is the master going to know when an LED is ON or OFF?

...R

When Slave turn off a LED, send "ackData = 1", Master read "ackData = 1", then Master generate a new random number

g22: When Slave turn off a LED, send "ackData = 1", Master read "ackData = 1", then Master generate a new random number

I'm not sure that ackData is the best solution for this because it requires the master repeatedly to query the slave - but a lot depends on how long the LED is likely to be ON.

What is the minimum, maximum and typical time for the LED to be ON?

The other issue is what is the longest acceptable latency between an LED turning OFF and the master being aware of that.

The way your program is written now using WHILE the master will send messages to the slave as fast as it possibly can. That is not a good idea because it jams up the airwaves for other users.

At the least, the master should not send messages more often than the minimum ON time.

...R

Robin2: What is the minimum, maximum and typical time for the LED to be ON?

The LED is ON until an object is less than 15cm from the HC-SR04 sensor

g22: The LED is ON until an object is less than 15cm from the HC-SR04 sensor

The important thing is the time that takes - hence my question in Reply #15

And you did not answer my question about latency - that is also important for the design of an effective system.

...R

Sorry

Robin2: What is the minimum, maximum and typical time for the LED to be ON?

Minimum - 1 sec Maximun - 60 secs Typical - betwen 20 and 30 secs

Robin2: The other issue is what is the longest acceptable latency between an LED turning OFF and the master being aware of that.

Sorry I don't know nothing abaut latency... but, from I've read, i think that 100ms

In view of the possible long times and the relatively low latency requirement I suggest that the master sends a message and then switches to listening - like the 3rd example in my Simple nRF24L01+ Tutorial. When the slave turns off the LED it can then send a message to the master.

...R