In questo tutorial imparerai le basi per costruire una stazione meteo internet utilizzando un ESP32.
Scaricheremo i dati meteo da OpenWeather, analizzeremo i dati JSON usando ArduinoJson per estrarre temperatura, umidità, posizione e descrizione del meteo e mostreremo queste informazioni su un display OLED.
Iniziamo!
Componenti necessari
Qui sotto trovi i componenti necessari per questo progetto. Per questo progetto sto usando una vecchia scheda ESP32 (ESP32 lite), che è stata deprecata ma puoi ancora trovarla. È quella elencata qui sotto. Esiste un modello successivo con specifiche migliorate, che puoi trovare here . Ma qualsiasi altro ESP32, ESP8266 o Arduino con Wi-Fi andrà bene lo stesso.

ESP32 lite

Cavo dati USB

Set di cavi Dupont

Breadboard

Display OLED
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
OpenWeather
Per la nostra stazione meteo internet ovviamente avremo bisogno di scaricare i dati meteo da internet. Ci sono vari modi per farlo ma il più semplice è usare OpenWeather .
OpenWeather è un servizio che fornisce dati meteo attuali e previsioni tramite un’API che gli sviluppatori possono usare nei loro progetti. Hanno un piano gratuito plan che permette di fare 1000 chiamate API al giorno. Ovvero una chiamata API ogni 60* 60* 24/1000 = 86,4 secondi ed è più che sufficiente, visto che aggiornare il meteo ogni 5 o 10 minuti è più che abbastanza.
Inoltre, anche solo il piano gratuito fornisce informazioni su Current Weather , 3-hour Forecast 5 days , Basic weather maps , Air Pollution e Geocoding . Più che sufficiente per la maggior parte delle applicazioni hobbistiche.
Creare un account OpenWeather
Prima di poter usare qualsiasi API di OpenWeather, ti serve una API-key e per ottenerla devi creare un account. Per creare un account vai alla pagina sign-up e inserisci i tuoi dati lì.

Crea una API-key OpenWeather
Una volta che hai un account e hai effettuato l’accesso vai alla pagina di creazione api-key e crea una API-key. La API-key è quella lunga stringa “sdfd87fakeby6apikeysf4z” che vedi nello screenshot qui sotto. La tua chiave sarà diversa dalla mia, e quella mostrata ovviamente è una chiave finta ; )

Puoi dare un nome alla chiave ma non è obbligatorio. I nomi sono utili se hai più applicazioni che usano chiavi diverse e vuoi tenerle separate.
Scaricare i dati meteo da OpenWeather
Con la tua API-key ora puoi recuperare i dati meteo dalle varie API costruendo l’URL corrispondente. Ad esempio, se vai alla Current Weather API, la documentazione ti dice che l’URL dovrebbe essere così:
https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}
Quindi, dovresti conoscere la latitudine e la longitudine della tua posizione, e la tua API-key e sostituire i segnaposto tra parentesi graffe ( {lat} , {lon} , {API key} ) con i valori reali. Funziona, ma trovare latitudine e longitudine per varie città di interesse è un po’ scomodo.
Per fortuna, c’è la Geocoding API che ci permette di ottenere i dati meteo più facilmente fornendo una stringa con il nome della città e il codice del paese. Il pattern dell’URL è così:
https://api.openweathermap.org/data/2.5/weather?q={city name},{country code}&appid={API key}
Ad esempio, per ottenere il meteo a Melbourne, Australia (AU), dove vivo, scriveresti:
http://api.openweathermap.org/data/2.5/weather?q=Melbourne,AU&APPID=sdfd87fakeby6apikeysf4z
Se incolli questo URL nella barra di ricerca del browser vedrai il seguente output. Assicurati di spuntare la casella “Pretty print” in alto.

Se guardi la temperatura noterai un valore altissimo. Nell’esempio sopra il valore di temperatura riportato è 283.38. Questo perché di default OpenWeather restituisce le temperature in Kelvin. Se vuoi unità metriche (Celsius) o imperiali (Fahrenheit), puoi specificarlo nell’URL.
Ad esempio, per avere le temperature in Celsius devi usare:
https://api.openweathermap.org/data/2.5/weather?q={city name},{country code}&appid={API key}&units=metric
e per Fahrenheit scriveresti units=imperial . Per maggiori informazioni dai un’occhiata alla documentazione di OpenWeather per units of measurement .
Questo è tutto quello che ti serve sapere per iniziare con OpenWeather. Ma ti consiglio di esplorare anche le altre API menzionate sopra. Ci sono un sacco di dati interessanti che puoi usare per rendere la tua stazione meteo davvero utile.
Analizzare dati JSON con ArduinoJson
Di default OpenWeather restituisce i dati in formato JSON . JSON è un formato di testo strutturato che dobbiamo analizzare per estrarre i dati che ci interessano. Farlo a mano è piuttosto complicato, quindi usiamo l’ottima libreria ArduinoJson .
Documento JSON
Ma prima di tutto vediamo quali informazioni vogliamo estrarre dai dati meteo. Lo screenshot qui sotto mostra tutti i dati che ottengo chiedendo a OpenWeather il meteo di Melbourne.

Per la nostra semplice stazione meteo internet, estrarrò quattro informazioni: la breve descrizione del meteo sotto weather -> main ( "Clouds" ), la temperatura attuale sotto main -> temp ( 10.29 ), l’umidità relativa attuale sotto main -> humidity ( 82 ), e il nome della località sotto name ( "Melbourne" ).
Estrazione dei dati con ArduinoJson
Uno snippet di codice che usa ArduinoJson per estrarre questi quattro valori meteo sarebbe così:
StaticJsonDocument<4096> doc; String json = http.getString(); deserializeJson(doc, json); const char* name = doc["name"]; const char* weather = doc["weather"][0]["main"]; float temp = doc["main"]["temp"]; int hum = doc["main"]["humidity"];
Per prima cosa devi riservare un po’ di memoria dove caricare i dati JSON. La riga StaticJsonDocument<4096> doc; riserva 4KB di memoria. Se scarichi più dati meteo, come le previsioni, potresti dover aumentare questo valore.
Poi scarichiamo i dati meteo e li scriviamo (deserializziamo) nel documento. Lo snippet di codice non mostra il client HTTP che usiamo per il download ma lo troverai nel codice completo qui sotto.
String json = http.getString(); deserializeJson(doc, json);
Se i dati JSON restituiti da OpenWeather fossero sintatticamente errati (parentesi mancanti, …), la deserializzazione fallirà.
Deserializzare significa semplicemente che il testo semplice della stringa json viene analizzato e convertito in una struttura dati che ci permette di accedere più facilmente ai campi e ai valori del documento JSON doc . Per maggiori dettagli sulla deserializzazione dai un’occhiata all’ottima ArduinoJson tutorial on deserialization .
Le seguenti quattro righe di codice estraggono le informazioni che ci servono dal doc che contiene la stringa json deserializzata.
const char* name = doc["name"]; const char* weather = doc["weather"][0]["main"]; float temp = doc["main"]["temp"]; int hum = doc["main"]["humidity"];
La prima riga estrae il nome della località meteo ( "Melbourne" ), che è memorizzato sotto doc["name"] . Poiché è una stringa (vedi le virgolette), dobbiamo salvarla in una variabile di tipo const char* name .
La breve descrizione del meteo ( "Clouds" ) è memorizzata sotto doc["weather"][0]["main"] . Nota che sotto doc["weather"] , abbiamo una lista [] e ci interessa il primo (e unico) elemento di quella lista. Quindi dobbiamo scrivere doc["weather"][0] . Poi otteniamo la descrizione sotto main , e il percorso completo è doc["weather"][0]["main"] . Anche qui viene restituita una stringa e va salvata in una variabile di tipo const char* weather .
La temperatura attuale è un valore floating point (10.29), che si trova sotto doc["main"]["temp"] . Essendo un valore floating point va salvato in una variabile di tipo float .
Infine, estraiamo l’umidità attuale ( 82 ) da doc["main"]["humidity"] e la salviamo in una variabile di tipo int .
Devi fare molta attenzione a far corrispondere i tipi di dato dei valori con quelli usati nel documento JSON e a usare i percorsi corretti per estrarre quei valori. Altrimenti rischi errori di memoria molto difficili da individuare. Se vuoi estrarre valori diversi, procedi con calma e aggiungi nuovi valori uno alla volta, così saprai subito quando qualcosa non va.
Collegare ESP32 e OLED
Collegare l’ESP32 all’OLED è molto semplice perché l’OLED ha un’interfaccia I2C. Prima collega il ground (G) dell’ESP32 al GND dell’OLED. Poi collega il 3V dell’ESP32 al VCC dell’OLED.

Poi dobbiamo collegare SCL e SDA. Qualsiasi pin va bene ma i pin I2C di default su ESP32-lite sono 23 per SCL e 19 per SDA. Quindi colleghiamo i pin corrispondenti dell’OLED a questi. L’immagine sopra mostra il cablaggio completo. Se hai difficoltà, guarda il tutorial How to Interface the SSD1306 I2C OLED Graphic Display With Arduino
Se non sai quali sono i pin I2C di default per il tuo ESP32, non preoccuparti. È facile scoprirlo. Basta eseguire il seguente codice e il tuo ESP32 te lo dirà.
void print(const char* name, int pin) {
Serial.print(name);
Serial.println(pin);
}
void setup() {
Serial.begin(9600);
}
void loop() {
print("SDA: ", SDA);
print("SCL: ", SCL);
delay(5000);
}
Per maggiori informazioni leggi il nostro post su come Find I2C and SPI default pins . In alternativa, puoi definire tu i pin che vuoi usare. Il codice nelle sezioni seguenti ti mostra come fare.
Codice per la Stazione Meteo Internet
In questa sezione scriveremo il codice per scaricare i dati meteo da OpenWeather, estrarre posizione, temperatura, umidità e descrizione del meteo dai dati e mostrarli su un OLED. Dai un’occhiata al codice completo qui sotto e poi ne discuteremo i dettagli.
#include "WiFi.h"
#include "HTTPClient.h"
#include "ArduinoJson.h"
#include "Adafruit_SSD1306.h"
#define WIFI_SSID "YOURSSID"
#define WIFI_PASSWORD "YOURPASSWORD"
#define URL "http://api.openweathermap.org/data/2.5/weather?q=Melbourne,AU&APPID=YOURAPIKEY&units=metric"
HTTPClient http;
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
StaticJsonDocument<4096> doc;
void downloadWeather() {
http.begin(URL);
if (http.GET() > 0) {
String json = http.getString();
auto err = deserializeJson(doc, json);
if (err) {
Serial.printf("Deserializion error: %s\n", err.f_str());
}
} else {
Serial.println("Could not get data!");
}
http.end();
}
void displayWeather() {
const char* name = doc["name"];
const char* weather = doc["weather"][0]["main"];
float temp = doc["main"]["temp"];
int hum = doc["main"]["humidity"];
oled.clearDisplay();
oled.setCursor(0, 0);
oled.printf(" %s\n", name);
oled.printf(" %s\n", weather);
oled.printf(" T: %.1f C\n", temp);
oled.printf(" H: %d %%\n", hum);
oled.display();
}
void oled_init() {
Wire.begin(19, 23); // sda, scl
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.clearDisplay();
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
void wifi_init() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED)
delay(500);
}
void setup(void) {
Serial.begin(115200);
oled_init();
wifi_init();
}
void loop() {
downloadWeather();
displayWeather();
delay(10*60*1000); // 10min
}
Librerie
Il codice inizia includendo le librerie necessarie. WiFi.h per l’accesso WiFi, HTTPClient.h per scaricare dati via HTTP, ArduinoJson.h per analizzare i dati scaricati e Adafruit_SSD1306.h per mostrare i dati sull’OLED.
WiFi.h e HTTPClient.h sono librerie standard ma ArduinoJson.h e Adafruit_SSD1306.h dovrai installarle tramite il Library Manager.
Costanti
Poi definiamo alcune costanti. In particolare le credenziali WiFi e l’URL dell’API OpenWeather da cui scarichiamo i dati meteo. Puoi cambiare l’URL per ottenere i dati di un’altra località o in un’altra unità, ma non dimenticare di usare la tua API-key.
#define WIFI_SSID "YOURSSID" #define WIFI_PASSWORD "YOURPASSWORD" #define URL "http://api.openweathermap.org/data/2.5/weather?q=Melbourne,AU&APPID=YOURAPIKEY&units=metric"
Dai un’occhiata alla documentazione API per Current Weather , che mostra tutti i modi diversi in cui puoi costruire un URL. Guarda anche la Geocoding API , che semplifica l’uso delle località.
Oggetti
Per il resto del codice ci serviranno tre oggetti. Un HTTPClient che ci permette di scaricare dati da un sito web, un StaticJsonDocument per memorizzare i dati deserializzati e un oggetto oled per mostrare i dati sull’OLED.
HTTPClient http; Adafruit_SSD1306 oled(128, 64, &Wire, -1); StaticJsonDocument<4096> doc;
Per l’OLED devi specificare le dimensioni, nel mio caso sono 128×64 pixel, e per il documento JSON dobbiamo riservare la quantità massima di memoria che potenzialmente ci serve. Ho riservato generosamente 4kB (4069 Byte), che bastano per i dati meteo attuali. Se scarichi le previsioni, che sono più grandi, potresti dover riservare più spazio.
downloadWeather
La funzione downloadWeather scarica i dati meteo da OpenWeather tramite http.GET() , li deserializza e li salva nel StaticJsonDocument tramite deserializeJson ().
void downloadWeather() {
http.begin(URL);
if (http.GET() > 0) {
String json = http.getString();
auto err = deserializeJson(doc, json);
if (err) {
Serial.printf("Deserializion error: %s\n", err.f_str());
}
} else {
Serial.println("Could not get data!");
}
http.end();
}
Se qualcosa va storto, stampiamo un messaggio di errore sul Serial Monitor.
displayWeather
Per mostrare il meteo prima estraiamo le quattro informazioni meteo dal doc come descritto sopra. Poi puliamo il display, impostiamo il cursore e semplicemente stampiamo il nome della località, la breve descrizione del meteo, la temperatura attuale e l’umidità relativa.
void displayWeather() {
const char* name = doc["name"];
const char* weather = doc["weather"][0]["main"];
float temp = doc["main"]["temp"];
int hum = doc["main"]["humidity"];
oled.clearDisplay();
oled.setCursor(0, 0);
oled.printf(" %s\n", name);
oled.printf(" %s\n", weather);
oled.printf(" T: %.1f C\n", temp);
oled.printf(" H: %d %%\n", hum);
oled.display();
}
Sull’OLED le informazioni meteo verranno visualizzate come mostrato nell’immagine qui sotto.

oledInit
Prima di poter usare l’OLED dobbiamo inizializzarlo. La cosa più importante è specificare i pin usati per l’interfaccia I2C (SDA, SCL) e l’indirizzo I2C del display.
Se usi i pin I2C di default per il tuo microcontrollore, non serve chiamare Wire.begin(), altrimenti sì.
L’indirizzo I2C dell’OLED che sto usando è 0x3C, che è comune, ma il tuo potrebbe essere diverso. Dai un’occhiata al tutorial How to Interface the SSD1306 I2C OLED Graphic Display With Arduino , se hai difficoltà.
void oled_init() {
Wire.begin(19, 23); // sda, scl
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.clearDisplay();
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
A parte questo, basta pulire il display e impostare la dimensione e il colore del testo.
wifiInit
Allo stesso modo dell’OLED dobbiamo anche inizializzare la connessione WiFi. Assicurati di usare il ssid e la password corretti, altrimenti il client WiFi non si connetterà.
void wifi_init() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED)
delay(500);
}
setup
Con le funzioni di supporto sopra la funzione setup è diventata molto semplice. Basta inizializzare la comunicazione seriale, l’OLED e il WiFi e il gioco è fatto.
void setup(void) {
Serial.begin(115200);
oled_init();
wifi_init();
}
loop
Anche la funzione loop è semplice. Scarichiamo i dati meteo, li mostriamo sull’OLED e poi aspettiamo 10 minuti prima di ripetere il processo.
void loop() {
downloadWeather();
displayWeather();
delay(10*60*1000); // 10min
}
Durante l’implementazione e i test assicurati di avere un ritardo abbastanza lungo quando scarichi i dati meteo. Se superi le 1000 chiamate al giorno verrai bloccato per quel giorno.
Altrimenti, è tutto qui! Ora hai una bella stazione meteo internet!
Conclusione
In questo tutorial hai imparato come costruire una stazione meteo internet. Anche se è molto basilare, è un ottimo punto di partenza per una stazione meteo molto più avanzata.
Esplora le altre API che OpenWeather offre e vedi quali dati vuoi estrarre. I dati restituiti da OpenWeather includono anche gli id delle icone che puoi usare per mostrare le icone meteo.
Potresti voler passare a un display più grande rispetto al piccolo OLED che abbiamo usato qui. Alcuni display Elecrow con ESP32 integrato e touch screen potrebbero essere una buona scelta. Vedi la CrowPanel 2.8″ ESP32 Display : Easy Setup Guide su come usarne uno.
Oltre ai dati meteo da internet puoi anche raccogliere dati meteo locali usando sensori di temperatura, umidità e qualità dell’aria.
Infine, reagire attivamente alle condizioni meteo cambianti e accendere irrigatori, chiudere finestre o attivare il condizionatore sono progetti divertenti.
Divertiti ; )

