Una cámara de frío que se corta a las tres de la mañana no avisa. El producto se echa a perder en silencio y te enteras al día siguiente, cuando ya no hay nada que hacer. Lo mismo pasa en una bodega rural, en un invernadero, en una sala de servidores chica o en un camión: son justamente los lugares donde no llega el WiFi de la casa ni hay una red a la cual conectarse.

Este proyecto resuelve esa situación con un ESP32 que sale a internet por la red celular, un sensor infrarrojo que mide temperatura sin tocar nada y una app que abres desde cualquier parte. Al terminar vas a tener un termómetro remoto funcionando, vas a entender por qué un sensor sin contacto necesita que le declares la emisividad del material que estás midiendo, y vas a poder accionar un relé. para cortar o encender un equipo. desde el teléfono, estés donde estés.

Por qué 4G y no WiFi

El ESP32 trae WiFi integrado, así que agregar un módem celular parece un rodeo caro. Lo es, hasta que el punto de medición queda fuera del alcance de cualquier router. Un módulo SIM7600G le da al proyecto una ruta propia a internet: le pones una SIM con datos y el equipo queda autónomo, sin depender de la red del lugar ni de la clave WiFi de otra persona.

La otra ventaja es la cobertura hacia atrás. El SIM7600G habla 4G LTE, pero si en el sector no hay LTE cae a 3G o 2G y sigue reportando. Para un punto de medición en zona rural esa degradación ordenada vale más que la velocidad: no necesitas ancho de banda, necesitas que el dato llegue.

Módulo SIM7600G 4G LTE conectado a un ESP32 mediante cables en protoboard

El costo de esa autonomía es el cableado. El módem, el sensor, el relé y la alimentación se acumulan rápido sobre la protoboard, y ahí aparece el riesgo real de este proyecto: un cable suelto que toca donde no debe puede quemar el módulo más caro del montaje. Si vas a repetir el circuito más de una vez, vale la pena pasarlo a una placa o al menos fijar el módem con headers en vez de dejarlo colgando de jumpers.

Cómo mide temperatura un sensor que no toca nada

El MLX90614 no es un termómetro común. Adentro tiene una termopila: una serie de termocuplas diminutas que generan un voltaje proporcional a la radiación infrarroja que les llega. Todo cuerpo por encima del cero absoluto emite infrarrojo, y la cantidad que emite depende de su temperatura. El sensor lee esa radiación, la compara con la temperatura de su propio encapsulado. por eso entrega dos valores, ambiente y objeto. y despeja la temperatura de lo que está mirando.

De ahí sale la particularidad que el código maneja en una sola línea y que conviene entender antes de confiar en la medición:

C++
sensor.setEmissivityCorrectionCoefficient(0.91);

La emisividad es qué tan eficientemente un material irradia calor, en una escala de 0 a 1. La piel humana, la pintura mate, el plástico y la madera están alrededor de 0,95. El metal pulido, en cambio, puede estar en 0,1: irradia poquísimo y refleja el infrarrojo de todo lo que tiene alrededor. Si apuntas el sensor a una superficie de acero inoxidable sin corregir la emisividad, la lectura va a estar muchos grados abajo de la temperatura real, y el sensor no está fallando. El valor de 0,91 del código es un promedio razonable para superficies opacas comunes; si vas a medir siempre el mismo material, ajústalo.

El segundo detalle es el campo de visión. El sensor no mide un punto, mide un cono. Lo que entrega es el promedio de todo lo que entra en ese cono, así que mientras más lejos lo pongas, más área está promediando. Para medir el interior de un refrigerador, acércalo a la zona que te importa: a 20 cm de distancia ya estás midiendo un círculo bastante más grande que el objeto que creías estar apuntando, con las paredes incluidas en el promedio.

Hardware y conexiones

El montaje son cuatro bloques: el ESP32 que coordina, el sensor que mide, el módem que comunica y el relé que actúa.

Diagrama de conexión del proyecto con ESP32, módulo SIM7600G, sensor MLX90614 y relé

El MLX90614 se comunica por I2C, así que son cuatro cables: VCC al pin de 3,3 V del ESP32. no a 5 V. , GND a GND, SDA al GPIO 21 y SCL al GPIO 22. Esos dos últimos son los pines I2C por defecto del ESP32, y la mayoría de los módulos MLX90614 que se venden ya traen las resistencias de pull up en la placa.

El SIM7600G se conecta por puerto serie, y acá está el error clásico: las señales van cruzadas. El TX del módem va al pin que el ESP32 usa como RX (GPIO 4), y el RX del módem va al pin que el ESP32 usa como TX (GPIO 2). Si conectas TX con TX no hay humo ni daño, simplemente no pasa nada, y es lo primero que hay que revisar cuando el módem no responde. Además necesitan una tierra común: el GND del módem tiene que estar unido al GND del ESP32 aunque cada uno reciba su alimentación por separado.

El módulo de relés va al GPIO 13 y a los 5 V. Con un módulo de cuatro canales puedes manejar cuatro cargas independientes; el código de más abajo ya deja los cuatro definidos.

La alimentación es el punto crítico

Placa de desarrollo ESP32 junto a una fuente de alimentación de 5 V y 3 A

Este es el punto donde más proyectos con módem celular fracasan, y casi nunca se diagnostica bien. El SIM7600G consume poco en reposo, pero cada vez que transmite genera pulsos de corriente que pueden superar los 2 A durante unos pocos milisegundos. Si la fuente no los entrega, el voltaje cae por un instante, el módem se reinicia y el sistema entra en un ciclo de conexiones que se caen solas. El síntoma engaña: parece un problema de señal o de APN, y es la fuente.

Por eso el proyecto pide una fuente regulada de 5 V y al menos 3 A, y por eso el módem no debe alimentarse desde el puerto USB del computador ni desde el pin de 5 V del ESP32. Dos precauciones que ayudan:

  • Alimenta el módem directo desde la fuente, con su propio par de cables cortos y del grosor adecuado. Un cable largo y delgado tiene resistencia suficiente para provocar la caída de voltaje por sí solo.
  • Pon un condensador electrolítico de 1000 µF entre VCC y GND lo más cerca posible del módem. Funciona como reserva local de energía para los pulsos de transmisión y es la solución más barata a un problema que, sin él, parece intermitente y aleatorio.

Configurar el dashboard en Blynk

Blynk es el puente entre el ESP32 y tu teléfono: la nube que recibe los datos y la app que los muestra. La configuración se hace primero en el navegador y después en el celular.

En la consola web creas una plantilla nueva. Le pones nombre, eliges ESP32 como tipo de hardware y. acá está la única diferencia respecto de cualquier proyecto Blynk con WiFi. seleccionas GSM como tipo de conexión. Ese cambio es el que hace que la librería espere un módem en vez de una red inalámbrica.

Creación de una plantilla nueva en la consola web de Blynk seleccionando ESP32 como hardware

Después vienen los datastreams, que son los canales de datos entre la placa y la nube. Necesitas cinco: uno para la temperatura y cuatro para los relés, cada uno asociado a un pin virtual.

Pantalla de creación de un datastream nuevo en Blynk con la opción de pin virtual

El de temperatura va en el pin virtual V0 y es de tipo decimal; los cuatro relés ocupan V1, V2, V3 y V4 como valores enteros. La correspondencia entre esos números y el código tiene que ser exacta: si en la consola declaras el gauge en V0 y en el código escribes Blynk.virtualWrite(V1, temp), el dato se envía pero ningún widget lo muestra.

Lista con los cinco datastreams configurados en Blynk para el proyecto

Con los datastreams listos, armas el dashboard. Un widget Gauge para la temperatura, enlazado a V0 desde su ícono de configuración, y cuatro Switch para los relés, cada uno apuntando a su pin virtual.

Agregando un widget de tipo switch al dashboard de Blynk para controlar un relé

Lo último es crear el dispositivo a partir de la plantilla. Blynk genera tres credenciales. template ID, nombre de plantilla y token de autenticación. que son las tres primeras líneas del programa.

Selección de la plantilla del proyecto al crear un dispositivo nuevo en Blynk

Ese token identifica a tu dispositivo ante la nube: cualquiera que lo tenga puede leer tus datos y accionar tus relés. Trátalo como una contraseña y no lo publiques en un repositorio ni en un foro cuando pidas ayuda.

El programa

Antes de compilar necesitas el soporte de placas ESP32 en el IDE de Arduino y tres librerías: la de Blynk. que se instala como paquete completo desde Sketch → Include Library → Manage Libraries. , TinyGSM para el módem y DFRobot_MLX90614 para el sensor.

Instalación del paquete de librerías de Blynk desde el gestor de librerías del IDE de Arduino

El programa completo está más abajo. La lógica es corta: setup() inicializa el sensor, configura los pines de los relés y levanta la conexión GPRS; loop() solo mantiene vivos el cliente Blynk y el temporizador. Todo lo demás son funciones que reaccionan a eventos. BLYNK_WRITE(V1) hasta BLYNK_WRITE(V4) se ejecutan cuando presionas un switch en la app y escriben el estado en el relé correspondiente. sensor_reading() corre periódicamente, lee el sensor y publica el valor en V0.

Antes de cargarlo tienes que cambiar tres cosas: las credenciales de Blynk, el APN de tu operador y. si el sensor no lee bien. el coeficiente de emisividad.

C++
#define BLYNK_TEMPLATE_ID "TU_TEMPLATE_ID"
#define BLYNK_TEMPLATE_NAME "TU_TEMPLATE_NAME"
#define BLYNK_AUTH_TOKEN "TU_AUTH_TOKEN"

#include <HardwareSerial.h>
#include <DFRobot_MLX90614.h>
#define TINY_GSM_MODEM_SIM7600
#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>
#define rxPin 4 //connect the RX pin of the sim7600 with pin 2 and TX with pin 4
#define txPin 2
HardwareSerial SerialAT(1);
DFRobot_MLX90614_I2C sensor;   // instantiate an object to drive our sensor

#if !defined(TINY_GSM_RX_BUFFER)
#define TINY_GSM_RX_BUFFER 650
#endif
#define TINY_GSM_YIELD() { delay(2); }
const char apn[]  = "ufone.pinternet"; // Change this to your Provider details
const char gprsUser[] = "";
const char gprsPass[] = "";
unsigned long timeout;
BlynkTimer timer;
int Relay1 = 12;
int Relay2 = 13;
int Relay3 = 14;
int Relay4 = 27;

// WiFi Status
int WiFi_Led = 5;
float ambientTemp;
float objectTemp;
float temp;
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);

void setup() {
 
  Serial.begin(9600,SERIAL_8N1); 
      SerialAT.begin(115200,SERIAL_8N1,rxPin, txPin, false);
// initialize the sensor
  while( NO_ERR != sensor.begin() ){
    Serial.println("Communication with device failed, please check connection");
    delay(3000);
  }
  Serial.println("Begin ok!");

 pinMode(Relay1,OUTPUT);
 pinMode(Relay2,OUTPUT);
 pinMode(Relay3,OUTPUT);
 pinMode(Relay4,OUTPUT);
 pinMode(WiFi_Led, OUTPUT);
 Blynk.begin(BLYNK_AUTH_TOKEN, modem, apn, gprsUser, gprsPass);

    // Configure and start the watchdog timer
//  esp_task_wdt_init(10, true); // 10 seconds timeout
//  esp_task_wdt_add(NULL);      // Attach to the current task 
sensor.enterSleepMode();
  delay(50);
  sensor.enterSleepMode(false);
  delay(200);

sensor.setEmissivityCorrectionCoefficient(0.91);
ambientTemp = sensor.getAmbientTempCelsius();
objectTemp = sensor.getObjectTempCelsius();
 
  timer.setInterval(1000L, sensor_reading); // call the function every 5 seconds

  
}

void loop() {
   Blynk.run();
  timer.run();
 // esp_task_wdt_reset();
}








   BLYNK_WRITE(V1) // From Blynk to the ESP32, to control a Relay
{
  int pinValue1 = param.asInt();
  digitalWrite(Relay1 , pinValue1);
  
  }
     BLYNK_WRITE(V2) // From Blynk to the ESP32, to control a Relay
{
  int pinValue2 = param.asInt();
  digitalWrite(Relay2 , pinValue2);
  
  }
     BLYNK_WRITE(V3) // From Blynk to the ESP32, to control a Relay
{
  int pinValue3 = param.asInt();
  digitalWrite(Relay3 , pinValue3);
  
  }
     BLYNK_WRITE(V4) // From Blynk to the ESP32, to control a Relay
{
  int pinValue4 = param.asInt();
  digitalWrite(Relay4 , pinValue4);
  
  }
   void sensor_reading()
  {
ambientTemp = sensor.getAmbientTempCelsius();  
temp = sensor.getObjectTempCelsius();
Blynk.virtualWrite(V0,   temp ); // Gauge
 
  }

Tres detalles del código que conviene revisar

El programa funciona tal como está, pero tiene tres puntos que en la práctica dan problemas y que vale la pena conocer antes de que te pasen:

El GPIO 12 es un pin especial. El código asigna Relay1 al GPIO 12, que en el ESP32 es un pin de arranque (strapping pin): su estado al encender define el voltaje de la memoria flash. Si el módulo de relés lo mantiene en alto en el momento del arranque, la placa puede no partir. Si te pasa que el ESP32 arranca suelto pero no con el relé conectado, cambia ese canal a otro GPIO libre. el 25, 26 o 27 funcionan sin condiciones. y el problema desaparece.

El comentario del temporizador no coincide con el valor. La línea dice que llama a la función cada 5 segundos, pero el valor es 1000L, es decir una vez por segundo. Para monitoreo de temperatura, una lectura por segundo es innecesaria y consume datos móviles sin aportar nada. Súbelo a 30000L o 60000L según cuánto te importe la resolución temporal: un refrigerador no cambia de temperatura en un segundo, y tu plan de datos lo va a agradecer.

Los nombres rxPin y txPin están definidos desde el punto de vista del ESP32. rxPin es 4 porque es el pin por donde el ESP32 recibe, y ahí va el TX del módem. El comentario de esa misma línea dice lo contrario y confunde a mucha gente. Si el módem no responde, invierte los dos cables antes de suponer que el módulo está malo.

Puesta en marcha y depuración

Con todo cargado, alimenta el proyecto y abre el monitor serie a 9600 baudios. La secuencia normal es: el sensor responde, el módem registra en la red y Blynk conecta. Entre encender y ver el primer dato en la app pasan entre 20 y 60 segundos, la mayor parte del tiempo en el registro celular.

Aplicación Blynk en un teléfono mostrando el proyecto creado

Si algo no arranca, los tres bloques fallan de manera distinta:

  • Se repite "Communication with device failed" en el monitor serie. Es el sensor. Revisa que esté alimentado con 3,3 V y no con 5 V, y que SDA y SCL no estén invertidos. Si tienes dudas, un sketch de escaneo I2C debería encontrarlo en la dirección 0x5A.
  • El módem no registra en la red. Confirma que la SIM tenga datos activos y que no pida PIN: el código no lo desbloquea, así que una SIM con PIN nunca va a conectar. Prueba la SIM en un teléfono primero. También revisa la antena: sin ella conectada, el módem puede registrar en un lugar con buena señal y fallar en cuanto lo muevas.
  • Registra en la red pero Blynk no conecta. Casi siempre es el APN. El código trae el de un operador de Pakistán y hay que reemplazarlo por el que corresponda.

Sobre el APN en Chile: varía según operador y según el tipo de plan, y los planes de datos M2M o IoT no usan el mismo que un plan de celular común. La forma confiable de obtenerlo es consultarlo con tu operador, o poner la SIM en un teléfono y leer la configuración en Ajustes → Redes móviles → APN. Como referencia, los valores que se ven habitualmente son imovil.entelpcs.cl en Entel, bam.movistar.cl en Movistar, internet.wom.cl en WOM y bam.clarochile.cl en Claro, pero confírmalo antes de dar por sentado que el problema es otro. Si tu plan no requiere usuario ni contraseña, las dos variables siguientes quedan como están, vacías.

Seguridad con 220 V

Si vas a usar el relé para cortar un equipo conectado a la red eléctrica, esta parte no es opcional.

Nunca toques los contactos del relé ni el cableado de carga con el proyecto energizado. Desconecta desde el enchufe antes de cualquier ajuste, no desde el interruptor del equipo. Mantén el cableado de 220 V físicamente separado de la electrónica de baja tensión y, si el módulo de relés lo permite, usa borneras cerradas en vez de dejar terminales expuestos. Todo el conjunto debe ir dentro de una caja aislante: un montaje con 220 V sobre una protoboard al aire, sobre el escritorio, es un accidente esperando su turno.

Una regla práctica: si la carga que quieres controlar es un equipo de refrigeración o algo que supere el consumo doméstico corriente, no la manejes directo con el relé del módulo. Usa ese relé para accionar un contactor dimensionado para la carga, que es lo que corresponde para equipos con motor y su corriente de partida.

Variantes y mejoras

El montaje tal cual es un termómetro que reporta y un relé que obedece. Estas tres extensiones lo convierten en algo bastante más útil:

Alarma automática por umbral. Blynk permite enviar notificaciones al teléfono desde el código. Comparando temp contra un valor límite dentro de sensor_reading() puedes disparar un aviso cuando la cámara de frío supere los 8 °C, sin depender de que alguien esté mirando la app. Combinado con el relé, el mismo umbral puede cortar o encender un equipo de forma autónoma; agrega una banda de histéresis de un par de grados para que no conmute sin parar cuando la temperatura oscile alrededor del límite.

Registro local para cuando se cae la red. El punto débil de todo sistema que reporta a la nube es que, sin señal, el dato se pierde. Con un módulo lector de microSD por SPI puedes guardar cada lectura con su hora en un archivo CSV y conservar el histórico completo aunque el módem esté desconectado. Es la diferencia entre saber que hubo una falla y poder demostrar cuánto duró.

Varios puntos de medición. El MLX90614 tiene una dirección I2C fija, así que para medir en dos lugares distintos con el mismo ESP32 conviene un multiplexor I2C TCA9548A, o bien cambiar a sensores de contacto DS18B20, que van todos en un mismo bus de un solo cable y cada uno trae su identificador único de fábrica. Para medir el aire dentro de un refrigerador, un DS18B20 sumergible es incluso más apropiado que el infrarrojo: mide donde lo pones y no depende ni de la emisividad ni de la distancia.

Personalización para Chile

Los componentes del proyecto se consiguen en el catálogo de MechatronicStore, con algunas equivalencias respecto de lo que usa el tutorial original:

  • Placa ESP32 DevKit. es el mismo controlador del proyecto. Cualquier variante DevKit con los GPIO 21 y 22 accesibles sirve.
  • Sensor infrarrojo MLX90614. el componente central, sin reemplazo posible: es el único que mide sin contacto.
  • Módulo relé 4 canales. cumple exactamente el rol del módulo del original. Si solo vas a controlar una carga, uno de un canal basta y el código igual funciona.
  • Fuente 5V 3A switching. la pieza que no conviene achicar, por lo explicado en la sección de alimentación.
  • Protoboard 830 puntos y jumpers macho hembra 20cm. para el montaje de prueba.

Dos cosas del proyecto no salen del catálogo de electrónica y hay que resolverlas aparte: el módulo SIM7600G 4G LTE con su antena, que es el componente más caro del montaje y suele conseguirse por importación, y la SIM con plan de datos, que en Chile puedes tomar como plan prepago o, mejor, como plan M2M pensado para equipos. consumen poquísimo y no requieren renovar saldo a mano.

Sobre el consumo de datos: con una lectura por minuto, este proyecto mueve del orden de unos pocos MB al mes. El plan de datos más básico sobra, y ahí es donde el ajuste del temporizador que mencionamos antes deja de ser un detalle.

Recursos

Versión chilena con componentes en stock local en MechatronicStore.