Los robots por software pueden resultar muy útiles a la hora del desarrollo de sistemas de control, mediante el uso de un Bot vamos a iniciar un chat por Telegram con una placa electrónica para leer datos de un sensor BME280 y controlar el estado de un pin.
Telegram fué anunciada oficialmente en el 2013, está enfocada a la mensajería instantánea, el envío de varios archivos y la comunicación en masa, la aplicación se parece mucho a WhatsApp con algunas funciones extras.

La idea es conectar ESP32 programado con el IDE de Arduino para que envíe mensajes de chat a Telegram, también se puede hacer lo mismo para WhatsApp sin embargo debido a las bibliotecas disponibles en este momento, es mas simple conectar con Telegram.
Para ensamblar el proyecto vamos a necesitar algunas bibliotecas siendo necesario que la versión de ArduinoJson encargada de manejar los textos de los mensajes enviados hacia y desde Telegram sea versión 5.x ya que versiones superiores no funcionan con la biblioteca de Arduino para Telegram.   

  • ArduinoJson-5.x.x.
  • Universal-Arduino-Telegram-Bot.
  • Bibliotecas para programar ESP32.

NOTA:
Para agregar las bibliotecas necesarias para el manejo de ESP32 con Arduino vamos a Archivos > Preferencias > Gestor de URLs Adiciones de Tarjetas y agregamos la siguiente línea: https://dl.espressif.com/dl/package_esp32_index.json

Como funciona?

Claro que necesitamos tener instalado Telegram en nuestro móvil y su funcionamiento se basa en los Bot (Robots de software) de Telegram. Lo primero que tenemos que hacer es crear un bot para conversar con ESP32, para esto en Telegram buscamos Botfather.

Este es un robot para crear robots, iniciamos conversación con el y escribimos /newbot donde nos preguntará el nombre del nuevo bot y el nombre de usuario, es importante que el nombre de usuario termine con la palabra bot por ejemplo prueba_bot.
Una vez que Botfather confirma la creación del nuevo bot asigna una identificación única a ese bot, este número o token será necesario para controlar el bot y debe ser privado ya que cualquiera que lo tenga controlara el robot.
En el programa para ESP32 el token declarado permite la conexión con el bot de telegram, ArduinoJson procesa las cadenas de texto de los mensajes y Arduino-Telegram-Bot hace la conexión con Telegram.  
El código completo para el ESP32 es el siguiente y se puede descargar desde el siguiente link.

/*********************************************************************** 
 *  ESP32 mediante el puerto I2C recibe informacion de 
 *  un sensor bme280, mide temperatura, humedad y presión. 
 *  Los datos del sensor se envían mediante Telegram cuando
 *  se recibe el mensaje /sensor.
 *  Cuando se recibe el mensaje /led, contesta con el estado
 *  de un led conctado al Pin5 de la placa ESP32.
 *  El mensaje /encender o /apagar controlan el estado del LED
 *  
 *  Pines usados en ESP32 GPIO_21 (SDA) y GPIO_22 (SCL), pin 5 LED
 *  www.firtec.com.ar  
***********************************************************************/
 
#include <WiFiClientSecure.h>		// Biblioteca WiFi
#include <UniversalTelegramBot.h>	// Biblioteca Telegram
#include "SparkFunBME280.h"		// Biblioteca Sensor BME280
#define ledPin 5
 
BME280 mySensorB; // I2C address 0x76 
 
// Datos de conexión con la red WiFi
const char* ssid     = "RED_Lab_1";
const char* password = "mICroLab_2020";
 
float p;   
float t;  
float h;
char msg[30];
 
// Inicia el bot de telegram con el bot token generado por Botfather
#define BOTtoken "442837211:ABFlea9Ya-JI_SOzxiP4AGSw8FFKwhyaAAM" 
	
 
WiFiClientSecure client;			// Instancia para la red WiFi
UniversalTelegramBot bot(BOTtoken, client);	// Instancia para el Bot Telegram
 
int Bot_mtbs = 200; // Espera entre mensajes
long Bot_lasttime;   
bool Start = false, bandera = false;
 
int ledStatus = 0;
void Leer_Sensor(void);	// Función para leer el sensor BME280
String chat_id;
String text;
String from_name;
 
void handleNewMessages(int numNewMessages) {
  
  for (int i=0; i<numNewMessages; i++) {
     chat_id = String(bot.messages[i].chat_id);
     text = bot.messages[i].text;
 
    from_name = bot.messages[i].from_name;
    if (from_name == "") from_name = "Guest";
 
    if (text == "/encender") {
      digitalWrite(ledPin, HIGH);   // LED encendido
      ledStatus = 1;
      bot.sendMessage(chat_id, "Led encendido!!", "");
      bandera = true;
    }
 
    if (text == "/apagar") {
      ledStatus = 0;
      digitalWrite(ledPin, LOW);    // LED apagado
      bot.sendMessage(chat_id, "Led apagado!!", "");
      bandera = true;
    }
 
    if (text == "/led") {
      if(ledStatus){
        bot.sendMessage(chat_id, "Led encendido", "");
        bandera = true;
      } else {
        bot.sendMessage(chat_id, "Led apagado", "");
        bandera = true;
      }
    }
    if (text == "/sensor") {	// Interroga por datos del sensor
       Leer_Sensor();		// Rutina del sensor BME280
       bandera = true;
    }
    
    if (text == "/start") {	// Mensaje al inicar el chat con el bot
      String welcome = "Benvenido al Bot Telegram con ESP32, " + from_name + ".\n";
      bot.sendMessage(chat_id, welcome, "Markdown");
      bandera = true;
    }
 
    else // Si el comando no es correcto envía mensaje de error con emoticon
         // Emoticones https://apps.timwhitlock.info/emoji/tables/unicode
      {
        if(bandera == false){
        String welcome = "Comando invalido \xF0\x9F\x98\x9E";
        bot.sendSimpleMessage(chat_id, welcome, "");
        }
      }
      bandera = false;
  }
}
 
void setup() {
pinMode(ledPin, OUTPUT); // ledPin es salida
  delay(10);
  digitalWrite(ledPin, LOW); // inicia apagado
  
  Serial.begin(115200);
  
  // Conectando con la red Wifi:
  Serial.print("Conectando con Wifi: ");
  Serial.println(ssid);
 
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
 
    mySensorB.setI2CAddress(0x76); // Conectando con el sensor BME280
  if(mySensorB.beginI2C() == false) Serial.println("ERROR! Sensor no encontrado");
  }
 
  Serial.println("");
  Serial.println("WiFi conectado");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}
 
void loop() {
  if (millis() > Bot_lasttime + Bot_mtbs)  {
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
 
    while(numNewMessages) {
      Serial.println("LLegó un mensaje!!");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }
      Bot_lasttime = millis();
  }
}
 
void Leer_Sensor(void){
  t = mySensorB.readTempC();
  snprintf (msg, 28, "Temperatura: %2.1f  \xF0\x9F\x86\x97 \n", t); 
  bot.sendMessage(chat_id, msg, "Markdown");
  
  p = mySensorB.readFloatPressure()/100;
  snprintf (msg, 25, "Presión: %3.1f  \xF0\x9F\x86\x97 \n", p);
  bot.sendMessage(chat_id, msg, "Markdown"); 
 
  h = mySensorB.readFloatHumidity();
  snprintf (msg, 28, "Humedad: %2.1f %%  \xF0\x9F\x86\x97 \n", h);  
  bot.sendMessage(chat_id, msg, "Markdown");
 
}

Como se puede ver en el código, la conexión con el bot se realiza usando el Token generado cuando el robot se creo, este token es único y todo el que lo posea podrá establecer un chat con la placa electrónica.
Al igual que otras aplicaciones de chat, telegram tiene servidores donde los mensajes no entregados se almacenan por ejemplo si no hay conexión de red cuando alguno de los mensajes es enviado, el mismo se entregará cuando la conexión sea posible.

 En el vídeo se puede ver el ejemplo funcionando, el programa básicamente tiene una función que recibe los mensajes nuevos y los decodifica para responder en consecuencia.
Si se recibe /led contesta con el del LED conectado al pin5, los comandos /encender o /apagar cambian de estado el LED.
El comando /sensor lleva el flujo del programa a la función que lee los datos del sensor BME280 y los envía en forma de chat agregando un emoticon al final de la línea.

Conclusiones.

Cuando necesitamos el control de sistemas a distancia muchas son las opciones disponibles, Socket de red, Servidores WEB, MQTT, etc, sin embargo el uso de bots simplifica mucho el trabajo, ese ejemplo funciona perfectamente con un Arduino Uno y el Shield Ethernet solo hemos usado ESP32 por tener una opción WiFi.

También podríamos tener cualquier microcontrolador (PIC, Atmel, ARM, etc) conectado a ESP32 mediante la UART y usarlo como enlace con Telegram llevando este tipo de conexión a cualquier arquitectura de micros.
En próximas notas estaremos viendo como hacer lo mismo con WhatsApp.
Descarga del código y bibliotecas usadas.

Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.