En esta guía vas a aprender cómo hacer peticiones HTTP GET y HTTP POST con la placa ESP32 usando Arduino IDE. Cubriremos ejemplos sobre cómo obtener valores, enviar objetos JSON, peticiones URL encoded y mucho más.
Métodos de petición HTTP: GET vs POST
El Hypertext Transfer Protocol (HTTP) funciona como un protocolo de petición-respuesta entre un cliente y un servidor. Aquí tienes un ejemplo típico:
El ESP32 (cliente) envía una petición HTTP a una Raspberry Pi ejecutando Node-RED (servidor). El servidor devuelve una respuesta al ESP32 (cliente). Finalmente, la respuesta contiene información de estado sobre la petición y también puede contener el contenido solicitado.
HTTP GET
GET se usa para solicitar datos de un recurso específico. Se usa a menudo para obtener valores de APIs. Por ejemplo, puedes tener: GET /update-sensor?temperature=value1. Fíjate en que la cadena de consulta (nombre = temperature y valor = value1) se envía en la URL de la petición HTTP GET. O puedes usar una petición simple para devolver un valor u objeto JSON: GET /get-sensor.
Importante: con HTTP GET, los datos son visibles para cualquiera en la URL de la petición.
HTTP POST
POST se usa para enviar datos a un servidor para crear o actualizar un recurso. Por ejemplo, publicar lecturas de sensores a un servidor. Los datos enviados al servidor con POST se almacenan en el cuerpo de la petición HTTP:
POST /update-sensor HTTP/1.1
Host: example.com
api_key=api&sensor_name=name&temperature=value1&humidity=value2&pressure=value3
Content-Type: application/x-www-form-urlencoded
En el cuerpo de la petición, también puedes enviar un objeto JSON:
POST /update-sensor HTTP/1.1
Host: example.com
{api_key: "api", sensor_name: "name", temperature: value1, humidity: value2, pressure: value3}
Content-Type: application/json
Importante: con HTTP POST, los datos no son visibles en la URL de la petición. Sin embargo, si no está cifrado, siguen siendo visibles en el cuerpo de la petición.
HTTP GET/POST con el ESP32
En esta guía, exploraremos los siguientes escenarios: HTTP GET con valor o consulta en la URL, HTTP GET con objeto JSON o texto plano y HTTP POST con URL encoded, objeto JSON o texto plano.
Requisitos previos
Antes de proceder con este tutorial, asegúrate de completar los siguientes requisitos previos.
Arduino IDE
Vamos a programar el ESP32 usando Arduino IDE, así que asegúrate de tener el complemento ESP32 instalado.
Librería Arduino_JSON
También necesitas instalar la librería Arduino_JSON. Puedes instalarla en el Gestor de Librerías de Arduino IDE. Ve a Programa > Incluir Librería > Gestionar Librerías y busca el nombre de la librería.
Componentes necesarios
Para este tutorial necesitas: un ESP32, una placa Raspberry Pi, una tarjeta microSD de 16 GB Clase 10, una fuente de alimentación para Raspberry Pi (5V 2.5A), cables jumper y una protoboard.
Preparar Node-RED (opcional)
Como ejemplo, crearemos un servicio web con una Raspberry Pi y Node-RED para actuar como servicio web (como una API). Básicamente, harás peticiones HTTP GET y HTTP POST a tu Raspberry Pi para obtener valores o actualizarlos. Puedes usar cualquier otro servicio web.
Si no tienes Node-RED instalado, sigue los tutoriales correspondientes de instalación. Una vez que tengas Node-RED ejecutándose en tu Raspberry Pi, ve a la dirección IP de tu Raspberry Pi seguida de :1880:
http://raspberry-pi-ip-address:1880
La interfaz de Node-RED debería abrirse. Puedes simplemente importar el flujo final: ve a Menu > Import y copia el flujo proporcionado en tu portapapeles para crear tu flujo de Node-RED.
Otros servicios web o APIs
En esta guía, el ESP32 hace peticiones HTTP a Node-RED, pero puedes usar estos ejemplos con otros servicios como ThingSpeak, IFTTT.com (servicio WebHooks), OpenWeatherMap.org, servidor PHP, etc. Todos los ejemplos presentados en esta guía también funcionarán con otras APIs.
En resumen, para hacer esta guía compatible con cualquier servicio, necesitas buscar la documentación de la API del servicio. Después, necesitas el nombre del servidor (URL o dirección IP) y los parámetros a enviar en la petición (ruta URL o cuerpo de la petición). Finalmente, modifica nuestros ejemplos para integrarte con cualquier API que quieras usar.
1. HTTP GET en el ESP32: valor o consulta en la URL
En el primer ejemplo, el ESP32 hará una petición HTTP GET para actualizar una lectura en un servicio. Este tipo de petición también podría usarse para filtrar un valor, solicitar un valor o devolver un objeto JSON.
Código HTTP GET con Arduino IDE
Después de instalar los complementos de placa y librerías necesarios, copia el siguiente código en tu Arduino IDE, pero no lo subas todavía. Necesitas hacer algunos cambios para que funcione en tu caso.
/*
Rui Santos
Detalles completos del proyecto en https://RandomNerdTutorials.com/esp32-http-get-post-arduino/
*/
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Tu nombre de dominio con ruta URL o dirección IP con ruta
String serverName = "http://192.168.1.106:1880/update-sensor";
// Las siguientes variables son unsigned long porque el tiempo, medido en
// milisegundos, se convertirá rápidamente en un número mayor de lo que puede almacenar un int.
unsigned long lastTime = 0;
// Temporizador establecido a 10 minutos (600000)
//unsigned long timerDelay = 600000;
// Temporizador establecido a 5 segundos (5000)
unsigned long timerDelay = 5000;
void setup() {
Serial.begin(115200);
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());
Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}
void loop() {
// Envía una petición HTTP POST cada 10 minutos
if ((millis() - lastTime) > timerDelay) {
// Comprueba el estado de la conexión WiFi
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
String serverPath = serverName + "?temperature=24.37";
// Tu nombre de dominio con ruta URL o dirección IP con ruta
http.begin(serverPath.c_str());
// Si necesitas autenticación de Node-RED/servidor, inserta usuario y contraseña a continuación
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
// Envía la petición HTTP GET
int httpResponseCode = http.GET();
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String payload = http.getString();
Serial.println(payload);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Libera recursos
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
Configurar las credenciales de red
Modifica las siguientes líneas con las credenciales de tu red: SSID y contraseña. El código está bien comentado indicando dónde debes hacer los cambios:
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Configurar tu serverName
También necesitas escribir tu nombre de dominio o la dirección IP de Node-RED, para que el ESP32 publique las lecturas en tu propio servidor:
String serverName = "http://192.168.1.106:1880/update-sensor";
Ahora, sube el código a tu placa y debería funcionar inmediatamente.
La petición HTTP GET
En el loop() es donde realmente haces la petición HTTP GET cada 5 segundos con datos de ejemplo:
String serverPath = serverName + "?temperature=24.37";
http.begin(serverPath.c_str());
int httpResponseCode = http.GET();
Nota: si Node-RED requiere autenticación, descomenta la siguiente línea e inserta el usuario y la contraseña de Node-RED:
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
El ESP32 hace una nueva petición a la siguiente URL para actualizar el campo sensor con una nueva temperatura: http://192.168.1.106:1880/update-sensor?temperature=24.37.
Después, las siguientes líneas de código guardan la respuesta HTTP del servidor:
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String payload = http.getString();
Serial.println(payload);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
Demostración
Con tu placa ejecutando el nuevo sketch, abre la ventana de depuración de Node-RED. Verás que los valores de ejemplo se están imprimiendo con éxito (24.37).
2. HTTP GET en el ESP32: objeto JSON o texto plano
Este siguiente ejemplo muestra cómo hacer una petición HTTP GET para obtener un objeto JSON y decodificarlo con el ESP32. Muchas APIs devuelven datos en formato JSON.
Copia el siguiente sketch en tu Arduino IDE (escribe tu SSID y contraseña):
/*
Rui Santos
Detalles completos del proyecto en https://RandomNerdTutorials.com/esp32-http-get-post-arduino/
*/
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Tu nombre de dominio con ruta URL o dirección IP con ruta
const char* serverName = "http://192.168.1.106:1880/get-sensor";
unsigned long lastTime = 0;
// Temporizador establecido a 10 minutos (600000)
//unsigned long timerDelay = 600000;
// Temporizador establecido a 5 segundos (5000)
unsigned long timerDelay = 5000;
String sensorReadings;
float sensorReadingsArr[3];
void setup() {
Serial.begin(115200);
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());
Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
if(WiFi.status()== WL_CONNECTED){
sensorReadings = httpGETRequest(serverName);
Serial.println(sensorReadings);
JSONVar myObject = JSON.parse(sensorReadings);
// JSON.typeof(jsonVar) se puede usar para obtener el tipo de la variable
if (JSON.typeof(myObject) == "undefined") {
Serial.println("Parsing input failed!");
return;
}
Serial.print("JSON object = ");
Serial.println(myObject);
// myObject.keys() se puede usar para obtener un array de todas las claves del objeto
JSONVar keys = myObject.keys();
for (int i = 0; i < keys.length(); i++) {
JSONVar value = myObject[keys[i]];
Serial.print(keys[i]);
Serial.print(" = ");
Serial.println(value);
sensorReadingsArr[i] = double(value);
}
Serial.print("1 = ");
Serial.println(sensorReadingsArr[0]);
Serial.print("2 = ");
Serial.println(sensorReadingsArr[1]);
Serial.print("3 = ");
Serial.println(sensorReadingsArr[2]);
}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
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);
// Si necesitas autenticación de Node-RED/servidor, inserta usuario y contraseña a continuación
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
// 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;
}
Configurar tu serverName
Introduce tu nombre de dominio o la dirección IP de Node-RED, para que el ESP32 solicite las lecturas de los sensores que se recuperarán en un objeto JSON:
String serverName = "http://192.168.1.106:1880/get-sensor";
Ahora, sube el código a tu placa.
La petición HTTP GET (objeto JSON)
En el loop(), llama a la función httpGETRequest() para hacer la petición HTTP GET:
sensorReadings = httpGETRequest(serverName);
La función httpGETRequest() hace una petición a la dirección de Node-RED http://192.168.1.106:1880/get-sensor y recupera una cadena con un objeto JSON.
Nota: si Node-RED requiere autenticación, descomenta la línea correspondiente e inserta el usuario y la contraseña de Node-RED.
Decodificar el objeto JSON
Para obtener acceso a los valores, decodifica el objeto JSON y almacena todos los valores en el array sensorReadingsArr:
JSONVar myObject = JSON.parse(sensorReadings);
if (JSON.typeof(myObject) == "undefined") {
Serial.println("Parsing input failed!");
return;
}
JSONVar keys = myObject.keys();
for (int i = 0; i < keys.length(); i++) {
JSONVar value = myObject[keys[i]];
Serial.print(keys[i]);
Serial.print(" = ");
Serial.println(value);
sensorReadingsArr[i] = double(value);
}
Demostración
Después de subir el código, abre el Arduino IDE y verás que está recibiendo los siguientes datos JSON: {"value1":24.25,"value2":49.54,"value3":1005.14}. Después, imprime el objeto JSON decodificado en el Monitor Serie de Arduino IDE. Con fines de depuración, la información solicitada también se imprime en la ventana de depuración de Node-RED.
3. HTTP POST en el ESP32: URL encoded, JSON y texto plano
Finalmente, vas a aprender cómo hacer una petición HTTP POST con un ESP32.
Con este ejemplo, tu ESP32 puede hacer peticiones HTTP POST usando tres tipos diferentes de cuerpo de petición: URL encoded, objeto JSON o texto plano. Estos son los métodos más comunes y deberían integrarse con la mayoría de APIs o servicios web.
Copia el siguiente sketch en tu Arduino IDE (escribe tu SSID y contraseña):
/*
Rui Santos
Detalles completos del proyecto en https://RandomNerdTutorials.com/esp32-http-get-post-arduino/
*/
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Tu nombre de dominio con ruta URL o dirección IP con ruta
const char* serverName = "http://192.168.1.106:1880/update-sensor";
unsigned long lastTime = 0;
// Temporizador establecido a 10 minutos (600000)
//unsigned long timerDelay = 600000;
// Temporizador establecido a 5 segundos (5000)
unsigned long timerDelay = 5000;
void setup() {
Serial.begin(115200);
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());
Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
if(WiFi.status()== WL_CONNECTED){
WiFiClient client;
HTTPClient http;
// Tu nombre de dominio con ruta URL o dirección IP con ruta
http.begin(client, serverName);
// Si necesitas autenticación de Node-RED/servidor, inserta usuario y contraseña a continuación
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
// Especifica el header content-type
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Datos a enviar con HTTP POST
String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&value1=24.25&value2=49.54&value3=1005.14";
// Envía la petición HTTP POST
int httpResponseCode = http.POST(httpRequestData);
// Si necesitas una petición HTTP con content type: application/json, usa lo siguiente:
//http.addHeader("Content-Type", "application/json");
//int httpResponseCode = http.POST("{\"api_key\":\"tPmAT5Ab3j7F9\",\"sensor\":\"BME280\",\"value1\":\"24.25\",\"value2\":\"49.54\",\"value3\":\"1005.14\"}");
// Si necesitas una petición HTTP con content type: text/plain
//http.addHeader("Content-Type", "text/plain");
//int httpResponseCode = http.POST("Hello, World!");
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
// Libera recursos
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
Configurar tu serverName
Introduce tu nombre de dominio o la dirección IP de Node-RED, para que el ESP32 publique lecturas de sensores de ejemplo:
String serverName = "http://192.168.1.106:1880/update-sensor";
Ahora, sube el código a tu placa.
HTTP POST URL Encoded
Para hacer una petición HTTP POST de tipo URL encoded como esta:
POST /update-sensor HTTP/1.1
Host: 192.168.1.106:1880
api_key=tPmAT5Ab3j7F9&sensor=BME280&value1=24.25&value2=49.54&value3=1005.14
Content-Type: application/x-www-form-urlencoded
Necesitas ejecutar lo siguiente en tu código Arduino:
http.begin(serverName);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&value1=24.25&value2=49.54&value3=1005.14";
int httpResponseCode = http.POST(httpRequestData);
HTTP POST JSON Object
O si prefieres hacer una petición HTTP POST con un objeto JSON:
POST /update-sensor HTTP/1.1
Host: example.com
{api_key: "tPmAT5Ab3j7F9", sensor_name: "BME280", temperature: 24.25; humidity: 49.54; pressure: 1005.14}
Content-Type: application/json
Usa el siguiente fragmento:
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.POST("{\"api_key\":\"tPmAT5Ab3j7F9\",\"sensor\":\"BME280\",\"value1\":\"24.25\",\"value2\":\"49.54\",\"value3\":\"1005.14\"}");
HTTP POST texto plano
Si quieres enviar texto plano o un valor, usa lo siguiente:
http.addHeader("Content-Type", "text/plain");
int httpResponseCode = http.POST("Hello, World!");
Nota: el flujo de Node-RED que estamos usando (servicio web) no está configurado para recibir texto plano, pero si la API que planeas integrar solo acepta texto plano o un valor, puedes usar el fragmento anterior.
Demostración
En la ventana de depuración de Node-RED, puedes ver que tu ESP32 está haciendo una petición HTTP POST cada 5 segundos. Y en este ejemplo, esos valores también se envían a 3 Gauges y se muestran en el Dashboard de Node-RED: http://raspberry-pi-ip-address:1880/ui.
Conclusión: lo que has aprendido
En este tutorial has aprendido cómo integrar tu ESP32 con servicios online usando peticiones HTTP GET y HTTP POST.
HTTP GET y HTTP POST se usan comúnmente en la mayoría de servicios web y APIs. Estos pueden ser útiles en tus proyectos para: publicar tus lecturas de sensores a un servicio web como IFTTT, ThingSpeak; a un servidor web ESP32 o Raspberry Pi o a tu propio servidor; solicitar datos de internet o de tu base de datos, y mucho más.
Dominar HTTP GET y POST es fundamental para cualquier proyecto IoT serio. Prácticamente todos los servicios cloud modernos exponen sus funcionalidades a través de APIs REST que usan estos métodos. Con estas dos herramientas en tu arsenal, puedes conectar tu ESP32 a prácticamente cualquier servicio de internet: desde enviar datos a Google Sheets hasta consultar el clima de OpenWeatherMap, pasando por integrarte con plataformas de domótica como Home Assistant o con bases de datos como Firebase o MySQL.
El ESP32 se convierte así en un verdadero ciudadano de internet, capaz de hablar con cualquier servidor del mundo.
Descubre más desde CIBERED
Suscríbete y recibe las últimas entradas en tu correo electrónico.
