Station météo ESP32 connectée à internet
Le projet
J'ai fait l'acquisition d'un ESP32 Yellow Display. Comme son nom l'indique c'est un ESP32 avec un écran.
Il possède les extensions principales suivantes :
Ecran tactile 320 x 240 pixels de 2,8 ''
LED RVB et LDR embarquées
Lecteur de carte micro SD
Connecteur de Port sériel
Connecteur pour haut-parleur
Connecteur GPIO : P3 -> Gnd, GPIO 35,22,21
Connecteur GPIO : CN1 -> Gnd, GPIO 22, 27, 3,3V
Un connecteur micro USB : programmation et alimentation 5V
Le tout pour 10 € sur AliExpress, avec la possibilité de le programmer avec l'IDE d'Arduino, utiliser
des bibliothèques graphiques puissantes comme TFT_espi, LVGL et se connecter à internet.
Après avoir testé différents sketchs Arduino comme la commande d'un relais avec 2 boutons tactiles, des mesures analogiques affichées sur l'écran, j'ai trouvé sur le site internet Medium une station météo qui affiche les données météo en se connectant à un site OpenWeather via une API.
Les fichiers à télécharger
Affichage avec Bme280 |
Station complète | Support |
|---|---|---|
La station météo complète
Le programme ci-dessus à été porté dans le code de la station météo.
On affiche donc la température et l'humidité en local.
La date, l'heure ont été déplacées en haut à gauche de l'afficheur.
En haut à droite on affiche la température et l'humidité en local sous l'étiquette HOME.
La mise en veille s'éffectue au bout de 5 minutes, la variable counter est incrémentée toute les minutes.

L'affichage mis à jour
le reveil se fait avec un bouton poussoir comme dans le programme ci-dessus.
L'API d'OpenWeather est gratuite mais limite les requêtes à 60 appels en 24 h, ce qui est largement suffisant
pour une consulation journalière. De toute façon la boucle loop est réglée pour des appels toutes les 1/4 d'heure.
Un support a été réalisé avec une'imprante 3D, dans lequel prend
place
le Bme280, le bouton poussoir
et ESP32 Yellow Display.
Le support

La station dans son support
Des améliorations
Affichage de données locales
L'ESP32 Yellow Display disposant d'un accès à quelques GPIO, je trouvais dommage de ne pas les utiliser.
Pourquoi ne pas réaliser une mise en veille à l'aide d'un bouton poussoir ? Il n'est pas utile d'avoir un affichage actif 24 h sur 24. La consommation est divisée par 10. On passe de 145 mA à 14 mA en mode sleep profond de l'ESP 32.
Il y a de la place sur l'afficheur pour des données locales comme
la température et l'humidité dans la pièce. Un capteur comme un DHT11 ou
BME280 peut être utilisé.
J'ai connecté un bouton poussoir à P3 et un BME280 à CN1.
j'ai d'abord écrit un sketch Arduino avec un BME280 et un bouton
poussoir
sans connection à internet, sans les données météo du site
Openweather.
Le schéma de câblage montre les branchements.
Le bouton poussoir permet le reveil de l'ESP32 gràce à une interruption
sur la broche IO35.
Une résistance de forçage de 10 Kohms met la broche
au niveau haut.
Un appui sur le bouton poussoir fait passer la broche au
niveau bas.
Le mode Deep Sleep de l'ESP32 est bien expliqué sur ce tutoriel
Le BME280 est connecté en I2C.
L'affichage des 4 mesures
Le programme
Les mesures et l'affichage
#define I2C_SDA 27
#define I2C_SCL 22
Adafruit_BME280 bme;
TwoWire MyWire = TwoWire(0);
Adafruit_BME280 bme;
MyWire.begin(I2C_SDA, I2C_SCL, 100000);
Attribution des broches GPIO SDA -> 27 SCL-> 22
Création d'un objet bme et MyWire
tft.drawString("Temperature", 175, 5, FONT_SIZE4);
String tmp = String(bme.readTemperature()) + " C";
tft.drawString(tmp, 195, 35, FONT_SIZE4);Lecture de la température avec la fonction
bme.readTemperature()
Affichage la temperature
La mise en veille et le reveil
RTC_DATA_ATTR int bootCount = 0;
++bootCount;
esp_sleep_enable_ext0_wakeup(GPIO_NUM_35,0);
Charger le Timer RTC avec la variable bountCout
Incrémenter bountCountDéclencher une interruption sur la broche GPIO 35 pour faire passer l'ESP32 en mode réveil
void loop()
{
char k ;
for(k = 0; k < 6; k++)
{
Update();
delay(5000);
}
esp_deep_sleep_start();
}
Dans la boucle la variable K est incrémenté 5 fois, l'affichage est mis à jour toute les 5 s.
L'ESP32 passe en mode sommeil après 25 s
Le programme complet
/**************************************************************************** * BME280 PRESSURE, TEMPERATURE, HUMIDITY AND ALTITUDE * =========================================================================== * * BME 280 sensor module is used to measure the atmospheric, pressure, * temperature, humidity, and the altitude.The results are displayed on the * TFT display * * ESP 32 in mode SLEEP * * Program: BME280 * Jm defais * January 2026 * See Https://www.electroloisirs.fr *********************************************************************************/ #include < SPI.h > #include < TFT_eSPI.h> #include < Adafruit_BME280.h > #include < Wire.h> #define I2C_SDA 27 #define I2C_SCL 22 RTC_DATA_ATTR int bootCount = 0; // Variable to RTC counter TwoWire MyWire = TwoWire(0); Adafruit_BME280 bme; // Create a BME 280 object TFT_eSPI tft = TFT_eSPI(); #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 #define FONT_SIZE2 2 #define FONT_SIZE4 4 // // This function updates the TFT display // void Update() { // Draw separators on the display tft.fillScreen(TFT_BLACK); tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.drawFastHLine(0, 188, 319, TFT_BLUE); tft.drawFastVLine(170, 0, 239, TFT_BLUE); tft.drawFastHLine(170, 65, 239, TFT_BLUE); tft.drawFastHLine(170, 130, 239, TFT_BLUE); // temperature, pressure, humidity, and altitude draw on display tft.drawString("Temperature", 175, 5, FONT_SIZE4); String tmp = String(bme.readTemperature()) + " C"; tft.drawString(tmp, 195, 35, FONT_SIZE4); tft.drawString("Pressure", 190, 70, FONT_SIZE4); String pres = String(bme.readPressure() / 100) + " hPa"; tft.drawString(pres, 176, 100, FONT_SIZE4); tft.drawString("Humidity", 190, 135, FONT_SIZE4); String humi = String(bme.readHumidity()) + " %"; tft.drawString(humi, 190, 160, FONT_SIZE4); tft.drawString("Altitude", 190, 195, FONT_SIZE4); String alti = String(bme.readAltitude(1013.25)) + " m"; tft.drawString(alti, 186, 217, FONT_SIZE4); tft.setTextColor(TFT_RED); tft.drawString("Jm Defais", 50, 205, FONT_SIZE2); tft.setTextColor(TFT_ORANGE); tft.drawString("HOME", 50, 80, FONT_SIZE4); } void setup() { ++bootCount; esp_sleep_enable_ext0_wakeup(GPIO_NUM_35,0); // LOW Signal on GPIO 35 wake up ESP32 delay(500); Serial.begin(9600); MyWire.begin(I2C_SDA, I2C_SCL, 100000); bool status = bme.begin(0x76, &MyWire); //BME 280 address 0x76 if(!status) { Serial.println("Error in initializing the sensor"); while(1); } tft.init(); tft.setRotation(1); } // // Main program loop. The TFT display is updated every 5 seconds // void loop() { char k ; for(k = 0; k < 6; k++) { Update(); // Update the TFT delay(5000); } esp_deep_sleep_start(); // ESP 32 sleep }


La réalisation
Toutes les instructions se trouvent sur la page Medium d'AndroidCrypto et le téléchargement du projet se trouve sur le dépôt Github d'AndroidCrypto.
Comme l'explique AndroidCrypto sur sa page, il a réalisé quelques modifications mais les sources restent les mêmes.
Le code a été réalisé par Daniel Eishhorn, voir sur la page squix . le code a été modifié par Bodmer sur Github
Si vous comptez réaliser ce projet, voici les prérequis:
Créer un compte sur OpenWeather pour obtenir une APi, gratuite pour 60 requêtes sur 24 h.
Télécharger les bibliothèques spécifiques sur le dépôt github TFT_eSPI , JSON_decoder, OpenWeather de Bodmer, Time et Timezone
Charger les images dans la mémoire flash de l'ESP32 en utilisant Little.FS, voir le tutoriel
Pour utiliser la bibliothèque TFT_eSPI, il faut configurer le fichier User_Setup.h, pour l'adapter au driver ILI9341 de l'affichage.
Sur mon PC le fichier se trouve dans le dossier : C:\Users\JMDefais\Documents\Arduino\libraries\TFT_eSPI. C'est de dossier où les sketchs sont enregistés. On peut remplacer ce fichier par celui contenu l'archive Bme280.zip ou le modifier en utilisant le fichier texte setup_change.txt.
Ensuite il suffit de modifier le fichier All_settings.h comme expliqué sur la page d'AndroidCrypto. En veillant à ne pas mettre des accents ou caractères spéciaux dans les constantes String .
j'ai modifier les lignes :
#define WIFI_SSID "ma livebox"
#define WIFI_PASSWORD "ma clé"const String api_key = "ma clé API OpenWeather " ;
const String latitude = "ma latitude" ;
const String longitude = "ma longitude" ;const String language = "fr" ;
const String shortDOW [ 8 ] = { "???" , "DIM" , "LUN" , "MAR" , "MER" , "JEU" , "VEN" , "SAM" } ;
const char sunStr[] = "Soleil" ;
const char cloudStr[] = "Nuages" ;
const char humidityStr[] = "Humidite" ;
const String moonPhase [ 8 ] = { "Nouvelle" , "1er croissant" , "1er quartier" , "Croissante" , "Pleine" , "Decroissante" , "Der quartier" , "Der croissant" } ;
