Dans ce tutoriel, vous allez apprendre les bases pour construire votre propre station météo connectée à Internet avec un ESP32.
Nous allons télécharger les données météo depuis OpenWeather, analyser les données JSON avec ArduinoJson pour extraire la température, l’humidité, la localisation et la description météo, puis afficher ces informations sur un écran OLED.
C’est parti !
Matériel nécessaire
Vous trouverez ci-dessous la liste des composants nécessaires pour ce projet. Pour ce tutoriel, j’utilise une ancienne carte ESP32 (ESP32 lite), qui n’est plus produite mais reste disponible. C’est celle listée ci-dessous. Il existe un modèle successeur avec de meilleures spécifications, que vous pouvez trouver here . Mais n’importe quel autre ESP32, ESP8266 ou Arduino avec Wi-Fi fonctionnera aussi.

ESP32 lite

Câble USB de données

Jeu de fils Dupont

Breadboard

Écran 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
Pour notre station météo connectée, il nous faut évidemment télécharger les données météo depuis Internet. Il existe plusieurs façons de le faire, mais la plus simple est d’utiliser OpenWeather .
OpenWeather est un service qui fournit des données météo actuelles et des prévisions via une API que les développeurs peuvent utiliser dans leurs projets. Ils proposent une plan gratuite qui permet de faire 1000 requêtes API par jour. Cela fait une requête API toutes les 60* 60* 24/1000 = 86,4 secondes, ce qui est largement suffisant, car mettre à jour la météo toutes les 5 ou 10 minutes est amplement rapide.
De plus, même le plan gratuit fournit des informations sur Current Weather , 3-hour Forecast 5 days , Basic weather maps , Air Pollution et Geocoding . C’est largement suffisant pour la plupart des projets de loisirs.
Créer un compte OpenWeather
Avant de pouvoir utiliser les API OpenWeather, il vous faut une clé API, donc un compte. Pour créer un compte, rendez-vous sur la page sign-up et saisissez vos informations.

Créer une clé API OpenWeather
Une fois votre compte créé et connecté, allez sur la page de création de api-key clé API et créez-en une. La clé API est cette longue chaîne de caractères « sdfd87fakeby6apikeysf4z » que vous voyez dans la capture d’écran ci-dessous. Votre clé sera différente de la mienne, et celle affichée ici est évidemment une fausse ; )

Vous pouvez donner un nom à la clé, mais ce n’est pas obligatoire. Les noms sont utiles si vous avez plusieurs applications qui utilisent différentes clés et que vous souhaitez les organiser.
Télécharger les données météo OpenWeather
Avec votre clé API, vous pouvez maintenant récupérer les données météo depuis les différentes API en construisant l’URL appropriée. Par exemple, si vous allez sur l’API Current Weather , la documentation indique que l’URL doit ressembler à ceci :
https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}
Vous aurez donc besoin de connaître la latitude et la longitude de votre emplacement, ainsi que votre clé API, et de remplacer les éléments entre accolades ( {lat} , {lon} , {API key} ) par les valeurs réelles. Cela fonctionne, mais trouver la latitude et la longitude de chaque ville qui vous intéresse peut être un peu fastidieux.
Heureusement, il existe l’API Geocoding API qui permet d’obtenir les données météo plus facilement en fournissant simplement le nom de la ville et le code pays. Le format d’URL ressemble à ceci :
https://api.openweathermap.org/data/2.5/weather?q={city name},{country code}&appid={API key}
Par exemple, pour obtenir la météo à Melbourne, Australie (AU), où je vis, il suffit d’écrire :
http://api.openweathermap.org/data/2.5/weather?q=Melbourne,AU&APPID=sdfd87fakeby6apikeysf4z
Si vous collez cette URL dans la barre de recherche de votre navigateur, vous verrez la sortie suivante. Pensez à cocher la case « Pretty print » en haut.

Si vous regardez la température, vous remarquerez une valeur très élevée. Dans l’exemple ci-dessus, la température indiquée est 283,38. C’est parce que, par défaut, OpenWeather retourne les températures en Kelvin. Si vous souhaitez des unités métriques (Celsius) ou impériales (Fahrenheit), vous pouvez le préciser dans l’URL.
Par exemple, pour obtenir la température en Celsius, il faut utiliser :
https://api.openweathermap.org/data/2.5/weather?q={city name},{country code}&appid={API key}&units=metric
et pour Fahrenheit, il faut écrire units=imperial . Pour plus d’informations, consultez la documentation OpenWeather pour units of measurement .
C’est tout ce qu’il faut savoir pour débuter avec OpenWeather. Mais je vous recommande de parcourir les autres API mentionnées plus haut. Il y a plein de données intéressantes à exploiter pour rendre votre station météo vraiment utile.
Analyser les données JSON avec ArduinoJson
Par défaut, OpenWeather retourne les données au format JSON . JSON est un format texte structuré qu’il faut analyser pour extraire les données souhaitées. C’est assez compliqué à faire soi-même, c’est pourquoi nous utilisons l’excellente bibliothèque ArduinoJson à la place.
Document JSON
Mais d’abord, voyons quelles informations nous voulons extraire des données météo. La capture d’écran ci-dessous montre toutes les données que j’obtiens en demandant la météo de Melbourne à OpenWeather.

Pour notre petite station météo connectée, je vais extraire quatre informations : la courte description de la météo sous weather -> main ( "Clouds" ), la température actuelle sous main -> temp ( 10.29 ), l’humidité relative actuelle sous main -> humidity ( 82 ), et le nom de la localisation sous name ( "Melbourne" ).
Extraire les données avec ArduinoJson
Un extrait de code utilisant ArduinoJson pour extraire ces quatre valeurs météo ressemblerait à ceci :
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"];
D’abord, il faut réserver de la mémoire pour charger les données JSON. La ligne StaticJsonDocument<4096> doc; réserve 4 Ko de mémoire. Si vous téléchargez plus de données météo, comme les prévisions, il faudra peut-être augmenter cette valeur.
Ensuite, on télécharge les données météo et on les écrit (désérialise) dans le document. L’extrait de code ne montre pas le client HTTP utilisé pour le téléchargement, mais vous le trouverez dans le code complet ci-dessous.
String json = http.getString(); deserializeJson(doc, json);
Si les données JSON retournées par OpenWeather sont syntaxiquement incorrectes (crochets manquants, …), la désérialisation échouera.
La désérialisation signifie simplement que le texte brut de la chaîne json est analysé et converti en une structure de données qui permet d’accéder plus facilement aux champs et valeurs du document JSON doc . Pour plus de détails sur la désérialisation, consultez l’excellente documentation de ArduinoJson tutorial on deserialization .
Les quatre lignes de code suivantes extraient les informations souhaitées du doc qui contient la chaîne json désérialisée.
const char* name = doc["name"]; const char* weather = doc["weather"][0]["main"]; float temp = doc["main"]["temp"]; int hum = doc["main"]["humidity"];
La première ligne extrait le nom de la localisation météo ( "Melbourne" ), qui est stocké sous doc["name"] . Comme il s’agit d’une chaîne de caractères (voir les guillemets), il faut la stocker dans une variable de type const char* name .
La courte description météo ( "Clouds" ) est stockée sous doc["weather"][0]["main"] . Notez que sous doc["weather"] , on a une liste [] et on veut le premier (et unique) élément de cette liste. Il faut donc écrire doc["weather"][0] . Ensuite, on récupère la description sous main , et le chemin complet est doc["weather"][0]["main"] . Là encore, cela retourne une chaîne à stocker dans une variable de type const char* weather .
La température actuelle est une valeur flottante (10,29), située sous doc["main"]["temp"] . Comme c’est une valeur à virgule flottante, il faut la stocker dans une variable de type float .
Enfin, on extrait l’humidité actuelle ( 82 ) depuis doc["main"]["humidity"] et on la stocke dans une variable de type int .
Il faut bien faire attention à faire correspondre les types de données des valeurs avec ceux utilisés dans le document JSON, et à utiliser les bons chemins pour extraire ces valeurs. Sinon, vous risquez d’avoir des erreurs mémoire très difficiles à déboguer. Si vous souhaitez extraire d’autres valeurs, allez-y progressivement et ajoutez-les une par une pour savoir quand un problème survient.
Connexion de l’ESP32 et de l’OLED
Connecter l’ESP32 à l’OLED est très simple car l’OLED utilise une interface I2C. Commencez par relier la masse (G) de l’ESP32 au GND de l’OLED. Ensuite, connectez le 3V de l’ESP32 au VCC de l’OLED.

Ensuite, il faut connecter les broches SCL et SDA. N’importe quelle broche peut convenir, mais les broches I2C par défaut sur l’ESP32-lite sont 23 pour SCL et 19 pour SDA. Il suffit donc de relier les broches correspondantes de l’OLED à celles-ci. La photo ci-dessus montre le câblage complet. Si vous avez des difficultés, consultez le tutoriel How to Interface the SSD1306 I2C OLED Graphic Display With Arduino
Si vous ne connaissez pas les broches I2C par défaut de votre ESP32, pas de panique. C’est facile à trouver. Lancez simplement le code suivant et votre ESP32 vous l’indiquera.
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);
}
Pour plus d’informations, lisez notre article sur comment Find I2C and SPI default pins . Sinon, vous pouvez définir les broches que vous souhaitez utiliser. Le code dans les sections suivantes vous montre comment faire.
Code pour la station météo connectée
Dans cette section, nous allons écrire le code pour télécharger les données météo depuis OpenWeather, extraire la localisation, la température, l’humidité et la description météo, puis les afficher sur un écran OLED. Regardez d’abord le code complet ci-dessous, puis nous en discuterons les détails.
#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
}
Bibliothèques
Le code commence par inclure les bibliothèques nécessaires. WiFi.h pour l’accès WiFi, HTTPClient.h pour télécharger les données via HTTP, ArduinoJson.h pour analyser les données téléchargées et Adafruit_SSD1306.h pour afficher les données sur l’OLED.
WiFi.h et HTTPClient.h sont des bibliothèques standards, mais ArduinoJson.h et Adafruit_SSD1306.h devront être installées via le Library Manager.
Constantes
Ensuite, nous définissons quelques constantes, notamment les identifiants WiFi et l’URL de l’API OpenWeather, d’où nous téléchargeons les données météo. Vous pouvez modifier l’URL pour obtenir la météo d’un autre endroit ou dans une autre unité, mais n’oubliez pas d’utiliser votre clé API.
#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"
Consultez la documentation de l’API pour Current Weather , qui montre toutes les façons de construire une URL. Regardez aussi Geocoding API , qui simplifie l’utilisation des localisations.
Objets
Pour le reste du code, nous aurons besoin de trois objets : un HTTPClient pour télécharger les données depuis un site web, un StaticJsonDocument pour stocker les données désérialisées, et un objet oled pour afficher les données sur l’OLED.
HTTPClient http; Adafruit_SSD1306 oled(128, 64, &Wire, -1); StaticJsonDocument<4096> doc;
Pour l’OLED, il faut spécifier les dimensions, dans mon cas 128×64 pixels, et pour le document JSON, il faut réserver la quantité maximale de mémoire potentiellement nécessaire. J’ai généreusement réservé 4 Ko (4069 octets), ce qui suffit pour les données météo actuelles. Si vous téléchargez les prévisions météo, qui sont plus volumineuses, il faudra peut-être prévoir plus d’espace.
downloadWeather
La fonction downloadWeather télécharge les données météo depuis OpenWeather via http.GET() , les désérialise et les stocke dans le StaticJsonDocument via 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();
}
Si quelque chose ne va pas, un message d’erreur s’affiche dans le Serial Monitor.
displayWeather
Pour afficher la météo, on extrait d’abord les quatre informations météo du doc comme expliqué plus haut. Ensuite, on efface l’écran, on place le curseur et on affiche simplement le nom de la localisation, la courte description météo, la température actuelle et l’humidité relative.
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();
}
Sur l’OLED, les informations météo s’afficheront comme sur la photo ci-dessous.

oledInit
Avant d’utiliser l’OLED, il faut l’initialiser. Le plus important est de spécifier les broches utilisées pour l’interface I2C (SDA, SCL) et l’adresse I2C de l’écran.
Si vous utilisez les broches I2C par défaut de votre microcontrôleur, vous n’avez pas besoin d’appeler Wire.begin(), sinon il faut le faire.
L’adresse I2C de l’OLED que j’utilise est 0x3C, ce qui est courant, mais la vôtre peut être différente. Consultez le tutoriel How to Interface the SSD1306 I2C OLED Graphic Display With Arduino si vous avez des difficultés.
void oled_init() {
Wire.begin(19, 23); // sda, scl
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.clearDisplay();
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
À part ça, on efface juste l’écran et on définit la taille et la couleur du texte.
wifiInit
Comme pour l’OLED, il faut aussi initialiser la connexion WiFi. Assurez-vous d’utiliser le bon ssid et mot de passe, sinon le client WiFi ne se connectera pas.
void wifi_init() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED)
delay(500);
}
setup
Avec les fonctions utilitaires ci-dessus, la fonction setup est devenue très simple. On initialise juste la communication série, l’OLED et le WiFi, et c’est tout.
void setup(void) {
Serial.begin(115200);
oled_init();
wifi_init();
}
loop
La fonction loop est aussi simple. On télécharge les données météo, on les affiche sur l’OLED, puis on attend 10 minutes avant de recommencer.
void loop() {
downloadWeather();
displayWeather();
delay(10*60*1000); // 10min
}
Lors de l’implémentation et des tests, assurez-vous d’avoir un délai suffisamment long entre chaque téléchargement de données météo. Si vous dépassez 1000 appels par jour, vous serez bloqué pour la journée.
Sinon, c’est tout ! Vous avez maintenant une petite station météo connectée sympa !
Conclusion
Dans ce tutoriel, vous avez appris à construire une station météo connectée. Même si elle est très basique, c’est un excellent point de départ pour une station météo bien plus avancée.
Explorez les autres API proposées par OpenWeather et voyez quelles données vous souhaitez extraire. Les données retournées par OpenWeather incluent même des identifiants d’icônes que vous pouvez utiliser pour afficher des pictogrammes météo.
Vous voudrez peut-être passer à un écran plus grand que le petit OLED utilisé ici. Certains écrans Elecrow avec ESP32 intégré et écran tactile peuvent être un bon choix. Consultez le CrowPanel 2.8″ ESP32 Display : Easy Setup Guide pour savoir comment en utiliser un.
En plus des données météo Internet, vous pouvez aussi collecter des données locales avec des capteurs de température, d’humidité et de qualité de l’air.
Enfin, réagir activement aux changements météo en allumant des arroseurs, en fermant des fenêtres ou en activant la climatisation sont des projets amusants à réaliser.
Amusez-vous bien ; )

