NRF24L01+ Receiver mixup of Transmitter Data

This is my 1st post, so forgive if a violate any standards.

I have setup 3 arduino's, 1 Receiver and 2 Transmitters, to send data on button presses. It is meant to be a simple sketch that lets 2 remotes toggle relays, it does not need to return whether the transmission was received (for now) and works fine in my scenario.
Right now I'm just trying to get the right values.

Here are the problems:

  1. The radio keeps "Disconnecting"
  2. (After removing the block of code that displays "Disconnected") The data received from the 2 transmitters are moving between the 2 Variables : RemOne and RemTwo instead of staying in their respective spots.
  3. When printing to Serial, I occasionally get missing or altered characters

Receiver Code:

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


RF24 radio(9,10);
const uint64_t Pipe[2] = {0xE8E8F0F0E1, 0x123};
int RemOne[3] ;
int RemTwo[3] ;

boolean lastSig1 = LOW;
boolean RelayOn1 = false;

boolean lastSig2 = LOW;
boolean RelayOn2 = false;

const int Relay1 = 2;
const int Relay2 = 3;

void setup(){
  Serial.begin(57600);
  radio.begin();
  radio.setDataRate(RF24_1MBPS);
   radio.openReadingPipe(1, Pipe[1]);
   radio.openReadingPipe(0, Pipe[0]);
  radio.setChannel(99);
  radio.startListening();
  
  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop(){
   if(radio.available(Pipe[0])){
     bool done = false;
   while (!done){
     done = radio.read(RemOne, sizeof(RemOne) );
      Serial.print(" RemOne: ");
      Serial.print(RemOne[0]);
      Serial.print(RemOne[1]);
      Serial.println("   ");
   }}
   
   else if(radio.available(1)){
     bool don = false;
   while(!don){
    don = radio.read(RemTwo, sizeof(RemTwo));
      Serial.print("RemTwo: ");
      Serial.print(RemTwo[0]);
      Serial.print(RemTwo[1]);
      Serial.println("    ");
  }
   }
      
 /*  if (RemOne[0] == HIGH && lastSig1 == LOW){
        RelayOn1 = !RelayOn1;
        lastSig1 = HIGH;
      } else{lastSig1 = RemOne[0]; } 
      digitalWrite(Relay1, RelayOn1);

      if (RemOne[1] == HIGH && lastSig2 == LOW){
        RelayOn2 = !RelayOn2;
        lastSig2 = HIGH;
      } else{lastSig2 = RemOne[1];} 
      digitalWrite(Relay2, RelayOn2); 
*/

 
   if (!radio.available()) { 
    Serial.println("Disconnected");
    digitalWrite(6, HIGH);
    delay(50);
    digitalWrite(6,LOW);
   }

 
}

Transmitter 1 Code:

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

int ledPin =13;
const int butPin1 = 3;
const int butPin2 = 4;
int butState1 = 0;
int butState2 = 0;

RF24 radio(9,10);
const uint64_t Pipe[2] = {0xE8E8F0F0E1, 0x123};
int Rem1[3];

void setup(){
  pinMode(butPin1, INPUT);
  pinMode(butPin2, INPUT);
  pinMode(ledPin, OUTPUT);
  radio.begin();
  radio.setChannel(99);
  radio.setDataRate(RF24_1MBPS);
  radio.openWritingPipe(Pipe[0]);
  radio.stopListening();

  Serial.begin(9600);
  Serial.println("TX Rem A");
 
}

void loop(){
  
 
 butState1 = digitalRead(butPin1);
  if (butState1 >0){
    Rem1[0] = 1;
  }
  else{
    Rem1[0] = 0;
  }

  butState2 = digitalRead(butPin2);
  if(butState2 >0){
    Rem1[1] = 1;
  }
  else{Rem1[1] = 0;}
 
  
 
  radio.write(Rem1, sizeof(Rem1));
  Serial.print(Rem1[0]);
  Serial.println(Rem1[1]);



}

Transmitter 2 Code:

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

int ledPin =13;
const int butPin1 = 3;
const int butPin2 = 4;


int butState1 = 0;
int butState2 = 0;

RF24 radio(9,10);

const uint64_t Pipe[2] = {0xE8E8F0F0E1, 0x123};
int B_Rem[3] = {5 ,6 ,7};

void setup(){
  pinMode(butPin1, INPUT);
  pinMode(butPin2, INPUT);
  pinMode(ledPin, OUTPUT); 
  radio.begin();
  radio.setChannel(99);
  radio.setDataRate(RF24_1MBPS);
  radio.openWritingPipe(Pipe[1]);

  Serial.begin(9600);
  Serial.println("TX Rem B");

}

void loop(){
  //Took out the code for reading button presses here and replaced with constant values

  radio.write(B_Rem, sizeof(B_Rem));
  Serial.print(B_Rem[0]);
  Serial.print(B_Rem[1]);
  Serial.println(B_Rem[2]);

}

P.S. all the hardware is functioning correctly, tested.

First of all it is not correct to say that the radio is disconnected just because it has not received a message. There is really no such concept as "disconnected". If the radio is listening then it either receives a message or not.

Your two Tx programs seem to send data as fast as loop() can repeat. That means that the two Txs are likely to send at the same time and corrupt both messages. At the very least put a short delay() into loop() in both programs to reduce the possibilitiy of data collisions. Although you are using 2 pipes on your receiver it has only one wireless for listening.

IMHO a much better solution would be to make the "Receiver" into the master and have it query each of the other "slaves" in turn. That way there will never be a data collision. Have a look at the 2nd example (which uses the ackPayload feature) in this Simple nRF24L01+ Tutorial. There is also an example illustrating a master working with 2 slaves.

...R

Alright, I used the ackPayload feature in the example and set a short delay like you suggested, but I am still experiencing data collision when both transmitters are running simultaneously.

I also removed the "Disconnected" statement since we're being technical :slight_smile:

Receiver 2.0

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


RF24 radio(9, 10);
const uint64_t Pipe[2] = {0xF0F0F0F0AA, 0xF0F0F0F066};
int RemOne[3] ;
int RemTwo[3] ;
int ackData[2] = {78, 90};


void setup() {
  Serial.begin(57600);
  radio.begin();
  radio.setDataRate(RF24_1MBPS);
  radio.enableAckPayload();
  // radio.openReadingPipe(1, Pipe[1]);
  //radio.openReadingPipe(0, Pipe[0]);
  radio.setChannel(99);
  radio.startListening();

  
}

void loop() {

  getData();


}

void getData() {
  radio.openReadingPipe(0, Pipe[0]);
  if ( radio.available() ) {
    radio.read(&RemOne, sizeof(RemOne) );
    radio.writeAckPayload(0, &ackData, sizeof(ackData));
    Serial.print(" RemOne: ");
    Serial.print(RemOne[0]);
    Serial.print(RemOne[1]);
    Serial.println("   ");
  }
  delay(50);
 
  radio.openReadingPipe(1, Pipe[1]);
  if (radio.available()) {
    radio.read(&RemTwo, sizeof(RemTwo));
    radio.writeAckPayload(1, &ackData, sizeof(ackData));
    Serial.print("RemTwo: ");
    Serial.print(RemTwo[0]);
    Serial.print(RemTwo[1]);
    Serial.println("    ");

  }


}

Remote (I just changed the address per transmitter)

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


RF24 radio(9,10);
const uint64_t Pipe[2] = {0xF0F0F0F0AA, 0xF0F0F0F066};
int Rem1[3]={9,2, 1};

int ackData[2]={ -1 ,-1};


void setup(){
  pinMode(butPin1, INPUT);
  pinMode(butPin2, INPUT);
  pinMode(ledPin, OUTPUT);
  radio.begin();
  radio.setChannel(99);
  radio.setDataRate(RF24_1MBPS);
  radio.enableAckPayload();
  radio.setRetries(3,5); 
  radio.openWritingPipe(Pipe[0]);
    
  Serial.begin(9600);
  Serial.println("TX Rem A");
 
}

void loop(){
  send();

}

void send(){
   radio.write(Rem1, sizeof(Rem1));
     if ( radio.isAckPayloadAvailable() ) {
        radio.read(&ackData,sizeof(ackData));
        Serial.print("Acknowledge received: ");
        Serial.print(ackData[0]);
        Serial.print("  ");
        Serial.println(ackData[1]);
         }
     else {
            Serial.println("  Acknowledge but no data ");
        }    
  
}

Also, Ty for the quick response

McRookie:
Alright, I used the ackPayload feature in the example

I don't understand --- you are not using the code from my examples. Have you actually tried it?

It looks as if you have put a delay() in your receiver program. The delay() needs to be in the transmitters. Putting a delay() in the receiver code will just make matters worse - think about it. And start with delay(1000). If that works, try reducing the interval.

...R