Chatbot de Telegram con ESP32 tarda mucho en responder

Hola, tengo el siguiente script cargado a una ESP32 donde implemento un bot de Telegram. El bot algunas veces responde al instante, pero en ocasiones, tarda demasiado en responder mi mensaje (hasta 2 minutos). Por medio de impresiones seriales de depuración me di cuenta que la línea específica donde se tarda es "int NewMessages = bot.getUpdates(bot.last_message_received + 1);" dentro del loop. El dispositivo lo tengo muy cerca del router y mi internet va bien, entonces no sé cual sea el problema.

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>

//Datos de la red:
const char* ssid = "mi ssid";
const char* password = " mi contraseña";

#define BOTtoken "token"
#define CHAT_ID "Chat id"

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

int botRequestDelay = 1000;
unsigned long lastTimeBotRan;
unsigned long lastRiegoTime = 0;
unsigned long riegoInterval = 300000; // 5 minutos

int valHumsuelo = 0;
const int humsuelo = 32;  // Lectura del sensor
const int bombaAgua = 26; // Pin para la bomba de agua
const int LED = 2; // Pin para el led


void setup() {
  Serial.begin(115200);
  pinMode(humsuelo, INPUT);
  pinMode(bombaAgua, OUTPUT); 
  pinMode(LED, OUTPUT); 

  //Conexión
  WiFi.mode(WIFI_STA);                
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  delay(1000);                       
  while(WiFi.waitForConnectResult() != WL_CONNECTED){Serial.print(".");}
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("Your Local IP address is: ");
  Serial.println(WiFi.localIP());      //Imprimir la ip 
  client.setCACert(TELEGRAM_CERTIFICATE_ROOT);

  lastRiegoTime = millis() - riegoInterval;//Hacer que la primera lectura y riego se haga inmediatamente al empezar
}

void loop() {
  if (millis() > lastTimeBotRan + botRequestDelay)  {
    Serial.println("Comprobando mensajes");
    int NewMessages = bot.getUpdates(bot.last_message_received + 1);
    Serial.println("Comprobación finalizada")
    while(NewMessages) {
      Serial.println("Response Received!");
      NewMessagesHandle(NewMessages);
      NewMessages = bot.getUpdates(bot.last_message_received + 1);
    }
    lastTimeBotRan = millis();
    Serial.println("Nada");
  }

  if (millis() - lastRiegoTime >= riegoInterval) {
    //PARTE DE LECTURA Y RIEGO
    valHumsuelo = map(analogRead(humsuelo), 4092, 0, 0, 100);

    // Imprimir valor
    Serial.print("Humedad del suelo: ");
    Serial.print(valHumsuelo);
    Serial.println(" %");

    // Determinar el tiempo de activación de la bomba según la humedad
    int tiempoBomba = calcularTiempoBomba(valHumsuelo);

    // Activar la bomba de agua por el tiempo determinado
    if (tiempoBomba > 0) {
      String automatico = "Humedad del suelo: " + String(valHumsuelo) + "%\n";
      automatico += "Activando riego automático";
      bot.sendMessage(CHAT_ID, automatico, "");
      digitalWrite(bombaAgua, HIGH); // Activar la bomba
      digitalWrite(LED, HIGH); 
      delay(tiempoBomba); // Mantener la bomba activada por el tiempo calculado
      digitalWrite(bombaAgua, LOW); // Desactivar la bomba
      digitalWrite(LED, LOW); 
      bot.sendMessage(CHAT_ID, "Riego automático finalizado", "");
    }
    lastRiegoTime = millis();
  }
}

int calcularTiempoBomba(int humedad) {
  // Asignar un tiempo de activación de la bomba en milisegundos basado en la humedad
  if(humedad < 10){
    return 2000; // 2 segundos
  } else if(humedad < 20){
    return 1500; // 1.5 segundos
  } else {
    return 0; 
  }
}

void NewMessagesHandle(int NewMessages) {
  Serial.println("NewMessagesHandle");
  Serial.println(String(NewMessages));

  for (int i=0; i<NewMessages; i++) {
    String chat_id = String(bot.messages[i].chat_id);
    if (chat_id != CHAT_ID){
      bot.sendMessage(chat_id, "Usuario no autorizado", "");
      continue;
    }
    
    String text = bot.messages[i].text;
    Serial.println(text);

    String from_name = bot.messages[i].from_name;

    if (text == "/start") {
      String welcome = "Hola " + from_name + ".\n";
      welcome += "Comandos: \n\n";
      welcome += "/regar Para activar el riego\n";
      welcome += "/humedad Para consultar la humedad del suelo\n";
      bot.sendMessage(chat_id, welcome, "");
    }

    if (text == "/regar") {
      bot.sendMessage(chat_id, "Activando riego", "");
      digitalWrite(LED, HIGH); 
      digitalWrite(bombaAgua, HIGH); // Activar la bomba
      delay(1500); // Mantener la bomba activada por 1.5 segundos
      digitalWrite(bombaAgua, LOW); // Desactivar la bomba
      digitalWrite(LED, LOW); 
      bot.sendMessage(chat_id, "Riego finalizado", "");
    }

    if (text == "/humedad") {
      valHumsuelo = map(analogRead(humsuelo), 4092, 0, 0, 100);
      bot.sendMessage(chat_id, "Humedad del suelo: "+String(valHumsuelo)+"% ", "");
    }
  }
}

Su publicacion se MUEVE a su ubicacion actual ya que es mas adecuada.

Esto no está bien

int botRequestDelay = 1000;

El tiempo entre consultas tiene que ser de al menos 3 segundos, seguramente ese es el problema por el que se demora tanto.

De todos modos, por experiencia propia, no siempre la respuesta es inmediata, puede retrasarse unos cuantos segundos (aunque no tanto como 2 minutos, claro).

Hola, gracias por responder. Puse el botRequestDelay en 3 segundos y después en 5 segundos. Los primeros minutos funciona correctamente, pero pasados unos 6 o 7 minutos comienza de nuevo a atorarse en la comprobación de nuevos mensajes. Algo extraño, la desconecto y la vuelvo a conectar y ocurre lo mismo.

¿Probaste con la librería CTbot? (Ojo con la versión de ArduinoJson, leé la documentación)

1 Like

Ok, he leído un poco sobre la librería CTBot, la probaré en cuanto tenga tiempo. Gracias.

A mi me funcionó a la primera, solo hay que tener la precaución de instalar ArduinoJson versión 6.19.4 como máximo.

Acabo de probarlo con la librería CTbot y hasta ahorita funciona todo bien.