Problema al unir código de Nextion para leer hora, temperatura, fecha y humedad con control de relés

Hola a todos,

Estoy trabajando en un proyecto con un Arduino Mega y una pantalla Nextion de 7 pulgadas. He logrado integrar dos funcionalidades en el código:

  1. Lectura de hora, temperatura, fecha y humedad desde la pantalla Nextion, y
  2. Control de relés para prender y apagar dispositivos.

La parte de la lectura de hora, temperatura, fecha y humedad funciona perfectamente, pero al intentar unir ambas funcionalidades, el control de los relés deja de funcionar. Los relés no responden a los comandos enviados desde la pantalla Nextion, aunque todo lo demás parece estar bien.

¿Alguien ha tenido una situación similar o tiene alguna idea de qué podría estar causando este problema?

Agradezco mucho cualquier ayuda o sugerencia.

¡Gracias de antemano!

este es el codigo
#include "DHT.h"
#include <Wire.h> // Librería para la comunicación I2C
#include <RTClib.h> // Librería para manejar el RTC DS3231

#define PINDHT11 2
DHT sensordht11(PINDHT11, DHT11);

RTC_DS3231 rtc; // Crear el objeto RTC

// Pines conectados a los relés
const int relayPins[] = {22, 23, 24, 25, 26, 27, 28, 29};

// Estados de los relés (inicialmente todos apagados)
bool relayStates[8] = {false, false, false, false, false, false, false, false};

unsigned long ultimaActualizacionClock = 0; // Para actualizar cada segundo
int temperaturadht11, humedaddht11;

void setup() {
Serial.begin(9600); // Comunicación serial con Nextion
sensordht11.begin();
Wire.begin(); // Iniciar la comunicación I2C con el RTC
rtc.begin(); // Iniciar el RTC

// Configurar todos los pines de los relés como salidas
for (int i = 0; i < 8; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW); // Inicialmente todos los relés apagados
}

// Verificar si el RTC está conectado correctamente
if (!rtc.begin()) {
Serial.println("No se pudo encontrar el RTC");
while (1); // Detener el programa si no se puede encontrar el RTC
}

// Si el RTC ha perdido la alimentación, ajustamos la hora al momento de la compilación
if (rtc.lostPower()) {
Serial.println("RTC ha perdido la alimentación. Estableciendo la hora...");
rtc.adjust(DateTime(F(DATE), F(TIME))); // Ajustar la hora al momento de la compilación
}

delay(1000); // Esperar por si la pantalla se reinicia

// Ir a la página "inicio" en Nextion
Serial.print("page inicio");
enviarComandoFinal();
}

void loop() {
// Obtener temperatura y humedad del DHT11
temperaturadht11 = sensordht11.readTemperature();
humedaddht11 = sensordht11.readHumidity();

// Enviar temperatura con símbolo °C
Serial.print("te.txt="");
Serial.print(temperaturadht11); // Temperatura sin el símbolo
Serial.print((char)0xB0); // Agregar el símbolo ° usando su código ASCII
Serial.print("C""); // Continuar con "C"
enviarComandoFinal();

delay(400);

// Enviar humedad con símbolo %
Serial.print("hu.txt="");
Serial.print(humedaddht11);
Serial.print("%""); // Agregar el símbolo de porcentaje
enviarComandoFinal();

delay(1000);

// Leer la hora y la fecha del RTC
DateTime now = rtc.now();

// Si ha pasado un segundo (milisegundos >= 1000)
if (millis() - ultimaActualizacionClock >= 1000) {
ultimaActualizacionClock = millis();

// Formatear la hora en formato HH:MM
char bufferHora[9];
sprintf(bufferHora, "%02d:%02d", now.hour(), now.minute());

// Enviar la hora al Nextion
enviarComandoNextion("hor.txt=\"" + String(bufferHora) + "\"");

// Formatear la fecha en formato DD/MM/YYYY
char bufferFecha[11];
sprintf(bufferFecha, "%02d/%02d/%04d", now.day(), now.month(), now.year());

// Enviar la fecha al Nextion
enviarComandoNextion("fe.txt=\"" + String(bufferFecha) + "\"");

}

// Leer datos enviados por Nextion para controlar los relés
if (Serial.available()) {
String command = readNextionData(); // Leer datos enviados por Nextion

Serial.print("Comando recibido: ");
Serial.println(command);

for (int i = 0; i < 8; i++) {
  // Formar el comando esperado (por ejemplo: "toggle1", "toggle2", etc.)
  String expectedCommand = "toggle" + String(i + 1);

  if (command == expectedCommand) {
    relayStates[i] = !relayStates[i];  // Alternar estado del relé
    digitalWrite(relayPins[i], relayStates[i] ? HIGH : LOW);  // Actualizar el relé
    Serial1.println(relayStates[i] ? "Relé " + String(i + 1) + " ENCENDIDO." : "Relé " + String(i + 1) + " APAGADO.");

    // Enviar el nuevo estado al Nextion para sincronizar el botón
    if (relayStates[i]) {
      Serial1.println("print \"bt" + String(i) + "_on\"");  // Botón ON
    } else {
      Serial1.println("print \"bt" + String(i) + "_off\""); // Botón OFF
    }
  }
}

}
}

// Función para leer datos y filtrar caracteres finales de Nextion (0xFF 0xFF 0xFF)
String readNextionData() {
String data = "";
while (Serial.available()) {
char c = Serial.read();
if (c == '\xFF') { // Ignorar fin de comando de Nextion
continue;
}
data += c;
}
data.trim(); // Eliminar espacios o caracteres extra
data.replace("\r", "");
data.replace("\n", "");
return data;
}

// Función para enviar comandos a Nextion
void enviarComandoFinal() {
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
}

// Función para enviar comandos a Nextion
void enviarComandoNextion(String comando) {
Serial.print(comando); // Enviar comando al Nextion
Serial.write(0xFF); // Finalizar el comando con el byte 0xFF
Serial.write(0xFF); // Finalizar el comando con el byte 0xFF
Serial.write(0xFF); // Finalizar el comando con el byte 0xFF
}

Moderador:
He editado tu código porque no usaste las etiquetas como se pide en las normas.
Por favor, lee las Normas del foro y la próxima postea tu código/error usando etiquetas de código.
Si no luce bien, ve a edición, luego selecciona todo el código que has publicado, lo cortas y click en (<CODE/>)


Tu error esta en usar delay(XXX)
Cuando el código se encuentra con esa instrucción no hace nada por los XXX milisegundos indicados entre paréntesis.
Para leer un DHT necesitas una pausa de 2 segundos entre lectura y lectura, nada mas, lo demás sobra
Si quieres mostrar que el reloj se actualiza cada seg entonces ve a Documentación y aprende a usar millis().
Crea con millis() una acción que se ejecute cada 2 seg y actualice temperatura y humedad.
Crea otra acción con otra variable y millis() que lo haga cada segundo y muestras el tiempo de ese instante.

Podrías tmb hacer solo una acción que ocurra cada 1 segundo, actualice el tiempo y cuando sean 2 pasadas actualice temperatura y humedad del DHT.
Todo eso permitirá que el código fluya sin delays.

Muchísimas gracias por tu ayuda, ahora al voy a ver