nrf24l01 project 4 transmitters and 12 receivers

past couple of weeks i've been playing around with wireless communication and i've managed to make; one way and bi-directional projects each with 1 transmitter and 1 receiver. now for my next project i would like to make 4 groups of 1 transmitter talking to 3 receivers without each group interfering with each other

each transmitter includes;
6 momentary push buttons
3 leds

each receiver includes;
1 led

so the idea is that 1 button activates one led or two leds so;

button 1 = led 1
button 2 = led 2
button 3 = led 3
button 4 = led 1&2
button 5 = led 1&3
button 6 = led 2&3

this combination will be repeated for the rest of the transmitters and receivers and all have to be able to work at the same time without interfering.

the 3 leds on the transmitter will indicate if each receiver is connected to the transmitter, this part i have achieved by connection the 5v pin to a digital pin and labelling it an input. see the attached code.

i've been trying to adjust this code to control a second led however i'm drawing a blank. if you could only use the activation of led in your reply's that would be most helpful since, i'll also be great full if you explained your answers step by step.

Wireless_Led_Control_Transmitter_With_Led_Indicator.ino (872 Bytes)

Wireless_Led_Control_Receiver_With_Led_Indicator.ino (843 Bytes)

Your transmitter code has no mention of any second or third LED or any of the multiple buttons you mention. It looks like stock example code.

Post your attempted code and where you are having problem and people will help. If you want to hire someone to write the code for you, post in the Gigs forum.

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

It includes an example for a master and 2 slaves that can easily be extended to a larger number of slaves - for example one Tx and 4 Rx.

If you use a different channel (frequency) and different addresses for each group they won't interfere with each other.

...R

Robin2:
If you use a different channel (frequency) and different addresses for each group they won't interfere with each other.

Using a different frequency is enough to isolate the groups.
Remember that 2 MHz transmission need a distance of two channels.

Whandall:
Using a different frequency is enough to isolate the groups.

Agreed.

However I suspect that also using different addresses will make the project easier to manage - for example GRPA1, GRPA2 and GRPB1, GRPB2 etc

..R

this is the code i have tried but couldn't get it to work

Wireless_Led_Control_Transmitter_1_3.ino (982 Bytes)

Wireless_Led_Control_Receiver_1.ino (572 Bytes)

Wireless_Led_Control_Receiver_2.ino (543 Bytes)

Blue_aoi:
this is the code i have tried but couldn't get it to work

What did you think of my suggestion?

Did you try it?

...R

hi robin2

do you have a more detailed explanation on what each line of code does in your 1 master 2 slaves, as i'm trying to modify it for my application and unsure of what i need to change/ remove for my project

Blue_aoi:
do you have a more detailed explanation on what each line of code does in your 1 master 2 slaves, as i'm trying to modify it for my application and unsure of what i need to change/ remove for my project

I don't.

But if you post your best attempt at a modification and tell me what you are hoping to do I will look at it.

However I am NOT going to look at your code unless you first confirm that you have tried my programs with no changes and got them working.

...R

Robin2 i have tried your code and it works fine for the simple 2 way transmission

what i have tried to modify your code to do is;

Master transmitter
output led
output led 1
input button
input button 1

1st slave receiver
output led

2nd slave receiver
output led

what i tried to make happened before i got quickly confused is
when all nrf24l01 turn on the 2 slaves send a single back to the master turning on the output leds to show single has been connected.

when input button is pressed on master, ouput led on 1st slave receiver turns on, when button is released it turns off

when input button1 is pressed on master, ouput led on 2nd slave receiver turns on, when button is released it turns off

Wireless_Led_Control_Receiver_With_Led_Indicator_1_1.ino (1.32 KB)

Wireless_Led_Control_Receiver_With_Led_Indicator_1_2.ino (1.28 KB)

It's much easier for people to help you if you include short programs in your Post so they don't have to download them. Like this
Rx1

// SimpleRx - the slave or the receiver

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

#define CE_PIN   7
#define CSN_PIN 8

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

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
char txNum = '0';
int ackData[2] = {-1, -1};
boolean button_state = 0;
boolean receiver_state = 0;
int led_pin = 2;
int receiver_pin = 4;


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

void setup() {

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.setPALevel(RF24_PA_MIN);
    radio.enableAckPayload();
    
    radio.startListening();

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


void getData() {

  delay (5)
  if ( radio.available() ) {
  radio.read(&button_state, sizeof(button_state));
  if (button_state == HIGH) {
  digitalWrite(led_pin, HIGH);
  }
  else {
  digitalWrite(led_pin, LOW);
  }
  delay(100);
  }

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

void updateReplyData() {
    ackData[0] -= 1;
    ackData[1] -= 1;
    if (ackData[0] < 100) {
        ackData[0] = 109;
    }
    if (ackData[1] < -4009) {
        ackData[1] = -4000;
    }
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}

Rx2

// SimpleRx - the slave or the receiver

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

#define CE_PIN   7
#define CSN_PIN 8

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

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
boolean button_state = 0;
boolean receiver_state = 0;
int led_pin = 3;
int receiver_pin = 4;


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

void setup() {

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.setPALevel(RF24_PA_MIN)
    radio.enableAckPayload();
    
    radio.startListening();

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


void getData() {

  delay (5)
  if ( radio.available() ) {
  radio.read(&button_state, sizeof(button_state));
  if (button_state == HIGH) {
  digitalWrite(led_pin, HIGH);
  }
  else {
  digitalWrite(led_pin, LOW);
  }
  delay(100);
  }

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

void updateReplyData() {
    ackData[0] -= 1;
    ackData[1] -= 1;
    if (ackData[0] < 100) {
        ackData[0] = 109;
    }
    if (ackData[1] < -4009) {
        ackData[1] = -4000;
    }
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}
[/code

...R

You also need to post the Master program - the two sides to wireless are essential.

It is not good practice to add the action code into the getData() function. It would make things much easier to develop maintain and debug if it is in a separate function so the different parts can be tested separately. Perhaps like this

void getData() {
    if ( radio.available() ) {
        radio.read(&button_state, sizeof(button_state));
        newData = true;
    }
}

void updateLED() {
    if (newData == true) {
      if (button_state == HIGH) {
          digitalWrite(led_pin, HIGH);
      }
      else {
          digitalWrite(led_pin, LOW);
      }
    newDate = false;
   }
}

Also, don't have a delay() in the Rx program. It should be listening all the time. Use the Master program to determine the time. Or use millis() in the Rx program to implement a non-blocking time interval.

...R

sorry about that i thought i attached it

master transmitter;

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

#define CE_PIN   7
#define CSN_PIN 8

const byte numSlaves = 2;
const byte slaveAddress[numSlaves][5] = { {'R','x','A','A','A'},{'R','X','B','A','A'} };
                                                   

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

//~ char dataToSend[10] = "Message 0";
char dataToSend[10] = "ToSlvN  0";
char txNum = '0';
int ackData[2] = {-1, -1}; // to hold the two values coming from the slave
int button_pin = 9;
int button_pin1 = 3;
boolean button_state = 0;
boolean button_state1 = 0;
int button_value = 0;
int button_value1 = 0;
int led = 5;
int led1 = 4;
boolean receiver_state = 0;
boolean receiver_state1 = 0;


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

void setup() {
pinMode(button_pin, INPUT);
pinMode(button_pin1, INPUT);
pinMode(led, OUTPUT);
pinMode(led1, OUTPUT);
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setPALevel(RF24_PA_MIN);
    radio.enableAckPayload();

    radio.setRetries(3,5); // delay, count
        // radio.openWritingPipe(slaveAddress); -- moved to loop()
}

void loop() {

     // call each slave in turn
    for (byte n = 0; n < numSlaves; n++){

            // open the writing pipe with the address of a slave
        radio.openWritingPipe(slaveAddress[n]);

            // include the slave number in the message
        dataToSend[5] = n + '0';}

 {   
  {
    delay(5);
    radio.stopListening();
    button_state = digitalRead(button_pin);
    radio.write(&button_state, sizeof(button_state));
    delay(100);
  }
  {
    
    radio.startListening();
    radio.read(&receiver_state, sizeof(receiver_state));
    if (receiver_state == HIGH) {
    digitalWrite(led, HIGH);
    }
    else 
    {
    digitalWrite(led, LOW);
    }
  }
 }
}

Wireless_Led_Control_Transmitter_With_Led_Indicator_1_3.ino (2.05 KB)

Your master program is all mixed up. Look at the example in Reply #17 in my tutorial and see how yours differs from it. For example you terminate this FOR loop much too early

     // call each slave in turn
    for (byte n = 0; n < numSlaves; n++){

...R

i think my main issue is that i don't know enough about coding myself, i can see what your code does robin i think i just lack the knowledge to modify it. i'll probably need to break this down section by section. i found a post that was of 1 master 10 receivers, seeing that his project worked i tried to copy his code and adjust it, current code for the master probably wrong though.

master

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

RF24 radio(7, 8);
const byte masteraddress[5] = {'T','X','a','a','a'};
const byte address1[5] = {'R','x','A','A','A'};
const byte address2[5] = {'R','x','A','A','B'};
   
int button_pin1 = 9;
int button_pin2 = 6;
boolean button_state1 = 0;
boolean button_state2 = 0;
boolean receiver_state1 = 1;
int button_value = 0;
int led = 2;
viod setup
pinMode(button_pin1, INPUT);
pinMode(button_pin2, INPUT);
pinMode(led, OUTPUT);
radio.begin();  
         
radio.setPALevel(RF24_PA_MIN);  //You can set it as minimutance between the transmitter and receiver.
radio.setRetries(3,5); // delay, count
}
void loop()
{
  {
    radio.openWritingPipe(address1);
    radio.stopListening();
    button_state1 = digitalRead(button_pin1);
    radio.write(&button_state1, sizeof(button_state1));
    
   }
    radio.openWritingPipe(address2);
    radio.stopListening();
    button_state2 = digitalRead(button_pin2);
    radio.write(&button_state2, sizeof(button_state2));

{
    radio.openReadingPipe(0, masteraddress);
    radio.startListening();
    radio.read(&receiver_state1, sizeof(receiver_state1));
    if (receiver_state1 == HIGH) {
    digitalWrite(led, HIGH);
    }
    else 
    {
    digitalWrite(led, LOW);}}
 
}

one salve

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

RF24 radio(7, 8);
const byte masteraddress[5] = {'T','X','a','a','a'};
const byte address1[5] = {'R','x','A','A','A'};
boolean button_state1 = 0;
boolean receiver_state1 = 0;
int led_pin = 2;
int receiver_pin = 6;

void setup() 
{
pinMode(led_pin, OUTPUT);
pinMode(receiver_pin, INPUT);
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1, address1);  
radio.setPALevel(RF24_PA_MIN);
radio.setRetries(3,5); // delay, count
radio.startListening();              
}

void loop()
{
  if ( radio.available());
  radio.read(&button_state1, sizeof(button_state1));
  if (button_state1 == HIGH) {
    digitalWrite(led_pin, HIGH);
  }
  else {
    digitalWrite(led_pin, LOW);
  }
  {
  radio.openWritingPipe(masteraddress);  
  radio.stopListening();
  receiver_state1 = digitalRead(receiver_pin);
  radio.write(&receiver_state1, sizeof(receiver_state1));
  }
}

Blue_aoi:
i found a post that was of 1 master 10 receivers, seeing that his project worked i tried to copy his code and adjust it, current code for the master probably wrong though.

This is confusing. Are you working with my code or another person's? Sorry, but I am too lazy to figure out another person's code, however good it may be.

I don't know why you say "probably wrong". Surely you tested it before posting a question here?

Please don't post a program in pieces - it is all too easy to make mistakes when trying to join pieces so I never do try.

...R

so i've managed to get all 3 receivers working at the same time. When i want one button to activate led on receiver 1 and 2 both are a solid on but now when i press buttons 1 & 2 they flash, how do i remove this flash

Master

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

RF24 radio(7, 8);
const byte address1[5] = {'R','x','A','A','A'}; 
const byte address2[5] = {'R','x','A','A','B'};
const byte address3[5] = {'R','x','A','A','C'};
int button_pin1 = 9;
int button_pin2 = 6;
int button_pin3 = 5;
int button_pin4 = 4;
boolean button_state1 = 0;
boolean button_state2 = 0;
boolean button_state3 = 0;
boolean button_state4 = 0;
int button_value1 = 0;
int button_value2 = 0;
int button_value3 = 0;
int button_value4 = 0;
 

void setup() {
pinMode(button_pin1, INPUT);
pinMode(button_pin2, INPUT);
pinMode(button_pin3, INPUT);
pinMode(button_pin4, INPUT);
radio.begin(); 
radio.setDataRate( RF24_250KBPS );                 
radio.setPALevel(RF24_PA_MIN); 
radio.setRetries(3,5);
}

void loop()
{   
  delay(50);
    {
    radio.openWritingPipe(address1); 
    radio.stopListening();
    button_state1 = digitalRead(button_pin1);
    radio.write(&button_state1, sizeof(button_state1));
    button_state1 = digitalRead(button_pin4);
    radio.write(&button_state1, sizeof(button_state1));
    
    }    
  {
    radio.openWritingPipe(address2); 
    radio.stopListening();
    button_state2 = digitalRead(button_pin2);
    radio.write(&button_state2, sizeof(button_state2));
    button_state2 = digitalRead(button_pin4);
    radio.write(&button_state2, sizeof(button_state2));
  }
 
 {
    radio.openWritingPipe(address3); 
    radio.stopListening();
    button_state3 = digitalRead(button_pin3);
    radio.write(&button_state3, sizeof(button_state3));
 }
 
 }

reveiver 1

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

RF24 radio(7, 8);
const byte address1[5] = {'R','x','A','A','A'};
boolean button_state1 = 0;
int led_pin = 3;

void setup() 
{
pinMode(led_pin, OUTPUT);
radio.begin();
radio.setDataRate( RF24_250KBPS ); 
radio.setPALevel(RF24_PA_MIN); 
radio.openReadingPipe(1, address1);  
radio.startListening();   
radio.setRetries(3,5);           
}

void loop()
{
  
  while (!radio.available());
  radio.read(&button_state1, sizeof(button_state1));
    if (button_state1 == HIGH){
    digitalWrite(led_pin, HIGH);
  }
  else {
    digitalWrite(led_pin, LOW);
  }
 

  
}

receiver 2

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



RF24 radio(7, 8);
const byte address2[5] = {'R','x','A','A','B'};
boolean button_state2 = 0;
boolean button_state4 = 0;
int led_pin = 3;

void setup() 
{
pinMode(led_pin, OUTPUT);
radio.begin();
radio.setDataRate( RF24_250KBPS ); 
radio.setPALevel(RF24_PA_MIN); 
radio.openReadingPipe(1, address2);  
radio.startListening();     
radio.setRetries(3,5);     
}

void loop()
{
  
  while (!radio.available());
  radio.read(&button_state2, sizeof(button_state2));
  if (button_state2 == HIGH) {
    digitalWrite(led_pin, HIGH);
  }
  else {
    digitalWrite(led_pin, LOW);
  }
  radio.read(&button_state4, sizeof(button_state4));
  if (button_state4 == HIGH) {
    digitalWrite(led_pin, HIGH);
  }
  else {
    digitalWrite(led_pin, LOW);
}

The organisation of your system is badly mixed up.

In your TX code...
Put radio.stopListening() in setup() - there no need to keep repeating it in loop()

Read all the buttons one after the other at the start of loop() and save their values - keep the button reading separate from the wireless code.

At least for testing increase the delay(50) to delay(500) - to get a human speed (or slowness)

To make the code in the Receivers as near identical as possible send two values to every receiver

Send the two values in a single message - for example

byte buttonTxData[2];  // this goes at the top of the program

then to send the values to the receiver at address1

buttonTxData[0] = button1State
buttonTxData[1] = button4State
radio.openWritingPipe(address1); 
radio.write(&buttonTxData, sizeof(buttonTxData));

Then in your Rx program ...
You need to receive the data into an identical array to the way it is sent
byte buttonRxData[2];

and receiving should be like this

if (radio.available()) {
  radio.read(&buttonRxData, sizeof(buttonRxData));

You now have two values and you can either use them directly or copy them to other variables as you choose. For example

button1State = buttonRxData[0];
button4State = buttonRxData[1];

if (button1State == HIGH) {
  // etc
  // etc

...R

this so i've got this now, i'll still a little confused about the buttontxdata= button1state part

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

RF24 radio(7, 8);
const byte address1[5] = {'R','x','A','A','A'}; 
const byte address2[5] = {'R','x','A','A','B'};
const byte address3[5] = {'R','x','A','A','C'};
byte buttonTxData[2];


int button_pin1 = 9;
int button_pin2 = 6;
int button_pin3 = 5;
int button_pin4 = 4;
int button_pin5 = 3;
int button_pin6 = 2;
boolean button_state1 = 0;
boolean button_state2 = 0;
boolean button_state3 = 0;
boolean button_state4 = 0;
boolean button_state5 = 0;
boolean button_state6 = 0;
int button_value1 = 0;
int button_value2 = 0;
int button_value3 = 0;
int button_value4 = 0;
int button_value5 = 0; 
int button_value6 = 0; 

void setup() {
pinMode(button_pin1, INPUT);
pinMode(button_pin2, INPUT);
pinMode(button_pin3, INPUT);
pinMode(button_pin4, INPUT);
pinMode(button_pin6, INPUT);




radio.begin(); 
radio.setDataRate( RF24_250KBPS );                 
radio.setPALevel(RF24_PA_MIN); 
radio.setRetries(5,5);
radio.stopListening();
}

void loop()
{
button_state1 = digitalRead(button_pin1);
button_state1 = digitalRead(button_pin4);
button_state1 = digitalRead(button_pin6);

button_state2 = digitalRead(button_pin2);
button_state2 = digitalRead(button_pin4);
button_state2 = digitalRead(button_pin5);

button_state3 = digitalRead(button_pin3);
button_state3 = digitalRead(button_pin5);
button_state3 = digitalRead(button_pin6);
}

{  delay(500);
    {
    radio.openWritingPipe(address1); 
    radio.write(&button_state1, sizeof(button_state1));
    radio.write(&button_state1, sizeof(button_state1));
    radio.write(&button_state1, sizeof(button_state1));
    
    }    
  {
    radio.openWritingPipe(address2); 
    radio.write(&button_state2, sizeof(button_state2));
    radio.write(&button_state2, sizeof(button_state2));
    radio.write(&button_state2, sizeof(button_state2));    
  }
 
 {
    radio.openWritingPipe(address3); 
    radio.write(&button_state3, sizeof(button_state3));
    radio.write(&button_state3, sizeof(button_state3));
    radio.write(&button_state3, sizeof(button_state3));
 }
 }

This makes no sense

button_state1 = digitalRead(button_pin1);
button_state1 = digitalRead(button_pin4);
button_state1 = digitalRead(button_pin6);

You are writing 3 different values to the same variable so only the last value will be remembered. It should be

button1state = digitalRead(button_pin1);
button4state = digitalRead(button_pin4);
button6state = digitalRead(button_pin6);

// etc.

I suspect if you sort that out the rest of the stuff will be more obvious.

I have changed the style of the variable names slightly because IMHO the variable holds the state of a particular button whereas (in my mind anyway) button_state1 implies that a button can have several states, not that there are several buttons. Of course either style will be perfectly acceptable to the compiler.

...R