Sensor afuera, display adentro: sin pasar cables
Hay un escenario clásico en domótica casera: quieres medir la temperatura del patio o de la pieza de servicio, pero quieres ver la lectura en una pantalla cómoda dentro del living. Conectar todo con cables implica pasar por paredes, perforar marcos y resignarte a un cable colgado. La alternativa moderna es ESP-NOW, un protocolo punto a punto de Espressif que conecta dos ESP32 sin pasar por un router WiFi, con latencias por debajo de 5 ms y un consumo bajísimo.
En este tutorial vamos a montar un termómetro inalámbrico de dos piezas: un transmisor con un sensor DS18B20 (waterproof, ideal para exterior) y un receptor con pantalla que muestra la temperatura. Vas a comparar dos arquitecturas, ESP-NOW directo y vía servidor HTTP local, y a entender cuál te conviene según tu caso de uso real.

El tutorial original es de Engr. Shahzada Fahad (Electronic Clinic) y usa un receptor con pantalla e-Paper Makerfabs de 4.2 pulgadas tricolor manejado por un ESP32-S3. Acá replicamos la misma lógica inalámbrica y, para el receptor, proponemos una alternativa accesible en Chile.
ESP-NOW vs HTTP/TCP: ¿cuándo elegir cuál?
| Aspecto | ESP-NOW | HTTP (WiFi tradicional) |
|---|---|---|
| Latencia | menos de 5 ms | 30 a 200 ms |
| Consumo TX | ~30 mA pico | ~120 mA pico |
| Alcance | 30 a 50 m (igual que WiFi) | depende del router |
| ¿Necesita router? | No | Sí |
| ¿Funciona en corte de luz? | Sí (si los nodos tienen batería) | No (cae con el router) |
| Integración con apps móviles | Difícil | Trivial |
| Encriptación | Sí (PMK + LMK opcional) | TLS si la implementas |
Conclusión rápida: ESP-NOW gana en autonomía, latencia y resiliencia. HTTP/TCP gana si necesitas que la lectura esté disponible para otros dispositivos (Home Assistant, app móvil, dashboard remoto). Por eso vamos a implementar ambas, y al final eliges según tu uso.
Hardware del transmisor (sensor exterior)
- ESP32 DevKit (cualquier WROOM-32 sirve)
- Sensor DS18B20 waterproof (sonda metálica encapsulada, soporta de menos 55 °C a más 125 °C)
- Resistencia 4.7 kΩ (pull-up del bus 1-Wire, sin esto el sensor no responde)
- Cables y opcionalmente fuente de alimentación 5V o batería
Cableado del DS18B20:
| DS18B20 | ESP32 |
|---|---|
| Rojo (VCC) | 3.3 V |
| Negro (GND) | GND |
| Amarillo/Blanco (DATA) | GPIO 4 + pull-up 4.7 kΩ a 3.3 V |

Por qué la pull-up es innegociable: el protocolo 1-Wire del DS18B20 usa una sola línea para datos. Cuando ni el maestro ni el sensor están manejando la línea, queda flotante. La resistencia a VCC asegura que esté en alto por defecto, y cualquier dispositivo puede tirarla a tierra para comunicar. Sin pull-up, el sensor lee 85.0 °C de forma constante (valor por defecto del registro de temperatura al encender) o devuelve -127.0. El valor estándar del datasheet es 4.7 kΩ; el diagrama de referencia usa una resistencia parecida en el mismo punto.
Hardware del receptor
El tutorial original usa una pantalla e-Paper Makerfabs de 4.2 pulgadas con ESP32-S3. En Chile no se vende ese display específico, así que vamos a implementar el receptor con un OLED SSD1306 + ESP32. Para la lectura de temperatura ambiente típica (de menos 10 °C a 40 °C) un OLED es perfectamente legible.
- ESP32 DevKit (puede ser el mismo modelo que el transmisor)
- Pantalla OLED 128x32 I2C SSD1306 (alternativa al e-Paper de 4.2 pulgadas)
Cableado del OLED:
| OLED | ESP32 |
|---|---|
| VCC | 3.3 V |
| GND | GND |
| SDA | GPIO 21 |
| SCL | GPIO 22 |
Versión 1: ESP-NOW directo
Paso 1: obtener la MAC del receptor
Antes de programar el transmisor necesitas saber a quién enviarle. Carga este sketch al receptor, abre el monitor serial, y anota la MAC que imprime:
#include <WiFi.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
Serial.print("MAC: ");
Serial.println(WiFi.macAddress());
}
void loop() {}

Paso 2: transmisor ESP-NOW
Reemplaza la MAC 0x3C, 0x84, 0x27, 0xC0, 0xE8, 0xBC por la tuya:
#include <WiFi.h>
#include <esp_now.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const int oneWireBus = 4;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
uint8_t receiverMAC[] = {0x3C, 0x84, 0x27, 0xC0, 0xE8, 0xBC};
typedef struct struct_message {
float temperature;
} struct_message;
struct_message dataToSend;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "OK" : "FAIL");
}
void setup() {
Serial.begin(115200);
sensors.begin();
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) { ESP.restart(); }
esp_now_register_send_cb(OnDataSent);
esp_now_peer_info_t peerInfo = {};
memcpy(peerInfo.peer_addr, receiverMAC, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
esp_now_add_peer(&peerInfo);
}
void loop() {
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0);
dataToSend.temperature = tempC;
esp_now_send(receiverMAC, (uint8_t *)&dataToSend, sizeof(dataToSend));
delay(5000); // cada 5 segundos
}
Paso 3: receptor ESP-NOW + OLED
#include <WiFi.h>
#include <esp_now.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
typedef struct struct_message {
float temperature;
} struct_message;
struct_message incomingData;
float latestTemp = -100.0;
void onReceive(const uint8_t *mac, const uint8_t *data, int len) {
memcpy(&incomingData, data, sizeof(incomingData));
latestTemp = incomingData.temperature;
}
void showTemp(float t) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 8);
if (t < -50) display.print("--.- C");
else { display.print(t, 1); display.print(" C"); }
display.display();
}
void setup() {
Serial.begin(115200);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
showTemp(-100);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
if (esp_now_init() != ESP_OK) return;
esp_now_register_recv_cb(onReceive);
}
void loop() {
static unsigned long last = 0;
if (millis() - last > 1000) {
showTemp(latestTemp);
last = millis();
}
}
Versión 2: HTTP/TCP por WiFi local
Si quieres que otros dispositivos (Home Assistant, una app móvil, un script Python) también lean la temperatura, conviene usar HTTP. El transmisor abre conexión al receptor y le manda el valor como texto plano (puedes evolucionar a JSON cuando agregues más sensores).
Transmisor
#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const int oneWireBus = 4;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
const char* WIFI_SSID = "TuRedWiFi";
const char* WIFI_PASS = "TuContrasena";
const char* HOST = "192.168.1.50"; // IP del receptor
const int PORT = 80;
void setup() {
Serial.begin(115200);
sensors.begin();
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
}
void loop() {
sensors.requestTemperatures();
float t = sensors.getTempCByIndex(0);
WiFiClient client;
if (client.connect(HOST, PORT)) {
client.println(String(t));
}
client.stop();
delay(5000);
}
Receptor
El receptor levanta un WiFiServer en el puerto 80, acepta conexiones, lee la línea recibida y actualiza la pantalla. La idea es la misma que en ESP-NOW pero usando TCP en lugar de paquetes ESP-NOW directos.
Pruebas: calienta el sensor y mira la pantalla
Con ambos programas cargados, la forma más rápida de validar el sistema es forzar un cambio de temperatura. En el tutorial original se acerca la llama de un fósforo a la sonda del DS18B20: la lectura sube de inmediato y, tras el siguiente refresco, la pantalla del receptor muestra el nuevo valor.

A los pocos segundos el receptor refresca y muestra la temperatura actualizada, nítida y legible desde cualquier ángulo.

Por qué refrescamos solo cada cierto tiempo
Tanto el OLED como las pantallas e-Paper tienen un costo no trivial en cada refresco:
- OLED SSD1306: cada
display.display()envía 1 KB por I2C a 400 kHz, unos 25 ms. Si lo haces a 100 Hz, saturas el bus. - e-Paper: cada refresco toma de 2 a 3 segundos completos y desgasta el panel (vida útil típica: cerca de 1 millón de refrescos). Por eso el código original solo refresca cada 2 minutos.
Si usas OLED puedes refrescar cada segundo sin problema. Si usas e-Paper, mantén el intervalo de 2 a 3 minutos. La gran ventaja del e-ink es que, una vez impreso el valor, la imagen se queda en pantalla incluso con la alimentación cortada, ideal para sensores con batería que duran meses.
Variantes y mejoras
Extensiones útiles que no están en el tutorial original:
- Multisensor con un solo receptor: el bus 1-Wire del DS18B20 soporta varios sensores en paralelo. Conecta 3 o 4 DS18B20 al mismo pin del transmisor, mándalos como arreglo por ESP-NOW, y muestra todos en el receptor. Útil para monitorear distintas piezas con un solo nodo transmisor.
- Modo deep sleep para batería de 6+ meses: entre transmisiones, pon el ESP32 en
esp_deep_sleep_start(). Con un despertar cada 5 minutos y una 18650 de 3000 mAh, llegas tranquilamente a 6 meses de autonomía. - Encriptación PMK + LMK en ESP-NOW: por defecto ESP-NOW va en claro. Si te preocupa que un vecino con un ESP32 cercano pueda capturar tus paquetes, agrega
esp_now_set_pmk()con una clave de 16 bytes compartida entre los dos nodos. AES 128 por defecto.
Personalización para Chile
Componentes en MechatronicStore con stock local:
- ESP32 con WiFi y Bluetooth ESP-WROOM-32 Tipo C (SKU X2-10V2): $7.990 CLP (necesitas 2: uno para el transmisor, uno para el receptor).
- Sensor de Temperatura DS18B20 tipo termocupla (SKU G-232): $2.990 CLP (es exactamente el waterproof del tutorial original).
- Pantalla OLED 128x32 I2C 0.91" SSD1306 (SKU D-112): $3.990 CLP (el tutorial original usa una pantalla e-Paper Makerfabs 4.2 pulgadas tricolor que no se vende en Chile. El OLED muestra perfectamente la temperatura ambiente y es mucho más barato, aunque sin el efecto papel del e-ink).
- Resistencia 4.7 kΩ (SKU GK2-15): $100 CLP (es el valor estándar de pull-up del bus 1-Wire del DS18B20; en la página del producto eliges el valor 4.7 kΩ).
- Protoboard 830 puntos MB102 (SKU C-302): $3.790 CLP (necesitas 2).
- Cables macho macho 30cm (SKU C-417): $2.990 CLP.
Total proyecto (2 nodos completos): aproximadamente $32.000 CLP.
Nota sobre el display e-Paper del original: si te interesa el efecto papel y la persistencia sin consumo, podemos pedir el módulo Waveshare equivalente bajo demanda. Pregunta en MechatronicStore.
Recursos
- Tutorial original (inglés): Build a Wireless ESP32 E-Ink Temperature Display with ESP-NOW por Engr. Shahzada Fahad (Electronic Clinic)
- Documentación oficial ESP-NOW (Espressif): https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html
- Librería OneWire para Arduino: https://github.com/PaulStoffregen/OneWire
- Librería DallasTemperature (DS18B20): https://github.com/milesburton/Arduino-Temperature-Control-Library
- Adafruit SSD1306: https://github.com/adafruit/Adafruit_SSD1306
Versión chilena basada en el tutorial de Electronic Clinic, con componentes en stock local en MechatronicStore.










