Es posible programar NodeMCU con reloj NTP + Alexa + LCD + botones

Hola a todos y espero se encuentren bien, soy Miguel Díaz y estoy pidiendo ayuda con un NodeMCU ESP8266 para programarlo ya que antes yo programaba PICs con lenguaje Basic pero ahora me estoy modernizando con Arduino por sus multiples ventajas de velocidad, capacidad, etc., pero estoy viendo que utiliza otro lenguaje muy diferente al que estoy acostumbrado y se me ha complicado, anteriormente hice un proyecto de automatizar mi luz de cochera con LCD se encendía y se apagaba a cierta hora y es programable ahora con la nueva tecnología (nodemcu) quiero que ponga la hora NTP poder apagar y encender manualmente y con Alexa, claro conectado a un LCD 16x2 ya pude compilar sin errores el reloj NTP y con Alexa pero al dar la instrucción de prender luz a Alexa se reinicia el nodemcu por eso la pregunta del titulo es posible juntar los códigos ya que por separado me funcionan a la perfección pero los junto y sale ese problema me apoyan por favor ya me atore :o se los agradecería mi código es el siguiente:) :

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <LiquidCrystal.h>
#include “fauxmoESP.h”
#define SERIAL_BAUDRATE 115200 //Velocidad del Puerto Serial
#define WIFI_SSID “TTyKmK” //Credenciales de RED
#define WIFI_PASS “123456”
fauxmoESP fauxmo;
bool estadoDispositivos[1]= {false};
// Dispositivos
#define PIN_1 D0
#define DISPOSITIVO_1 “Luz Cochera”

LiquidCrystal lcd(D6, D5, D1, D2, D3, D4);
int status = WL_IDLE_STATUS;
const long utcOffsetInSeconds = -21600; //Zona horaria (GMT-6) con formula (-66060 = -21600)
char daysOfTheWeek[7][12] = {“Domingo”, “Lunes”, “Martes”, “Miercoles”, “Jueves”, “Viernes”, “Sabado”};

// Define el cliente NTP para obtener el Tiempo
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, “mx.pool.ntp.org”, utcOffsetInSeconds);

void setup()
{
Serial.begin(SERIAL_BAUDRATE); //Iniciando puerto serial
pinMode(PIN_1, OUTPUT); //Ponemos el pin como salida
digitalWrite(PIN_1, LOW); //Apagamos el pin
lcd.begin(16, 2); //Iniciamos el LCD Display 16x2

//Conectamos el Wifi se dirige a la variable declarada wifiSetup
wifiSetup();

//Imprimimos el estado del WiFi en Display y Monitor serial se dirige a la variable declarada printWiFiStatus
printWifiStatus();
Serial.println("\nIniciando la conexión al servidor NTP…");

//fauxmo.createServer(true); // not needed, this is the default value
//fauxmo.setPort(80); // This is required for gen3 devices
// Habilitamos la librería para el descubrimiento y cambio de estado de los dispositivos
fauxmo.enable(true);
// Damos de alta el dispositivo
fauxmo.addDevice(DISPOSITIVO_1);
// Decimos cuales van a ser nuestras funciones para obtener estado y para establecerlo…
fauxmo.onSetState((unsigned char idDispositivo, const char * nombreDispositivo, bool estado)
{
Serial.printf(“Dispositivo #%d (%s) estado: %s\n”, idDispositivo, nombreDispositivo, estado ? “encendido” : “apagado”);

// Establecemos el estado del dispositivo concreto
estadoDispositivos[idDispositivo] = estado;

// En función del dispositivo recibido…
switch (idDispositivo)
{
case 0:
{
digitalWrite(PIN_1, estado);
}
break;
}
delay(50);
});

fauxmo.onGetState(obtenerEstado);
}

void loop()
{
fauxmo.handle();
static unsigned long last = millis();
if (millis() - last > 5000) {
last = millis();
Serial.printf("[MAIN] Free heap: %d bytes\n", ESP.getFreeHeap());
}

timeClient.update();
//Imprime en Monitor Serial el día de la semana y el tiempo cada segundo
Serial.print(daysOfTheWeek[timeClient.getDay()]);
Serial.print("-> ");
/Serial.print(timeClient.getHours());
Serial.print(":");
Serial.print(timeClient.getMinutes());
Serial.print(":");
Serial.println(timeClient.getSeconds());
/
Serial.println(timeClient.getFormattedTime());
//Imprime en Display el día de la semana y el tiempo cada segundo
lcd.setCursor(0, 0);
lcd.print(daysOfTheWeek[timeClient.getDay()]);
lcd.setCursor(0, 1);
lcd.print(timeClient.getFormattedTime());
delay(1000);
}

bool obtenerEstado(unsigned char idDispositivo, const char * nombreDispositivo)
{
return estadoDispositivos[idDispositivo];
}

//Istrucciones a realizar - Variable declarada WiFiSetup
void wifiSetup()
{
//Realizando la conexion del WiFi al NodeMCU
Serial.println();
Serial.printf("conectandose a WiFi: ", WIFI_SSID);
Serial.println();
WiFi.begin(WIFI_SSID, WIFI_PASS);

//Esperamos a que la conexión esté lista
while ( WiFi.status() != WL_CONNECTED)
{
lcd.clear();
lcd.print("Conectandose a ");
lcd.setCursor(0, 1);
lcd.print("WiFi: ");
lcd.print(WIFI_SSID);

delay(500);
}

}
//Istrucciones a realizar - Variable declarada printWiFiStatus
void printWifiStatus()
{
//Imprime en Display y Monitor Serial la conexion realizada al SSID y espera por 2 segundos
lcd.clear();
lcd.print(“Conectado a wifi”);
lcd.setCursor(5, 1);
lcd.print(WiFi.SSID());
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.println(“Conectado con exito al wifi”);
delay(2000);

//Imprime en Display y Monitor Serial la direccion IP y espera por 2 segundos
IPAddress ip = WiFi.localIP();
Serial.print("Direccion IP: ");
Serial.println(ip);
lcd.clear();
lcd.print("Direccion IP: ");
lcd.setCursor(2, 1);
lcd.print(ip);
delay(2000);

//Imprime en Display y Monitor Serial la intensidad de señal RSSI y espera por 2 segundos
long rssi = WiFi.RSSI();
Serial.print(“Intensidad de señal (RSSI):”);
Serial.print(rssi);
Serial.println(" dBm");
lcd.clear();
lcd.print(“Intensidad(RSSI)”);
lcd.setCursor(5, 1);
lcd.print(rssi);
lcd.print(" dBm ");
delay(2000);

//Imprime en Display la conexion del NTP por 2 segundos
lcd.clear();
lcd.print(“Conectando al”);
lcd.setCursor(0, 1);
lcd.print(“Servidor NTP”);
lcd.setCursor(12, 1);
lcd.print(".");
delay(500);
lcd.setCursor(13, 1);
lcd.print(".");
delay(500);
lcd.setCursor(14, 1);
lcd.print(".");
delay(500);
lcd.setCursor(15, 1);
lcd.print(".");
delay(500);
lcd.clear();
}

Moderador
Por favor edita tu post usando etiquetas de código.

Normas del foro

Lo primero que te pido es que no compartas jamas SSID y clave de tus proyectos. Nunca sabes quien esta mirando lo que haces.

EL ESP8266 cuando no esta cómodo con algo reacciona como lo has indicado, reinicíandose.
Mi consejo es que tomes el código mayor y vayas incorporando paso a paso instrucciones del código menor y presta atención al comportamiento.
En algún punto aparecerá que lo hace inestable.

Mi pregunta es: El reloj NTP funciona correctamente supongo?
Me parece que el problema es una vez mas de tiempos.

Veo que fauxmoesp.h trabaja de modo asincrónico pero seguramente algo en el código agregado esta haciendo que alcance algún limite de tiempo

Tal vez tenga que ver con esto: Cuando veas un manejador como esto

  fauxmo.handle();

no puedes luego livianamente agregar demoras con delay()

  timeClient.update();
  //Imprime en Monitor Serial el día de la semana y el tiempo cada segundo
  Serial.print(daysOfTheWeek[timeClient.getDay()]);
  Serial.print("-> ");
  /*Serial.print(timeClient.getHours());
  Serial.print(":");
  Serial.print(timeClient.getMinutes());
  Serial.print(":");
  Serial.println(timeClient.getSeconds());*/
  Serial.println(timeClient.getFormattedTime());
  //Imprime en Display el día de la semana y el tiempo cada segundo
  lcd.setCursor(0, 0);
  lcd.print(daysOfTheWeek[timeClient.getDay()]);
  lcd.setCursor(0, 1);
  lcd.print(timeClient.getFormattedTime());
  delay(1000);

ni hablar de WifiStatus que tiene delay() por todos lados.

delay() solo detiene al micro de hacer algo y se queda mirando la luna o sea haciendo nada.
Aunque no sea directamente el responsable, no es correcto hacerlo de ese modo.

La hora no se va a desplazar en tu ESP a menos que pase un buen lapso de tiempo, digamos 10 miin.
Mientras existen alternativas a presentar la hora usando el recursos internos. Cada 10 min consultas si esta actualizada y si no lo está la actualizas.

Hola, Surbyte te ha encaminado bien, el problema es el delay(50) que has puesto en la función lambda de fauxmo.getState, con la de abajo me compila correctamente, mi alexa detecta bien el dispositivo y lo enciende y apaga correctamente:

fauxmo.onSetState([](unsigned char idDispositivo, const char * nombreDispositivo, bool estado,unsigned char value)
  {
    
    Serial.printf("Dispositivo #%d (%s) estado: %s\n", idDispositivo, nombreDispositivo, estado ? "encendido" : "apagado");
    // Establecemos el estado del dispositivo concreto
    estadoDispositivos[idDispositivo] = estado;
    // En función del dispositivo recibido...
    switch (idDispositivo) 
    {
      case 0:
        {
          digitalWrite(PIN_1, estado);
        }
        break;
    }
   //delay(50);
  });

Estoy usando la ultima versión de fauxmoESP y he tenido que hacer varios cambios para que funcione:
En funcion lambda de onSetState tiene un parámetro más(char value) y no existe la función miembro onGestState.
Por otro lado para que mi Alexa pudiera detectar el dispositivo he tenido que descomentar:

fauxmo.createServer(true); // not needed, this is the default value
fauxmo.setPort(80); // This is required for gen3 devices

Y compilar con LwIP set to "v1.4 Higher Bandwidth", como indica en la pagina de la libreria: GitHub - simap/fauxmoesp: Clone of https://bitbucket.org/xoseperez/fauxmoesp. No sé como se hace eso con el IDE de Arduino, te pongo el archivo de conf. de platformio, que es lo que uso por si te sirve de ayuda:

[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
upload_speed = 921600
monitor_speed = 115200
build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
lib_deps = 
	arduino-libraries/LiquidCrystal@^1.0.7
	vintlabs/FauxmoESP@^3.2

Saludos