I am trying to connect three NRF24l01 RF modules

Hello,

I am working on the following project as describes below.

  1. I have three nrf24l01modules
  2. I have connected each module with each Arduino uno board
  3. first nrf24l01 module is transmitter, second nrf24l01 module is extender and third nrf24l01 modules is receiver
  4. Now I have written a code in transmitter that if I connect pin2 with GND then the message should only go through extender module and send to the receiver.
  5. whenever receiver receives this message from extender the relay module connected to the receiver should ON, if the pin2 is disconnected on transmitter side then relay on receiver should be OFF. There should not be a direct connection between transmitter and receiver modules.
  6. If I disconnect the extender module then the receiver module should complain that no devices connected and transmitter should report that no devices connected.
  7. If transmitter off and both extender and receiver ON then the externder should display a message like no devices connected until sender connected.
  8. Need to have mechanism to check the device connectivity continuously without effecting the data sending by the transmitter throughout reciever.

I am having the following sketch for each module:

Extender:

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

#define GREEN_LED 2  // LED for connection status

#define DATA_CHANNEL 110

RF24 radio(8, 9);  // CE, CSN pins

// Addresses for communication
const uint64_t DATA_ADDRESS = 0xF0F0F0F0E1LL;

void setup() {
    pinMode(GREEN_LED, OUTPUT);
    digitalWrite(GREEN_LED, LOW);  // Ensure LED is off initially

    radio.begin();
    radio.setPALevel(RF24_PA_LOW);
    
    // Setup the data channel
    radio.setChannel(DATA_CHANNEL);
    radio.openReadingPipe(1, DATA_ADDRESS);

    Serial.begin(9600); 
    radio.startListening();  // Start listening for messages
}

void loop() {
    if (radio.available()) {
        uint8_t pipeNum;
        char receivedMessage[32] = "";
        radio.read(&receivedMessage, sizeof(receivedMessage));

        Serial.print("Received from Transmitter: ");
        Serial.println(receivedMessage);

        // Forward the message to the receiver
        forwardData(receivedMessage);
    }
}

void forwardData(const char* message) {
    radio.stopListening();  // Stop listening to send data

    // Create a new message with the "Extender:" prefix
    char forwardedMessage[64] = "Extender:";
    strcat(forwardedMessage, message);  // Append the original message

    // Ensure the string is null-terminated to avoid corruption
    forwardedMessage[63] = '\0';  // Ensuring no overflow

    // Debugging output: Display the forwarded message
    Serial.print("Forwarding message: ");
    Serial.println(forwardedMessage);

    // Open the pipe to the receiver
    radio.openWritingPipe(DATA_ADDRESS);

    if (!radio.write(forwardedMessage, strlen(forwardedMessage) + 1)) {
        Serial.println("Failed to forward message.");
    } else {
        Serial.println("Message forwarded successfully.");
    }

    radio.startListening();  // Start listening again
}

Transmitter:

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

#define CONTROL_PIN 2     // Pin 2 for control functionality
#define GREEN_LED 4       // LED for connection status

#define DATA_CHANNEL 110

RF24 radio(8, 9);

// Addresses for communication
const uint64_t DATA_ADDRESS = 0xF0F0F0F0E1LL;
bool extenderPresent = false; // Assume no extender is present initially

void setup() {
    pinMode(CONTROL_PIN, INPUT_PULLUP); // Control pin
    pinMode(GREEN_LED, OUTPUT);          // LED for connection status
    
    radio.begin();
    radio.setPALevel(RF24_PA_LOW);
    
    // Setup the data channel
    radio.setChannel(DATA_CHANNEL);
    radio.openWritingPipe(DATA_ADDRESS);
    Serial.begin(9600);
}

void loop() {
    checkConnection();

    const char* message;
    if (digitalRead(CONTROL_PIN) == LOW) {
        message = extenderPresent ? "Extender:SENDER:pin2connected" : "SENDER:pin2connected";
    } else {
        message = extenderPresent ? "Extender:SENDER:pin2disconnected" : "SENDER:pin2disconnected";
    }

    sendData(message); // Send regardless of extender presence for testing
  
    // Blink LED if not connected
    if (!radio.available()) {
        blinkLed(GREEN_LED);
    } else {
        digitalWrite(GREEN_LED, HIGH);  // Stay ON if connected
    }
  
    delay(100); // Adjust delay as necessary
}

void checkConnection() {
    // Logic to update extenderPresent based on actual connection can be added here
}

void sendData(const char* message) {
    Serial.print("Sending data message: ");
    Serial.println(message);
    
    radio.stopListening();  // Switch to send mode
    if (!radio.write(message, strlen(message) + 1)) {
        Serial.println("Failed to send data message.");
    } else {
        Serial.println("Data message sent successfully.");
    }
  
    radio.startListening();  // Return to listening mode
}

void blinkLed(int pin) {
    digitalWrite(pin, LOW);
    delay(100);
    digitalWrite(pin, HIGH);
    delay(100);
}

Receiver:

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

// Define pins
#define RELAY_PIN 4       // Pin to control relay
#define RED_LED 2        // Red LED for extender connection
#define BLUE_LED 3       // Blue LED for direct sender connection

#define DATA_CHANNEL 110

RF24 radio(8, 9);  // CE, CSN pins

// Addresses for communication
const uint64_t DATA_ADDRESS = 0xF0F0F0F0E1LL;

bool extenderPresent = false; // Track if the extender is connected

void setup() {
    pinMode(RELAY_PIN, OUTPUT);
    pinMode(RED_LED, OUTPUT);
    pinMode(BLUE_LED, OUTPUT);
    digitalWrite(RELAY_PIN, HIGH);  // Ensure relay is OFF initially
    digitalWrite(RED_LED, LOW);      // Ensure RED LED is OFF
    digitalWrite(BLUE_LED, LOW);     // Ensure BLUE LED is OFF

    Serial.begin(9600); // Start Serial for debugging
    radio.begin();
    radio.setPALevel(RF24_PA_LOW);

    // Setup the data channel
    radio.setChannel(DATA_CHANNEL);
    radio.openReadingPipe(1, DATA_ADDRESS);

    radio.startListening();  // Start listening for messages
}

void loop() {
    handleDataMessage();
}

void handleDataMessage() {
    uint8_t pipeNum;
    while (radio.available(&pipeNum)) {
        char receivedMessage[32] = "";
        radio.read(&receivedMessage, sizeof(receivedMessage));

        Serial.print("Received: ");
        Serial.println(receivedMessage);

        // Check for extender connection status
        if (strstr(receivedMessage, "Extender:connected") != NULL) {
            extenderPresent = true;
            Serial.println("Extender is now connected.");
            digitalWrite(RED_LED, HIGH);   // Indicate extender is connected
            digitalWrite(BLUE_LED, LOW);    // Turn off blue LED
        }

        if (strstr(receivedMessage, "Extender:disconnected") != NULL) {
            extenderPresent = false;
            Serial.println("Extender is now disconnected.");
            digitalWrite(RED_LED, LOW);    // Turn off red LED
            digitalWrite(BLUE_LED, LOW);   // Turn off blue LED
        }

        // Handle messages based on extender presence
        if (extenderPresent) {
            if (strstr(receivedMessage, "Extender:") != NULL) {
                if (strstr(receivedMessage, "pin2connected") != NULL) {
                    digitalWrite(RELAY_PIN, LOW);  // Turn relay ON
                    Serial.println("Relay turned ON from Extender");
                } else if (strstr(receivedMessage, "pin2disconnected") != NULL) {
                    digitalWrite(RELAY_PIN, HIGH);  // Turn relay OFF
                    Serial.println("Relay turned OFF from Extender");
                }
            } else {
                Serial.println("Message ignored as it was not from Extender.");
            }
        } else {
            Serial.println("Extender not connected; ignoring messages.");
        }
    }
}

after executing these sketches, i found the weird behavior that the receiver always connects with transmitter though I connect or disconnect the extender module.

please help me how to resolve this. This is my wiring diagram whenever I press the button on transmitter the message should go though the extender to receiver.

Extender:

image

I think these devices can use a star-topology network, so one missing node would only be known if its activity was not received.

This looks like bit complex and my requirement diesnot have base module to talk with multiple nodes.

RF24 communication between multiple devices can be a bit complex, that's why there are libraries built to handle this complexity. Although, really you are just using one address, you need separate addresses to handle 3 devices. See TMRh20s Project Blog for a detailed explanation.

Libraries:

GitHub - Hobietime/RF24G: This library provides a simple way for up to 6 nRF24L01 radios to communicate with each other. - Recently updated to handle up to 7-devices in a mesh style network, need to install from ZIP for latest changes.

GitHub - nRF24/RF24Network: OSI Layer 3 Networking for nRF24L01(+) and nRF52x on Arduino and Raspberry Pi - A bit more complicated to use than RF24G, but works in a similar way, uses a Tree topology.

1 Like

My requirement is

I have radio1 which sends ping and data to the radio2 (if radio2 exists in-between radio1 and radio N) now the radio2 will transfer the ping and data (received from radio1) to radioN which is final receiver.

My plan is one channel for continuous ping from radio1 to radio N and one channel for ack from radioN to radio1 and one channel for data only from radio1 to radioN.

I may add multiple radios inbetween radio1 and radioN.

The data only transfer from top to bottom which means the data flow from radio1 to RadioN includes inbetween radio's if any.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.