NRF24L01: Unable to send bidirectional concatenated text messages

Hi everyone! :wave:t5:

I'm experiencing difficulties sending both plain text and concatenated text messages in a bidirectional communication setup between NRF24L01 modules. I would greatly appreciate any guidance you could provide, as I'm unable to find relevant references.

Project:
Transmitter contains the push buttons and Receiver contains 2 pumps and 2 temperature sensors (DS18B20). Button1 controls Pump1, Button2 controls Pump2, and Button3 controls two DS18B20.

(1) The NFR24L01 TRANSMITTER detects the pressed buttons and sends the array "Message1" to the NFR24L01 RECEIVER to execute an action.

(2) The NFR24L01 RECEIVER executes the action and sends back the array "Message2" to the NFR24L01 TRANSMITTER.


Issue
Pertains to (2). I'm unable to figure out how to send "Message2" and receive it. I have indicated the issue where I comment 'HERE IS MY ISSUE'.` What's odd is that when I print the messages for testing in the Serial Monitor of the receiver (COM3), it displays correctly. But in the transmitter (COM4), I get a '⸮⸮⸮⸮⸮#e⸮⸮'. I expect to receive on COM4 what is on COM3.

CODES

//NFR24L01 TRANSMITTER CODE

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

//PINS------------------------------------------------------------------------------------------------------------------------
// NRF24L01 Pins
RF24 radio(7, 8); // CE, CSN 
const byte address[][10] = {"00001","00002"};//addresses that receives and transfer data
// Pump Pins
const int pinPushButton1 = 22; //Controls Pump1
const int pinPushButton2 = 23; //Controls Pump2
// DS18B20 Pins
const int pinPushButton3 = 24; //Controls DS18B20

//VARIABLES------------------------------------------------------------------------------------------------------------------------
// NRF24L01 Variables
int Message1[3];
String Message2[4];

//MAIN------------------------------------------------------------------------------------------------------------------------
void setup() {
  pinMode(pinPushButton1, INPUT_PULLUP); // Pump1 - Enable internal pull-up resistor for button
  pinMode(pinPushButton2, INPUT_PULLUP); // Pump2 - Enable internal pull-up resistor for button
  pinMode(pinPushButton3, INPUT_PULLUP); // DS18B20
  
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address[0]);//address of transmitter
  radio.openReadingPipe(1, address[1]);//address of receiver - specify the ch-freq in which receives 
  radio.setPALevel(RF24_PA_MAX);//set power amplifier level (minimum since NRFs are close)
}

void loop() {
  
  delay(10);

  radio.stopListening(); //transmit
  
  Message1[0] = digitalRead(pinPushButton1); // Pump1 button current state
  Message1[1] = digitalRead(pinPushButton2); // Pump2 button current state
  Message1[2] = digitalRead(pinPushButton3); // DS18B20
  radio.write(Message1, sizeof(Message1));

  delay(10);

//HERE IS MY ISSUE  
  radio.startListening(); //receive

  if (radio.available()) 
  {
    radio.read(Message2, sizeof(Message2));
    Serial.println(Message2[0]);
    Serial.println(Message2[1]);
    Serial.println(Message2[2]);
  }
}
// NFR24L01 RECEIVER CODE

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

//PINS------------------------------------------------------------------------------------------------------------------------
// NFR24L01 Pins
RF24 radio(7, 8); // CE, CSN 
const byte address[][10] = {"00001","00002"};//addresses that receives and transfer data
// Pump Pins
const int pinRelay1 = 9;
const int pinRelay2 = 10;
// DS18B20 Pins
#define ONE_WIRE_BUS 25 // Data wire is plugged into pin 25 on the Arduino

//VARIABLES------------------------------------------------------------------------------------------------------------------------
// NRF24L01 Variables
int Message1[3];
String Message2[4];
// Pump Variables
bool previousButtonState1 = HIGH; // Variable to store the previous state of the button. Initially high (not pressed)
bool previousButtonState2 = HIGH; // Variable to store the previous state of the button. Initially high (not pressed)
bool printedState = false; // Flag to control the printing of the state
enum State1 {OFF1,ON1}; // States of Pump1
enum State2 {OFF2,ON2}; // States of Pump2
State1 state1 = OFF1;
State2 state2 = OFF2;
State1 previousState1 = OFF1;
State2 previousState2 = OFF2;
// DS18B20 Variables
enum State3 {OFF3, ON3};
State3 state3 = OFF3;
unsigned long lastDebounceTime = 0;  // millisecond timestamp for last button press
const unsigned long debounceDelay = 200; // milliseconds

// DS18B20 Variables
int buttonState3; //button for temperature sensor DS18B20

//FUNCTIONS---------------------------------------------------------------------------------------------------------------------
// Pump Functions
void turnonPump1();
void turnoffPump1();
void turnonPump2();
void turnoffPump2();
// DS18B20 Functions
void readtemperature();

//OBJECTS------------------------------------------------------------------------------------------------------------------------
// DS18B20 Objects
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature. 

//MAIN------------------------------------------------------------------------------------------------------------------------
void setup() {

  pinMode(pinRelay1, OUTPUT); // Initialize relay pin as output
  pinMode(pinRelay2, OUTPUT); // Initialize relay pin as output
  
  turnoffPump1();// Relay is initially off
  turnoffPump2();// Relay is initially off
  
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address[1]);//address of transmitter
  radio.openReadingPipe(1, address[0]);//address of receiver - specify the ch-freq in which receives 
  radio.setPALevel(RF24_PA_MAX);//set power amplifier level (minimum since NRFs are close)

  sensors.begin(); // DS18B20
}

void loop() {

  delay(10);
  
  radio.startListening(); //receive
  
  if (radio.available()) 
  {
    radio.read(Message1, sizeof(Message1));
    int buttonState1 = Message1[0]; // Pump1 button current state
    int buttonState2 = Message1[1]; // Pump2 button current state
    int buttonState3 = Message1[2]; // DS18B20 button current state
    
    // Pump1 Control
    if (buttonState1 != previousButtonState1) { //Compare previous and current states of the button1
      if (buttonState1 == LOW) {  //keep the button1 activated
        turnonPump1(); // Turn on Pump1
        state1 = ON1;
      } else {
        turnoffPump1(); // Turn off Pump1
        state1 = OFF1;
      }
      previousButtonState1 = buttonState1; // Update previous button state for button 1
    }

    // Pump2 Control
    if (buttonState2 != previousButtonState2) { //Compare previous and current states of the button2
      if (buttonState2 == LOW) { //keep the button2 activated
        turnonPump2(); // Turn on Pump2
        state2 = ON2;
      } else {
        turnoffPump2(); // Turn off Pump2
        state2 = OFF2;
      }
      previousButtonState2 = buttonState2; // Update previous button state for button 2
    } 
    delay(5);// Wait to avoid button bounces

    // DS18B20 Control
    if ((millis() - lastDebounceTime) > debounceDelay && buttonState3 == LOW) {
      readtemperature(); //Read temperatures from DS18B20 sensors
      state3 = ON3;
      lastDebounceTime = millis(); // Update debounce timer
    } else {
      state3 = OFF3;
    }
  }
  
  delay(10);

//HERE IS MY ISSUE
  radio.stopListening(); //transmit
  
  if (state1 != previousState1) { //Compare previous and current states of the button1 
    switch (state1) {
      case OFF1:
        Message2[0] = "PUMP 1 OFF";
        radio.write(Message2, sizeof(Message2));
        Serial.println(Message2[0]); //TEST
        break;
      case ON1:
        Message2[0] = "PUMP 1 ON";
        radio.write(Message2, sizeof(Message2));
        Serial.println(Message2[0]); //TEST
        break;
    }
   previousState1 = state1; //update state1
  }
  
  if (state2 != previousState2) { //Compare previous and current states of the button2
    switch (state2) {     
      case OFF2:
        Message2[1] = "PUMP 2 OFF";
        radio.write(Message2, sizeof(Message2));
        Serial.println(Message2[1]); //TEST
        break;
      case ON2:
        Message2[1] = "PUMP 2 ON";
        radio.write(Message2, sizeof(Message2));
        Serial.println(Message2[1]); //TEST
        break;
    }
   previousState2 = state2; //update state2
  }
  
  if (state3 == ON3) { //Compare previous and current states of the button3 
    Message2[2]="Temperatura 1: " + String(sensors.getTempCByIndex(0)); // Temperature from the sensor 1
    Message2[3]="Temperatura 2: " + String(sensors.getTempCByIndex(1)); // Temperature from the sensor 2
    radio.write(Message2, sizeof(Message2));
    Serial.println(Message2[2]); //TEST 
    Serial.println(Message2[3]); //TEST 
  }
}

//FUNCTIONS------------------------------------------------------------------------------------------------------------------------
void turnonPump1() {
  digitalWrite(pinRelay1, LOW);
}

void turnoffPump1() {
  digitalWrite(pinRelay1, HIGH);
}

void turnonPump2() {
  digitalWrite(pinRelay2, LOW);
}

void turnoffPump2() {
  digitalWrite(pinRelay2, HIGH);
}

void readtemperature(){
  sensors.requestTemperatures(); // Send the command to get temperatures  
}

The String type is a class, it doesn't contains a text itself, but only a link to the string. So you can't send the text as

Try this:
radio.write(Message2.c_str(), Message2.length() +1);
or use a char array instead

Thank you for the contribution, I reconsidered the communication with "char" and made some modifications, it worked!

        strcpy(Message2, "PUMP 2 OFF");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST

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