Esta guía muestra cómo configurar una comunicación HTTP entre dos placas ESP32 para intercambiar datos vía Wi-Fi sin conexión a internet (sin router). En palabras simples, vas a aprender cómo enviar datos de una placa a otra usando peticiones HTTP. Las placas ESP32 se programarán con Arduino IDE.
Con fines de demostración, enviaremos lecturas del sensor BME280 de una placa a la otra. El receptor mostrará las lecturas en una pantalla OLED. Esta técnica es especialmente útil cuando no hay router disponible o cuando quieres un enlace directo y fiable entre dos dispositivos sin depender de infraestructura externa.
Resumen del proyecto
Una placa ESP32 actuará como servidor y la otra placa ESP32 actuará como cliente. El flujo de funcionamiento es el siguiente:
El servidor ESP32 crea su propia red inalámbrica (ESP32 Soft-Access Point). Así, otros dispositivos Wi-Fi pueden conectarse a esa red (SSID: ESP32-Access-Point, contraseña: 123456789). El cliente ESP32 se configura como estación, por lo que puede conectarse a la red inalámbrica del servidor ESP32. El cliente puede hacer peticiones HTTP GET al servidor para solicitar datos del sensor o cualquier otra información. Solo necesita usar la dirección IP del servidor para hacer una petición en una ruta determinada: /temperature, /humidity o /pressure. El servidor escucha las peticiones entrantes y envía una respuesta apropiada con las lecturas. El cliente recibe las lecturas y las muestra en la pantalla OLED.
Como ejemplo, el cliente ESP32 solicita temperatura, humedad y presión al servidor haciendo peticiones en la dirección IP del servidor seguidas de /temperature, /humidity y /pressure, respectivamente. El servidor ESP32 escucha en esas rutas y, cuando se hace una petición, envía las lecturas correspondientes del sensor vía respuesta HTTP.
Componentes necesarios
Para este tutorial necesitas: dos placas de desarrollo ESP32, un sensor BME280, una pantalla OLED I2C SSD1306, cables jumper y una protoboard.
Instalar las librerías necesarias
Para este tutorial necesitas instalar varias librerías:
Librerías del servidor web asíncrono
Usaremos las siguientes librerías para manejar las peticiones HTTP: la librería ESPAsyncWebServer de ESP32Async y la librería AsyncTCP de ESP32Async.
Puedes instalar esas librerías en el Gestor de Librerías de Arduino IDE. Ve a Programa > Incluir Librería > Gestionar Librerías y busca los nombres de las librerías.
Librerías del BME280
Las siguientes librerías se pueden instalar a través del Gestor de Librerías de Arduino: la librería Adafruit_BME280 y la librería Adafruit Unified Sensor.
Librerías del OLED I2C SSD1306
Para interactuar con la pantalla OLED necesitas las siguientes librerías, que se pueden instalar a través del Gestor de Librerías de Arduino: la librería Adafruit SSD1306 y la librería Adafruit GFX.
Parte 1: Servidor ESP32 (Access Point)
El servidor ESP32 es un Access Point (AP) que escucha peticiones en las URLs /temperature, /humidity y /pressure. Cuando recibe peticiones en esas URLs, envía las últimas lecturas del sensor BME280.
Con fines de demostración, usamos un sensor BME280, pero puedes usar cualquier otro sensor modificando unas pocas líneas de código.
Esquema de conexión
Conecta el ESP32 al sensor BME280 de la siguiente forma: VIN/VCC del sensor a 3,3 V, GND a GND, SCL del sensor al GPIO 22 y SDA del sensor al GPIO 21.
Sketch de Arduino para el Servidor ESP32
Sube el siguiente código a tu placa:
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Detalles completos del proyecto en https://RandomNerdTutorials.com/esp32-client-server-wi-fi/
*/
// Importa las librerías requeridas
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// Establece las credenciales de tu red de punto de acceso
const char* ssid = "ESP32-Access-Point";
const char* password = "123456789";
Adafruit_BME280 bme; // I2C
// Crea el objeto AsyncWebServer en el puerto 80
AsyncWebServer server(80);
String readTemp() {
return String(bme.readTemperature());
//return String(1.8 * bme.readTemperature() + 32);
}
String readHumi() {
return String(bme.readHumidity());
}
String readPres() {
return String(bme.readPressure() / 100.0F);
}
void setup(){
// Puerto serie para depuración
Serial.begin(115200);
Serial.println();
// Configura el ESP como punto de acceso
Serial.print("Setting AP (Access Point)…");
// Elimina el parámetro password si quieres que el AP sea abierto
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", readTemp().c_str());
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", readHumi().c_str());
});
server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", readPres().c_str());
});
bool status;
// configuración por defecto
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
// Inicia el servidor
server.begin();
}
void loop(){
}
Cómo funciona el código paso a paso
Se empieza incluyendo las librerías necesarias. Se incluye la librería WiFi.h y la librería ESPAsyncWebServer.h para manejar peticiones HTTP entrantes. Se incluyen las librerías para interactuar con el sensor BME280.
En las siguientes variables, se definen las credenciales de tu red de punto de acceso. Establecemos el SSID a ESP32-Access-Point, pero puedes darle cualquier otro nombre. También puedes cambiar la contraseña. Por defecto, está establecida a 123456789.
Se crea una instancia para el sensor BME280 llamada bme. Se crea un servidor web asíncrono en el puerto 80. Después, se crean tres funciones que devuelven la temperatura, la humedad y la presión como variables String.
En el setup(), se inicializa el Monitor Serie para propósitos de demostración. Se establece tu ESP32 como punto de acceso con el nombre SSID y la contraseña definidos antes. Después, se manejan las rutas donde el ESP32 escuchará las peticiones entrantes.
Por ejemplo, cuando el servidor ESP32 recibe una petición en la URL /temperature, envía la temperatura devuelta por la función readTemp() como char (por eso usamos el método c_str()). Lo mismo ocurre cuando el ESP32 recibe una petición en las URLs /humidity y /pressure.
Después, se inicializa el sensor BME280. Finalmente, se inicia el servidor.
Como es un servidor web asíncrono, no hay nada en el loop(). Este es uno de los patrones más potentes del ESP32: la librería asíncrona maneja todas las peticiones en segundo plano, liberando el loop() para otras tareas. Esto significa que puedes hacer más cosas mientras el servidor atiende peticiones, algo impensable con el servidor síncrono tradicional.
Probar el servidor ESP32
Sube el código a tu placa y abre el Monitor Serie. Deberías obtener algo como el mensaje de que el punto de acceso se configuró con éxito. Eso significa que el punto de acceso se estableció correctamente.
Ahora, para asegurarte de que está escuchando peticiones de temperatura, humedad y presión, necesitas conectarte a su red. En tu smartphone, ve a los ajustes de Wi-Fi y conéctate a ESP32-Access-Point. La contraseña es 123456789.
Estando conectado al punto de acceso, abre tu navegador y escribe 192.168.4.1/temperature. Deberías obtener el valor de temperatura en tu navegador. Prueba esta ruta de URL para la humedad: 192.168.4.1/humidity. Finalmente, ve a la URL de presión: 192.168.4.1/pressure.
Si estás obteniendo lecturas válidas, significa que todo está funcionando correctamente. Ahora, necesitas preparar la otra placa ESP32 (cliente) para hacer esas peticiones por ti y mostrarlas en la pantalla OLED.
Parte 2: Cliente ESP32 (Station)
El cliente ESP32 es una estación Wi-Fi que está conectada al servidor ESP32. El cliente solicita la temperatura, humedad y presión al servidor haciendo peticiones HTTP GET en las rutas /temperature, /humidity y /pressure. Después, muestra las lecturas en una pantalla OLED.
Esquema de conexión
Conecta el ESP32 a la pantalla OLED de la siguiente forma: VIN/VCC de la pantalla a VIN del ESP32 (o 3,3 V), GND a GND, SCL al GPIO 22 y SDA al GPIO 21.
Sketch de Arduino para el Cliente ESP32
Sube el siguiente código al otro ESP32:
/*
Rui Santos
Detalles completos del proyecto en https://RandomNerdTutorials.com/esp32-client-server-wi-fi/
*/
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "ESP32-Access-Point";
const char* password = "123456789";
// Tu dirección IP o nombre de dominio con la ruta URL
const char* serverNameTemp = "http://192.168.4.1/temperature";
const char* serverNameHumi = "http://192.168.4.1/humidity";
const char* serverNamePres = "http://192.168.4.1/pressure";
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // Ancho de la pantalla OLED, en píxeles
#define SCREEN_HEIGHT 64 // Alto de la pantalla OLED, en píxeles
// Declaración para una pantalla SSD1306 conectada a I2C (pines SDA, SCL)
#define OLED_RESET 4 // Pin de reset # (o -1 si comparte el pin de reset del Arduino)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
String temperature;
String humidity;
String pressure;
unsigned long previousMillis = 0;
const long interval = 5000;
void setup() {
Serial.begin(115200);
// Dirección 0x3C para 128x64, puede que necesites cambiar este valor (usa un escáner I2C)
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // No continuar, bucle infinito
}
display.clearDisplay();
display.setTextColor(WHITE);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
}
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis >= interval) {
// Comprueba el estado de la conexión WiFi
if(WiFi.status()== WL_CONNECTED ){
temperature = httpGETRequest(serverNameTemp);
humidity = httpGETRequest(serverNameHumi);
pressure = httpGETRequest(serverNamePres);
Serial.println("Temperature: " + temperature + " *C - Humidity: " + humidity + " % - Pressure: " + pressure + " hPa");
display.clearDisplay();
// muestra la temperatura
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("T: ");
display.print(temperature);
display.print(" ");
display.setTextSize(1);
display.cp437(true);
display.write(248);
display.setTextSize(2);
display.print("C");
// muestra la humedad
display.setTextSize(2);
display.setCursor(0, 25);
display.print("H: ");
display.print(humidity);
display.print(" %");
// muestra la presión
display.setTextSize(2);
display.setCursor(0, 50);
display.print("P:");
display.print(pressure);
display.setTextSize(1);
display.setCursor(110, 56);
display.print("hPa");
display.display();
// guarda la última petición HTTP GET
previousMillis = currentMillis;
}
else {
Serial.println("WiFi Disconnected");
}
}
}
String httpGETRequest(const char* serverName) {
WiFiClient client;
HTTPClient http;
// Tu nombre de dominio con ruta URL o dirección IP con ruta
http.begin(client, serverName);
// Envía la petición HTTP GET
int httpResponseCode = http.GET();
String payload = "--";
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Libera recursos
http.end();
return payload;
}
Cómo funciona el código paso a paso
Se incluyen las librerías necesarias para la conexión Wi-Fi y para hacer peticiones HTTP. Después, inserta las credenciales de red del servidor ESP32. Si has cambiado las credenciales de red por defecto en el servidor ESP32, deberías cambiarlas aquí para que coincidan.
Después, guarda las URLs donde el cliente hará las peticiones HTTP. El servidor ESP32 tiene la dirección IP 192.168.4.1, y haremos peticiones en las URLs /temperature, /humidity y /pressure. Después, se incluyen las librerías para interactuar con la pantalla OLED. Se establece el tamaño de la pantalla OLED (128 x 64 píxeles). Se crea un objeto display con el tamaño definido y con protocolo de comunicación I2C.
Se inicializan las variables String que almacenarán las lecturas de temperatura, humedad y presión recuperadas del servidor. Se establece el intervalo de tiempo entre cada petición. Por defecto, está establecido a 5 segundos, pero puedes cambiarlo.
En el setup(), se inicializa la pantalla OLED. Después, se conecta el cliente ESP32 a la red del servidor ESP32.
Nota: si tu pantalla OLED no funciona, comprueba su dirección I2C usando un sketch de escáner I2C y cambia el código en consecuencia.
En el loop() es donde hacemos las peticiones HTTP GET. Hemos creado una función llamada httpGETRequest() que acepta como argumento la ruta URL donde queremos hacer la petición y devuelve la respuesta como un String. Puedes usar esta función en tus proyectos para simplificar tu código.
Usamos esa función para obtener las lecturas de temperatura, humedad y presión del servidor, imprimimos esas lecturas en el Monitor Serie para depuración, y después mostramos las lecturas en la pantalla OLED.
Usamos timers en lugar de delays para hacer una petición cada X segundos. Por eso tenemos las variables previousMillis, currentMillis y usamos la función millis(). Esta técnica es fundamental para no bloquear el microcontrolador mientras espera la siguiente lectura.
Probar el cliente ESP32
Teniendo ambas placas relativamente cerca y encendidas, verás que el ESP32 #2 está recibiendo nuevas lecturas de temperatura, humedad y presión cada 5 segundos del ESP32 #1. Verás las lecturas en el Monitor Serie del cliente y también en la pantalla OLED.
¡Eso es todo! Tus dos placas están hablando entre sí. Una comunicación establecida directamente entre dos ESP32 sin router, sin internet, sin infraestructura externa.
Conclusión: lo que has aprendido
En este tutorial has aprendido cómo enviar datos de un ESP32 a otra placa ESP32 vía Wi-Fi usando peticiones HTTP sin necesidad de conectarte a internet. Con fines de demostración, hemos mostrado cómo enviar lecturas del sensor BME280, pero puedes usar cualquier otro sensor o enviar cualquier otro dato.
Esta técnica es extremadamente útil cuando quieres comunicar dos dispositivos ESP32 de forma fiable en lugares sin cobertura Wi-Fi, o cuando quieres evitar depender de un router para tu proyecto. Combinada con otras técnicas como ESP-NOW, tienes un arsenal completo de protocolos de comunicación inalámbrica directa para tus proyectos IoT.
El patrón Access Point + Station + HTTP es uno de los más portables y flexibles en el mundo ESP32. Cualquier smartphone, tablet u ordenador puede conectarse al servidor para ver los datos, y cualquier otro ESP32 puede actuar como cliente para recoger y reenviar la información. Es la base de sistemas de monitorización distribuida, redes de sensores y proyectos de domótica autónomos.
Descubre más desde CIBERED
Suscríbete y recibe las últimas entradas en tu correo electrónico.
