Proyecto de reloj IOT que muestra hora y fecha, temperatura, humedad ambiente y estado del tiempo exterior en la ciudad elegida. Se ha usado un ESP32 C3 Supermini y un display GMT020-02-7P 240X320 con chipset ST7789. El código siguiente está realizado con Arduino IDE ver. 2.3.6
Conexion de pines:
TFT.........................ESP32 C3
CS .............................7
DC ............................20
RST ..........................21
SDA .........................9
SCL .........................4
VCC........................3V.
GND .......................GND
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <SPI.h>
#include "time.h"
// ESP32 C3 SUPERMINI y TFT 2.0 TFTSPI GMT020-02-7P
#define TFT_CS 7
#define TFT_RST 21
#define TFT_DC 20
//#define TFT_MOSI 6 // SDA, HW MOSI
//#define TFT_SCLK 4 // SCL, HW SCLK
//#define TFT_MISO 5 // not used
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
const char* ssid = "SSID WIFI"; //"LowiCD10"
const char* password = "PASSWORD WIFI"; //"2P3WHFC259TK3B"
const String apiKey = "APIKEY OPENWEATHERMAP"; // Tu clave de OpenWeatherMap
//const String ciudad_fija = "Granada,ES"; // Puedes fijarla o usar la detectada
const String ciudad_fija = "TU CIUDAD";
const char* ntpServer = "hora.roa.es"; //NPT HORA ESPAÑA
const long gmtOffset_sec = 3600; // Ajusta según tu país
const int daylightOffset_sec = 0; // 3600 si hay horario de verano
// Variables de datos
float temp = 0;
float veloc = 0;
int hum = 0;
String climaDesc = "...";
String site = "...";
String country = "..";
unsigned long ultimaActualizacionClima = 0;
const long intervaloClima = 600000; // Actualizar cada 10 minutos (600,000 ms)
int secuencia = 1;
unsigned long ultimaActualizacionInfo = 0;
const long intervaloInfo = 10000; // Actualizar info 10 segundos
void obtenerClima() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
// URL para obtener clima por ciudad
String url = "https://api.openweathermap.org/data/2.5/weather?q=" + ciudad_fija + "&appid=" + apiKey + "&units=metric&lang=es";
//String url = "https://api.openweathermap.org/data/2.5/weather?q=granada&appid=20e3cd6f640b1ae47e37932983b07a09&units=metric&lang=es";
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
StaticJsonDocument<1024> doc;
deserializeJson(doc, payload);
temp = doc["main"]["temp"];
hum = doc["main"]["humidity"];
veloc = doc["wind"]["speed"];
climaDesc = doc["weather"][0]["description"].as<String>();
site = doc["name"].as<String>();
country = doc["sys"]["country"].as<String>();
climaDesc.toUpperCase();
}
http.end();
}
}
void setup() {
tft.init(240, 320);
tft.setRotation(3);
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
tft.setTextSize(3);
tft.setTextWrap(true);
tft.setCursor(10, 50);
tft.print("Inicializando la pantalla.");
delay(2000);
tft.fillScreen(ST77XX_BLACK);
Serial.println(F("TFT Initialized"));
// Conexión WiFi
tft.setCursor(10, 50);
tft.print("Conectando WIFI..");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
tft.setCursor(10, 50);
tft.print("Conectando WIFI..");
delay(500);
tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
tft.setCursor(10, 50);
tft.print("Conectando WIFI..");
delay(500);
}
tft.fillScreen(ST77XX_BLACK);
// Configurar NTP
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
obtenerClima();
}
void loop() {
// 1. Gestionar Tiempo (NTP)
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
tft.setCursor(10, 10);
tft.print("Error Hora");
delay(3000);
tft.fillScreen(ST77XX_BLACK);
return;
}
// 2. Actualizar clima cada 10 minutos sin bloquear el reloj
if (millis() - ultimaActualizacionClima > intervaloClima) {
obtenerClima();
ultimaActualizacionClima = millis();
}
// --- DIBUJAR EN PANTALLA ---
tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
// HORA
tft.setCursor(20, 20);
tft.setTextSize(6);
// Formato HH:MM:SS
char buffer[10];
sprintf(buffer, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
tft.print(buffer);
// Dibujar Fecha debajo
tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
tft.setCursor(55, 70);
tft.setTextSize(3);
char fecha[12];
sprintf(fecha, "%02d/%02d/%04d", timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900);
tft.print(fecha);
//delay(1000); // Actualiza cada segundo
// TEMPERATURA Y HUMEDAD
tft.setTextSize(3);
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
tft.setCursor(10, 110);
tft.print("Temperat: "); tft.print(temp, 1); tft.print(" C");
tft.setCursor(10, 135);
tft.print("Humedad: "); tft.print(hum); tft.print(" %");
// 3. Actualizar linea de info meteo cada 60 segundows
if (millis() - ultimaActualizacionInfo > intervaloInfo) {
tft.setCursor(1, 165);
tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);
tft.setTextWrap(false);
tft.print(" "); // Espacios para limpiar texto anterior
if (secuencia >= 3) {secuencia = 1;}
if (secuencia == 1) {
// DESCRIPCIÓN CLIMA (Usamos setTextWrap(false) para evitar saltos raros)
tft.setCursor(1, 165);
tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);
tft.setTextWrap(false);
tft.print(climaDesc + " "); // Espacios para limpiar texto anterior
}
if (secuencia == 2) {
// DESCRIPCIÓN CLIMA (Usamos setTextWrap(false) para evitar saltos raros)
tft.setCursor(1, 165);
tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);
tft.setTextWrap(false);
tft.print("Viento: "); tft.print(veloc); tft.print(" Km/h");
}
ultimaActualizacionInfo = millis();
secuencia = secuencia + 1;
}
// CIUDAD Y FECHA (Base)
tft.setTextSize(3);
tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
tft.setCursor(10, 200);
//tft.print("Site: " + ciudad_fija);
tft.print("Site:"); tft.print(site);tft.print(",");tft.print(country);
delay(1000); // Actualiza cada segundo
}
No hay comentarios:
Publicar un comentario