Hacer petición HTTP con ESP8266

En este post sobre la tarjeta NodeMCU ESP8266 te mostraré cómo hacer una petición HTTP a un servidor web. Esto servirá para, por ejemplo, enviar datos de un sensor a un servidor web propio.

En este ejemplo te voy a mostrar cómo enviar datos desde una ESP8266 a un servidor Apache con PHP, pues es de las pilas de desarrollo más usadas, pero recuerda que podrías hacer esto con cualquier lenguaje por ejemplo usando Python y Flask o Go, etcétera.

Veamos entonces cómo comunicar la tarjeta con nuestro servidor, pues la misma ya tiene conexión WiFi así que podemos conectarla fácilmente.  Vamos a hacer que nuestra ESP8266 sea un cliente HTTP, pues anteriormente ya vimos cómo hacer que sea un servidor.

Preparando el código del servidor

Como lo dije, vamos a usar PHP y Apache así que debes configurar tu entorno ya sea en Windows o Linux.

Lo que haremos será recibir los valores que nos va a enviar la tarjeta. El primer ejemplo es con GET:

<?php
$value = $_GET["value"];
$another_value = $_GET["another_value"];

# Prepare the data
$date = date("Y-m-d H:i:s");
$data = sprintf("On %s the value is %s and another_value is %s\n", $date, $value, $another_value);
# Save it
file_put_contents("data.txt", $data, FILE_APPEND);

# And we need to answer the client. We just tell the date ;)
echo $date;

Como puedes ver, estamos recibiendo los valores por GET y guardándolos en un archivo con la función file_put_contents. Además, estamos respondiendo con la fecha y hora actual.

En este caso tú podrías guardar los valores en una base de datos o responder al cliente NodeMCU ESP8266 con otros valores ya sea sacados de una base de datos o de un archivo.

También existe otro ejemplo en donde se usa JSON y se hace una petición POST desde la tarjeta. Para ello el código queda así:

<?php
$data = json_decode(file_get_contents("php://input"));
# Prepare the data
$date = date("Y-m-d H:i:s");
$value = $data->value;
$another_value = $data->another_value;
$data = sprintf("On %s the data is %s and another_value is %s\n", $date, $value, $another_value);
# Save it
file_put_contents("data_post.txt", $data, FILE_APPEND);

# And we need to answer the client. We just tell the date ;)
echo $date;

De este modo nuestro servidor queda preparado. Por cierto, es importante que conozcas la IP de tu computadora dentro de tu red local en caso de que no subas tu proyecto a internet. También es necesario que tengas una red WiFi pues a ella se conectará la tarjeta.

En mi caso mi IP es 192.168.1.77 y he montado el proyecto en la carpeta llamada esp8266_api.

Librerías necesarias

En este caso necesitamos la librería WifiManager de tzapu y también la librería ESP8266HTTPClient de Markus Sattler que ya viene preinstalada.

Hacer petición GET con ESP8266

Cliente HTTP con ESP8266 – Petición GET a PHP

Veamos cómo hacer una petición GET. En este caso vamos a usar el Serial para depurar, pero en la práctica puede que quieras deshabilitarlo y eliminar todas las llamadas al mismo.

Iniciamos el Serial y también el WiFi. Luego iniciamos un cliente HTTP e invocamos al método GET. Fíjate en la URL pues a través de ella estamos enviando los valores:

/*
  ____          _____               _ _           _       
 |  _ \        |  __ \             (_) |         | |      
 | |_) |_   _  | |__) |_ _ _ __ _____| |__  _   _| |_ ___ 
 |  _ <| | | | |  ___/ _` | '__|_  / | '_ \| | | | __/ _ \
 | |_) | |_| | | |  | (_| | |   / /| | |_) | |_| | ||  __/
 |____/ \__, | |_|   \__,_|_|  /___|_|_.__/ \__, |\__\___|
         __/ |                               __/ |        
        |___/                               |___/         
    
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me               /
 ------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
Creado por Parzibyte (https://parzibyte.me).
------------------------------------------------------------------------------------------------
Si el código es útil para ti, puedes agradecerme siguiéndome: https://parzibyte.me/blog/sigueme/
Y compartiendo mi blog con tus amigos
También tengo canal de YouTube: https://www.youtube.com/channel/UCroP4BTWjfM0CkGB6AFUoBg?sub_confirmation=1
------------------------------------------------------------------------------------------------
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

// Credentials to connect to the wifi network
const char *ssid = "YOUR_SSID";
const char *password = "YOUR_PASSWORD";
/*
The ip or server address. If you are on localhost, put your computer's IP (for example http://192.168.1.65)
If the server is online, put the server's domain for example https://parzibyte.me
*/
const String SERVER_ADDRESS = "http://192.168.1.77/esp8266_api";
void setup()
{
  Serial.begin(9600); // Initialize serial communications with the PC. Just for debug
  while (!Serial)
    ;

  // Connect to wifi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.println("Connecting...");
  }
  Serial.println("Connected!");
}

void loop()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("Wifi is unavailable");
    return;
  }
  // Make request each 5 seconds

  HTTPClient http;
  

  // This value can come from a sensor
  String value = "Hello+from+ESP8266!";
  String another_value = "This+is+another+value";
  String full_url = SERVER_ADDRESS + "/save_data.php?value=" + value + "&another_value=" + another_value;
  http.begin(full_url);

  // Make request
  Serial.println("Making request to " + full_url);
  int httpCode = http.GET();
  if (httpCode > 0)
  {
    if (httpCode == HTTP_CODE_OK)
    {

      String payload = http.getString(); //Get the request response payload
      Serial.println("Request is OK! The server says: ");
      Serial.println(payload);
    }
    else
    {
      Serial.println("Error: httpCode was " + http.errorToString(httpCode));
    }
  }
  else
  {
    Serial.println("Request failed: " + http.errorToString(httpCode));
  }

  http.end(); //Close connection
  // And wait 5 seconds
  delay(5000);
}

La petición está en la línea 75, y la declaración de los valores está en la línea 68. Además, si la petición es correcta imprimimos lo que el servidor haya respondido en la línea 83.

Esto es importante de mencionar porque si por ejemplo quieres realizar cierta acción en la tarjeta (encender un LED, imprimir en una LCD, etcétera) puedes comparar esta respuesta del payload para realizar determinada acción.

Petición HTTP POST con ESP8266

Ahora veamos cómo hacer una petición POST. En este caso enviaremos un JSON codificado, pero lo vamos a codificar a mano. Yo te recomiendo que si los datos no son sensibles, los envíes por GET.

De igual modo estoy seguro de que ya debe haber una librería para codificar a JSON en C++ específicamente para esta tarjeta, pero para ahorrar cosas vamos a codificar “a mano”.

El código completo queda como se ve a continuación, lo único que cambia es que ya no enviamos los valores en la URL y que invocamos a http.post pasándole los valores JSON, en lugar de http.get.

/*
  ____          _____               _ _           _       
 |  _ \        |  __ \             (_) |         | |      
 | |_) |_   _  | |__) |_ _ _ __ _____| |__  _   _| |_ ___ 
 |  _ <| | | | |  ___/ _` | '__|_  / | '_ \| | | | __/ _ \
 | |_) | |_| | | |  | (_| | |   / /| | |_) | |_| | ||  __/
 |____/ \__, | |_|   \__,_|_|  /___|_|_.__/ \__, |\__\___|
         __/ |                               __/ |        
        |___/                               |___/         
    
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me               /
 ------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
Creado por Parzibyte (https://parzibyte.me).
------------------------------------------------------------------------------------------------
Si el código es útil para ti, puedes agradecerme siguiéndome: https://parzibyte.me/blog/sigueme/
Y compartiendo mi blog con tus amigos
También tengo canal de YouTube: https://www.youtube.com/channel/UCroP4BTWjfM0CkGB6AFUoBg?sub_confirmation=1
------------------------------------------------------------------------------------------------
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

// Credentials to connect to the wifi network
const char *ssid = "YOUR_SSID";
const char *password = "YOUR_PASSWORD";
/*
The ip or server address. If you are on localhost, put your computer's IP (for example http://192.168.1.65)
If the server is online, put the server's domain for example https://parzibyte.me
*/
const String SERVER_ADDRESS = "http://192.168.1.77/esp8266_api";
void setup()
{
  Serial.begin(9600); // Initialize serial communications with the PC. Just for debug
  while (!Serial)
    ;

  // Connect to wifi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.println("Connecting...");
  }
  Serial.println("Connected!");
}

void loop()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("Wifi is unavailable");
    return;
  }
  // Make request each 5 seconds

  HTTPClient http;
  WiFiClient client;

  // This value can come from a sensor
  String value = "Hello. This is a post request";
  String another_value = "Hello world! :)";
  String full_url = SERVER_ADDRESS + "/save_data_post.php";
  http.begin(client, full_url);

  // Make request
  Serial.println("Making request to " + full_url);
  // We send the data in JSON format. Something like:
  /*
  {"value":"some_value","another_value":"another_value"}
  */
  int httpCode = http.POST(
      "{\"value\":\"" + value + "\"" +
      ",\"another_value\":\"" +
      another_value + "\"" +
      "}");
  if (httpCode > 0)
  {
    if (httpCode == HTTP_CODE_OK)
    {

      String payload = http.getString(); //Get the request response payload
      Serial.println("Request is OK! The server says: ");
      Serial.println(payload);
    }
    else
    {
      Serial.println("Error: httpCode was " + http.errorToString(httpCode));
    }
  }
  else
  {
    Serial.println("Request failed: " + http.errorToString(httpCode));
  }

  http.end(); //Close connection
  // And wait 5 seconds
  delay(5000);
}

El envío de datos está en la línea 79; como lo dije, puede que sea un poco complejo de entender pero es para evitar incluir librerías de codificación a JSON.

Al hacer la petición vemos que igualmente se están guardando los datos, solo que ahora no necesitamos codificarlos para una URL.

Recuerda que con JSON podemos codificar más que una simple cadena, podemos enviar un arreglo, un objeto dentro de un objeto, números, etcétera.

Poniendo todo junto

El código completo lo dejaré en GitHub. Recuerda que el del servidor lo debes colocar en htdocs o en /var/www/public_html dependiendo de tu sistema operativo e instalación.

Más adelante traeré otros ejemplos de esta tarjeta, mientras tanto te dejo más sobre programación en ESP8266, Electrónica y PHP.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

3 comentarios en “Hacer petición HTTP con ESP8266”

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *