Relay gets stuck and RF issue

Hi everyone :wave:t5:,

Please, I need your insights on two issues in this bidirectional communication project:

  1. RELAY GETS STUCK IN CLOSED POSITION WHEN A 12V/400mA PUMP IS CONNECTED:
    (See diagrams images) While Buttons are pressed on the TX, Pumps on the RX are activated via relays. Releasing the button stops the Pumps.
    Problem: If a button is held for more than 6 seconds when a mini pump is connected, the relay remains closed, preventing the pump from shutting down until the program is reset. (This does not occur when no pump is connected.)

  2. MESSAGE 2 RETURNS INCOMPLETE
    (See "Code Logic" image) TX sends Message 1 with buttons states, RX controls actuators, then generates Message 2 accordingly the action taken, printing and sending it back to the TX.
    Problem: (See "Serial Monitors" image) Despite proper display by the RX, the TX sometimes skips action messages.

Thank you!




4. COM Transmitter
5. COM Receiver

//TRANSMITTER TX

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

//PINS------------------------------------------------------------------------------------------------------------------------
// NRF24L01 Pins
RF24 radio(9, 8); // CE, CSN 
const byte address[][10] = {"00001","00002"};//addresses that receives and transfer data
// Pump Pins
const int Button1 = 7; //Controls Pump1
const int Button2 = 6; //Controls Pump2
// DS18B20 Pin
const int Button3 = 5; //Controls DS18B20
// DC Pins
int vry = A1; // Potentiometer VRY (Y-AXIS)in the Joystick KY023

//VARIABLES------------------------------------------------------------------------------------------------------------------------
// NRF24L01 Variables
int Message1[4];
char Message2[50];

//MAIN------------------------------------------------------------------------------------------------------------------------
void setup() {
  pinMode(Button1, INPUT_PULLUP); // Pump1 - Enable internal pull-up resistor for button
  pinMode(Button2, INPUT_PULLUP); // Pump2 - Enable internal pull-up resistor for button
  pinMode(Button3, 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)

  delay(10);
}

void loop() {
  
  delay(10);

  radio.stopListening(); //transmit
  
  Message1[0] = digitalRead(Button1); // Pump1 button current state
  Message1[1] = digitalRead(Button2); // Pump2 button current state
  Message1[2] = digitalRead(Button3); // DS18B20
  Message1[3] = analogRead(vry)*(437.0/1023.0); //Joystick DC - Scale: 0-437rpm
  radio.write(Message1, sizeof(Message1));

  radio.startListening(); //receive

  if (radio.available()) 
  {
    // Read data into the Message2 array
    radio.read(&Message2, sizeof(Message2)); // Correct usage for arrays
    Serial.println(Message2);
  }
} 
   
//RECEIVER RX

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "BTS7960.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 Relay1 = 9;
const int Relay2 = 10;

// DC Pins
int pinA = 2; // Channel A in the DC Motor Encoder
int pinB = 3; // Channel B in the DC Motor Encoder
int RPWM = 4; // RPWM on the BTS7960
int LPWM = 5; // LPWM on the BTS7960
int EN = 6; // L_EN and R_EN on the BTS7960
const int PushTop = 32; //end of stroke 1 (top)
const int PushEnd = 34; //end of stroke 2 (end)

//VARIABLES------------------------------------------------------------------------------------------------------------------------
// NRF24L01 Variables
int Message1[4];
char Message2[50];

// 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 = 1000; // milliseconds
int buttonState3; //button for temperature sensor DS18B20

// DC Variables
int speed = 0; //Speed for soft start
float sp; // Set point 
float pv; // From encoder
volatile int contador = 0;
unsigned long previousMillis = 0;
long interval = 100; //100
enum State {OFF,UP,DOWN}; // States of DC
State state = OFF; // Current state of DC
State previousState = OFF; // Previous state of DC

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

// DS18B20 Functions
void readtemperature();

// DC Functions
void interrupcion();
void stopmotor();
void upmotor();
void downmotor();

//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. 

//DC Objects
BTS7960 motorController(EN, LPWM, RPWM); //Initialize the motor controller

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

  pinMode(Relay1, OUTPUT); // Initialize relay pin as output
  pinMode(Relay2, OUTPUT); // Initialize relay pin as output
  pinMode(pinA, INPUT); //DC
  pinMode(pinB, INPUT); //DC
  pinMode(RPWM, OUTPUT); //DC
  pinMode(LPWM, OUTPUT); //DC
  pinMode(EN, OUTPUT); //DC
  pinMode(PushTop, INPUT_PULLUP); //DC
  pinMode(PushEnd, INPUT_PULLUP); //DC

  digitalWrite(RPWM, LOW); //DC
  digitalWrite(LPWM, LOW); //DC
  digitalWrite(EN, HIGH);  //DC - Enable "Right" and "Left" movement on the HBridge
  
  turnoffPump1();// Pump1 initially off
  turnoffPump2();// Pump2 initially off
  stopmotor(); //DC 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
  attachInterrupt(0, interrupcion, RISING); //DC - Rising edge on PIN 2 (Channel A in the DC Motor Encoder)
}

void loop() {

  delay(10);
  
  radio.startListening(); //receive

  int buttonTop = digitalRead(PushTop); //DC
  int buttonEnd = digitalRead(PushEnd); //DC

  motorController.Enable(); //DC - Activate motor controller
  unsigned long currentMillis = millis();//DC

  if ((currentMillis - previousMillis)>= interval) //DC - si es mayor que el intervalo (1seg) hace lo que esta adentro
  {
    previousMillis = currentMillis;
    pv = 10*contador*(60.0/211.2); //RPM del eje principal
    contador = 0;
  } 
  
  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
    sp = Message1[3]; //Joystick DC
    
    // Relay1 + 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
    }
    delay(5);// Wait to avoid button bounces

    // Relay2 + 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(5);// Wait to avoid button bounces

    // DC Control
    if (sp > 224.0 && sp < 227.0){
      stopmotor();
      state = OFF;
    } 
    delay(5);// Wait to avoid button bounces
  
    if (sp > 227.0){
      if (buttonTop == HIGH) {
        upmotor();
        state = UP;
      } else {
        stopmotor();
        state = OFF;
      }
    } 
    delay(5);// Wait to avoid button bounces
  
    if (sp < 224.0) {
      if (buttonEnd == HIGH) {
        downmotor();
        state = DOWN;
      } else {
        stopmotor();
        state = OFF;
      }
    }
    delay(5);// Wait to avoid button bounces
  }
  
  delay(10);

  radio.stopListening(); //transmit
  
  if (state1 != previousState1) { //Compare previous and current states of the button1 
    switch (state1) {
      case OFF1:
        strcpy(Message2, "PUMP 1 OFF");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST
        break;
      case ON1:
        strcpy(Message2, "PUMP 1 ON");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST
        break;
    }
   previousState1 = state1; //update state1
  }
  
  if (state2 != previousState2) { //Compare previous and current states of the button2
    switch (state2) {     
      case OFF2:
        strcpy(Message2, "PUMP 2 OFF");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST
        break;
      case ON2:
        strcpy(Message2, "PUMP 2 ON");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST
        break;
    }
   previousState2 = state2; //update state2
  }
  
  if (state3 == ON3) { //Compare previous and current states of the button3 

    //Read temperatures
    float temp1 = sensors.getTempCByIndex(0);
    float temp2 = sensors.getTempCByIndex(1);
   
    // Crear cadenas para las temperaturas
    char tempStr1[20];
    char tempStr2[20];
    
    // Formatear temperaturas en cadenas
    dtostrf(temp1, 4, 2, tempStr1);
    dtostrf(temp2, 4, 2, tempStr2);
    
    // Construir el mensaje
    sprintf(Message2, "T1: %s°C\nT2: %s°C", tempStr1, tempStr2); 

    radio.write(&Message2, sizeof(Message2));
    Serial.println(Message2);//TEST
  }

    if (state != previousState) {
      switch (state) {
        case OFF:
          strcpy(Message2, "DC OFF");
          radio.write(&Message2, sizeof(Message2));
          Serial.println(Message2); //TEST
          break;
        case UP:
          strcpy(Message2, "DC UP");
          radio.write(&Message2, sizeof(Message2));
          Serial.println(Message2); //TEST
          break;
        case DOWN:
          strcpy(Message2, "DC DOWN");
          radio.write(&Message2, sizeof(Message2));
          Serial.println(Message2); //TEST
          break;
        }
      previousState = state; // update previousState
    }
   delay(10);
}

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

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

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

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

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

void interrupcion(){
  contador++; //Count rising edges
}

void stopmotor(){
  motorController.Stop();
  motorController.Disable();  
}

void upmotor(){
  motorController.TurnRight(sp-227.0); //analog outputs doesn't give more than 255
}

void downmotor(){
  motorController.TurnLeft(224.0-sp); 
}

Your transmitter code apparently sends all the time. Is that really necessary, or is it perhaps a better idea to only send something if there's any relevant update for the receiver?

Keep in mind that you're apparently doing some form of bidirectional communication. What happens if the receiver tries to talk back to the transmitter while the latter is sending? It's easy for them to get stuck in a loop where they're both listening and talking at the same time.

I'd tackle this issue first and then see how much of your original problems remain.

I suggest you remove the radios for now and concentrate on getting serial communications working without them, then when you are happy with that add the radios in. At that point you will know the communications work OK without the radios, so any problems will be radio related, not related to anything else.

Start with this:

You could also do with knowing how to read buttons properly, Here is my tutorial:

There's also the state change example in the IDE file / examples / digital / state change detection
Reading buttons correctly is a common topic here, so some reading of the forum will also help.

You need to get rid of the delay and learn how to code without them. Delay might be a quick fix at the moment, but the more you use it the more it will cause you problems.

What is this for:

pinMode(Button3, INPUT_PULLUP); // DS18B20

Why are you reading a DS18B20? How has that got anything to do with what you are doing? A DS18B20 is a 1 wire device and isn't read like that anyway.

2 Likes

Hi rsmls. I added a condition where the transmitter sends data only when one of the buttons is pressed and doesn't continuously send empty data. But it didn't make any difference.

  if (digitalRead(Button1) == LOW || digitalRead(Button2) == LOW || digitalRead(Button3) == LOW) {
    Message1[0] = digitalRead(Button1); // Pump1 button current state
    Message1[1] = digitalRead(Button2); // Pump2 button current state
    Message1[2] = digitalRead(Button3); // DS18B20
    Message1[3] = analogRead(vry)*(437.0/1023.0); //Joystick DC - Scale: 0-437rpm
  
    radio.write(Message1, sizeof(Message1));
  }

Well, to be more accurate: it only sends data while a button is pressed. I'd suggest sending data only once after a button has been pressed.

I also agree with what @PerryBebbington said above - separate the two problems. Work on the RF problem in one test sketch, and set up a different test sketch for the relay problem. Once everything works reliably, start merging them together. Presently it's unclear which problem has which cause(s).

1 Like

Hi Perry.

  1. Yes, I have tested the RX, which activates actuators in isolation without RF, and it worked perfectly. Furthermore, when the RX and TX are interconnected by RF, the TX sends Message 1 (buttons states) perfectly, and the RX displays Message 2 (action taken) properly in its Serial Monitor. The problem is that the RX is not sending Message 2 correctly to the TX, or the TX is not capturing and displaying Message 2 properly in its Serial Monitor.

  2. I will check the debouncing again.

  3. Yes, maybe delays() are desynchronizing the communication. I will review how to avoid them using only millis().

  4. DS18B20 sensors send temperature data from the water containers.

Thank you.

Ok, I got it. I'll make the modifications in the code and disconnect the relay to focus solely on the RF.
Regarding sending data while a button is pressed, it's because the pumps run while their respective button is being pressed and stop when it is released. However, I will test also if changing the logic to activate pumps by simply turning them on with one press and turning them off with another press yields different result

One possibility would be to send a start message when the button becomes pressed and a stop message when the button becomes released. To avoid the possibility of the stop message being missed you could send the start message every, say, 5 seconds and have a timeout on the receiver so it turns off if it doesn't get a start message after 6 seconds.

2 Likes

Which relay or relay module are you using? Do you have a kickback suppression diode in parallel with the pump?

Hi! I am using a Songle relay module (maybe not very reliable).

I placed a 1N 4001 diode but the relay still gets stuck after keeping the pump activated for approximately 15 seconds.

Does the relay module have a "pilot light" that indicates when it is energized? Is it ON or OFF when the relay is "stuck"?

Yes, while the relay is energized, red led is on. When the relay gets stuck, green led remains on.
I replaced the 1N4001 with a 1N4007 and added a 0.1uF capacitor in parallel. The sticking problems disappeared, even with the relay closed for more than 30 sec during some tests.

Apparently, the stuck relay problem disappeared. Now, I must focus on resolving the NRF24L01 issue with the recommendations given above.

Current situation:

Previous situations:

Does the RED light stay on?

If the RED light indicates the relay's status (ON / OFF), is it ON when the relay is energized? Does it change states when the relay is "stuck"?

Yes, when the relay got stuck, the red led was also on. For now, after adding the diode and capacitor in parallel, that issue has been resolved. Thank you! :grinning:

Now, I just need to tackle the communication problem as described in the tables above. It might be a code issue or a damaged module. I'll buy a new one for testing today and review my code as PerryBebbington and rsmls suggest. If you have any insight on this, I would appreciate it, dude.

Great! No comments on code at the moment, good luck.

1 Like

That is the classic symptom of your pump drawing TOO much current for TOO long of a time. Don't take the sellers word for the current, which is the RUNNING current, but measure the STARTING/STALLING current yourself.

1 Like

Hi, @danielarg1990

Now we need you to please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Not a cut and paste image, use pen(cil) and paper.

What are you using for power supplies?
What model NRF are you using, the plus versions?

A picture of your project would also help.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

1 Like

Hi @TomGeorge !

I took a step back to start troubleshooting RF communication. I also followed @PerryBebbington suggestion about using millis() instead of delay() and it improved the performance.

Setup (as the original post)
TX (Nano) send Message 1(activation commands) to RX (Mega).
RX activates pumps, displays Message 2 (action taken), and sends it back to TX.

Test results (see photos and diagram):
Message 2 displayed properly on RX but sometimes skips message lines on TX.

SET UP




TEST RESULTS
Captura de pantalla 2024-04-21 125713
Imagen de WhatsApp 2024-04-21 a las 14.50.52_97e9d5a7

TX CODE (on Nano)

//TRANSMITTER

#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 Button1 = 6; //Controls Pump1
const int Button2 = 5; //Controls Pump2
// DS18B20 Pin
const int Button3 = 4; //Controls DS18B20

//VARIABLES------------------------------------------------------------------------------------------------------------------------
// NRF24L01 Variables
int Message1[3];
char Message2[50];

//MAIN------------------------------------------------------------------------------------------------------------------------
void setup() {
  pinMode(Button1, INPUT_PULLUP); // Pump1 - Enable internal pull-up resistor for button
  pinMode(Button2, INPUT_PULLUP); // Pump2 - Enable internal pull-up resistor for button
  pinMode(Button3, 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 

  delay(10);
}

void loop() {
  
  delay(10);

  radio.stopListening(); //transmit

    Message1[0] = digitalRead(Button1); // Pump1 button current state
    Message1[1] = digitalRead(Button2); // Pump2 button current state
    Message1[2] = digitalRead(Button3); // DS18B20

    radio.write(Message1, sizeof(Message1));

  radio.startListening(); //receive

  if (radio.available()) 
  {
    // Read data into the Message2 array
    radio.read(&Message2, sizeof(Message2)); // Correct usage for arrays
    Serial.println(Message2);
  }
} 
   

RX CODE (on Mega)

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

//TIMERS ()-----------------------------------------------------------------------------------------------------------------
#define BUTTON_STATE_CHECK_INTERVAL 10 // Check button state every 10 milliseconds
#define TEMP_READ_INTERVAL 1000 // Read temperature every 1 second

//PINS AND PIPES---------------------------------------------------------------------------------------------------------------
// 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 24 // Data wire is plugged into pin 25 on the Arduino

//VARIABLES------------------------------------------------------------------------------------------------------------------------
// NRF24L01 Variables
int Message1[3];
char Message2[50];
// 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
unsigned long lastDebounceTime = 0; // debounce timer for Button 3
const unsigned long debounceDelay = 1000; //milliseconds
unsigned long lastTempReadTime = 0;
enum State3 {OFF3, ON3};
State3 state3 = OFF3;
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();// Pump1 initially off
  turnoffPump2();// Pump2 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() {

  unsigned long currentTime = millis();
  unsigned long lastButtonStateCheckTime = 0;
  
  // Check button state at regular intervals
  if (currentTime - lastButtonStateCheckTime >= BUTTON_STATE_CHECK_INTERVAL) {
    lastButtonStateCheckTime = currentTime;

    radio.startListening(); // Start listening for radio messages
  
    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
      } 
  
      // DS18B20 Control
      if ((currentTime - lastTempReadTime) >= TEMP_READ_INTERVAL && buttonState3 == LOW && (currentTime - lastDebounceTime >= debounceDelay)) {
        readtemperature(); //Read temperatures from DS18B20 sensors
        state3 = ON3;
        lastDebounceTime = millis(); // Update debounce timer
      } else {
        state3 = OFF3;
      }
    }
  }

  delay(10); //Wait a short time before switching from listening to transmitting (avoid interference)
  radio.stopListening(); //transmit
    
  if (state1 != previousState1) { //Compare previous and current states of the button1 
    switch (state1) {
      case OFF1:
        strcpy(Message2, "PUMP 1 OFF");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST
        break;
      case ON1:
        strcpy(Message2, "PUMP 1 ON");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST
        break;
    }
    previousState1 = state1; //update state1
  }
    
  if (state2 != previousState2) { //Compare previous and current states of the button2
    switch (state2) {     
      case OFF2:
        strcpy(Message2, "PUMP 2 OFF");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST
        break;
      case ON2:
        strcpy(Message2, "PUMP 2 ON");
        radio.write(&Message2, sizeof(Message2));
        Serial.println(Message2); //TEST
        break;
    }
    previousState2 = state2; //update state2
  }

  if (state3 == ON3) { //Compare previous and current states of the button3 
    
    //Read temperatures
    float temp1 = sensors.getTempCByIndex(0);
    float temp2 = sensors.getTempCByIndex(1);
       
    // Crear cadenas para las temperaturas
    char tempStr1[20];
    char tempStr2[20];
        
    // Formatear temperaturas en cadenas
    dtostrf(temp1, 4, 2, tempStr1);
    dtostrf(temp2, 4, 2, tempStr2);
       
    // Construir el mensaje
    sprintf(Message2, "T1: %sC\nT2: %sC", tempStr1, tempStr2); 
    
    radio.write(&Message2, sizeof(Message2));
    Serial.println(Message2);//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  
}

This is not how you connect switches. Remove the resistors, and connect the switch directly between pin and ground. I see you have the correct pinMode(pin, INPUT_PULLUP); in your code.

Note that the 3.3volt supply of a classic Nano is much weaker than a Mega (30mA vs. 150mA).
Maybe not such a good idea to power a radio from the 3.3volt pin of a Nano.
Leo..