Tutorial ESP32 43/55 - Estación Meteorológica IoT Internet | Kit de Aprendizaje IoT ESP32 de SunFounder
En este tutorial, construiremos una estación meteorológica conectada a Internet utilizando el ESP32 y su placa de extensión de cámara de SunFounder. Este proyecto permite que el ESP32 recupere datos meteorológicos en tiempo real, incluyendo temperatura y humedad, y los muestre en una pantalla LCD. Esta aplicación no solo muestra las capacidades del ESP32, sino que también demuestra cómo obtener y analizar datos de una API externa.

A medida que avancemos a través del tutorial, conectaremos los componentes, configuraremos el código y nos aseguraremos de que todo funcione sin problemas. El resultado final será una estación meteorológica completamente funcional que actualiza sus lecturas cada 10 segundos, proporcionando una visualización clara y concisa de las condiciones climáticas actuales (en el video a las 00:30).
Hardware Explicado
Los componentes principales utilizados en este proyecto incluyen el microcontrolador ESP32, una pantalla LCD y el cableado necesario. El ESP32 está equipado con Wi-Fi y Bluetooth integrados, lo que le permite conectarse a Internet y recuperar datos. La pantalla LCD mostrará la información meteorológica actual, incluyendo la temperatura y la humedad.
La LCD que estamos usando es un display de 16x2 caracteres, lo que significa que puede mostrar dos líneas de 16 caracteres cada una. Esto será suficiente para nuestra salida de información meteorológica. El ESP32 se comunicará con la LCD a través de I2C, lo que simplifica el cableado al usar solo dos líneas de datos.
Detalles de la hoja de datos
| Fabricante | Espressif |
|---|---|
| Número de parte | ESP32-WROOM-32 |
| Voltaje de lógica/IO | 3.3 V |
| Voltaje de suministro | 3.0-3.6 V |
| Corriente de salida (por canal) | 12 mA máx |
| Corriente de pico (por canal) | 40 mA |
| Orientación sobre la frecuencia PWM | 1 kHz |
| Umbrales lógicos de entrada | 0.3 V (bajo), 0.7 V (alto) |
| Caída de tensión / RDS(on)/ saturación | 0.5 V |
| Límites térmicos | -40 a 85 °C |
| Paquete | QFN48 |
| Notas / variantes | Incluye múltiples variantes para diferentes aplicaciones |
- Asegúrese de que el ESP32 esté alimentado con una fuente estable de 3.3 V.
- Utiliza un terreno común para todos los componentes para evitar problemas de comunicación.
- Verifica la dirección I2C del LCD utilizando un escáner I2C.
- Monitorea el estado de la conexión Wi-Fi para evitar desconexiones durante la obtención de datos.
- Manejar errores de análisis de JSON para mejorar la robustez en la recuperación de datos.
Instrucciones de cableado

Para cablear los componentes, comienza conectando el LCD al ESP32. El LCD utilizará la interfaz I2C, así que conecta el pin SDA del LCD al GPIO21 en el ESP32 y el pin SCL al GPIO22. Asegúrate de conectar los pines de alimentación y tierra del LCD a los pines de 5V y GND en el ESP32, respectivamente.
A continuación, asegúrese de que el ESP32 esté alimentado correctamente utilizando la batería de litio incluida o una conexión USB. La batería proporciona portabilidad, mientras que la conexión USB es útil para programar y depurar. Finalmente, verifique que todas las conexiones estén seguras para evitar problemas de cableado suelto que puedan interrumpir la funcionalidad.
Ejemplos de código y guía paso a paso
En la fase de configuración de nuestro programa, inicializamos la comunicación serial y nos conectamos a la red Wi-Fi utilizando el SSID y la contraseña proporcionados. El siguiente fragmento de código maneja la conexión Wi-Fi:
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());Este código asegura que el ESP32 se conecte a la red Wi-Fi especificada antes de proceder con la obtención de datos. Si la conexión falla, intentará reconectarse continuamente.
A continuación, necesitamos enviar una solicitud HTTP GET para recuperar datos meteorológicos. Esto se logra utilizando el siguiente fragmento de código:
String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&units=metric" + "&APPID=" + openWeatherMapApiKey;
jsonBuffer = httpGETRequest(serverPath.c_str());Aquí, construimos la URL para la solicitud de la API, que incluye la ciudad, el código del país y nuestra clave de API.httpGETRequestse llama a la función para obtener los datos del clima.
Finalmente, analizamos la respuesta JSON y mostramos los datos relevantes en el LCD:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(time);
lcd.print(" ");
lcd.print(myObject["weather"][0]["main"]);
lcd.setCursor(0, 1);
lcd.print("T:");
lcd.print(myObject["main"]["temp"]);
lcd.print("\xDF"); // "°" char
lcd.print("C ");
lcd.print("H:");
lcd.print(myObject["main"]["humidity"]);
lcd.print("%");Este fragmento de código actualiza la pantalla LCD con la hora actual, las condiciones meteorológicas, la temperatura y la humedad. Limpia la pantalla anterior y coloca el cursor en las posiciones adecuadas para cada línea.
Demostración / Qué Esperar
Una vez que la cableado y la programación sean exitosos, su estación meteorológica se conectará al Wi-Fi y empezará a obtener datos meteorológicos cada 10 segundos. Verá la temperatura actual, la humedad y las condiciones meteorológicas mostradas en la pantalla LCD. Si el ESP32 no logra conectarse al Wi-Fi, imprimirá un mensaje de error en el monitor serial.
Ten en cuenta los límites de llamadas a la API para evitar ser bloqueado del servicio OpenWeatherMap. Si encuentras algún problema con la recuperación de datos, verifica tu clave API y asegúrate de que tu código de ciudad y país estén correctamente especificados (en el video a las 15:45).
Marcas de tiempo del video
- 00:00 Comenzar
- 2:00 introducción al proyecto
- 5:04 Cuenta de OpenWeather
- 6:11 Cableado
- 8:05 Código de Arduino explicado
- 14:13 JASON Elementos en código
- 20:23 Seleccionando la placa ESP32 y el puerto COM en Arduino IDE
- 22:05 Demostración de la estación meteorológica en LCD1602
- 23:45 Demostración de la estación meteorológica en LCD2004
/*
* Rui Santos
* Detalles completos del proyecto en https://RandomNerdTutorials.com/esp32-http-get-open-weather-map-thingspeak-arduino/
*
* Por la presente se otorga permiso, sin cargo alguno, a cualquier persona que obtenga una copia de este software y los archivos de documentación asociados.
*
* El aviso de copyright anterior y este aviso de permiso deberán incluirse en todas las copias o partes sustanciales del Software.
*/
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>
// Reemplace las siguientes variables con su combinación de SSID/Contraseña.
const char* ssid = "SSID";
const char* password = "PASSWORD";
// Tu nombre de dominio con la ruta de URL o dirección IP con la ruta
String openWeatherMapApiKey = "openWeatherMapApiKey";
// Reemplace con el código de su país y ciudad.
// Multa el código del país en https://openweathermap.org/find
String city = "CITY";
String countryCode = "COUNTRY CODE";
// EL TEMPORIZADOR POR DEFECTO ESTÁ CONFIGURADO EN 10 SEGUNDOS PARA PROPÓSITOS DE PRUEBA
// Para una aplicación final, verifica los límites de llamadas a la API por hora/minuto para evitar ser bloqueado/prohibido.
unsigned long lastTime = 0;
// Temporizador configurado para 10 minutos (600000)
// unsigned long timerDelay = 600000;
// Configura el temporizador a 10 segundos (10000)
unsigned long timerDelay = 10000;
String jsonBuffer;
// establecer el número de columnas y filas del LCD
int lcdColumns = 16;
int lcdRows = 2;
// establecer dirección LCD, número de columnas y filas
// SDA -> GPIO21, SCL -> GPIO22
// La dirección del LCD es 0x27, ejecuta un boceto del escáner I2C.
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
// Hora del servidor NTP
const char* ntpServer = "pool.ntp.org";
long gmtOffset_sec = 0;
int daylightOffset_sec = 0; // 3600;
void setup() {
Serial.begin(115200);
// WiFi
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 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.");
// iniciar LCD
lcd.init();
// activar la retroiluminación de la pantalla LCD
lcd.backlight();
}
void loop() {
// Enviar una solicitud GET HTTP
if ((millis() - lastTime) > timerDelay) {
// Verificar el estado de la conexión WiFi
if(WiFi.status()== WL_CONNECTED){
String serverPath = "http: // api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&units=metric" + "&APPID=" + openWeatherMapApiKey;
jsonBuffer = httpGETRequest(serverPath.c_str());
Serial.println(jsonBuffer);
JSONVar myObject = JSON.parse(jsonBuffer);
// 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("Objeto JSON = ");
// Serial.println(myObject);
// Serial.print("Temperatura: ");
// Serial.println(myObject["main"]["temp"]);
// Presión:
// Serial.println(myObject["main"]["presión"]);
// Serial.print("Humedad: ");
// Serial.println(myObject["main"]["humedad"]);
// Velocidad del viento:
// Serial.println(myObject["viento"]["velocidad"]);
// Obtener tiempo
gmtOffset_sec = myObject["timezone"];
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
// tiempo =
String time = printLocalTime();
// Impresión LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(time);
lcd.print(" ");
lcd.print(myObject["weather"][0]["main"]);
lcd.setCursor(0, 1);
lcd.print("T:");
lcd.print(myObject["main"]["temp"]);
lcd.print("\xDF"); // "carácter °"
lcd.print("C ");
lcd.print("H:");
lcd.print(myObject["main"]["humidity"]);
lcd.print("%");
}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
String printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return "null";
}
// Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
// obtener formato de hora HH:MM
char timeHour[3];
strftime(timeHour,3, "%H", &timeinfo);
char timeMinute[3];
strftime(timeMinute,3, "%M", &timeinfo);
String time = String(timeHour) + ":" + String(timeMinute);
Serial.println(time)
; return time;
}
String httpGETRequest(const char* serverName) {
WiFiClient client;
HTTPClient http;
// Tu nombre de dominio con la ruta de URL o dirección IP con la ruta
http.begin(client, serverName);
// Enviar solicitud HTTP POST
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);
}
// Recursos gratuitos
http.end();
return payload;
}
Common Course Links
Common Course Files
Recursos y referencias
-
Documentación
Archivos📁
No hay archivos disponibles.