ESP Jardin — Station de monitoring environnemental
Firmware ESP32 pour une station d'acquisition de températures avec interface web temps réel, API REST et publication MQTT.
Matériel requis
| Composant | Quantité | Notes |
|---|---|---|
| ESP32 DevKit V1 | 1 | ou équivalent 38 broches |
| Sonde DS18B20 | 3 | waterproof recommandé |
| Résistance 4.7 kΩ | 1 | pull-up obligatoire |
| Câbles Dupont | — |
Câblage
DS18B20 (×3 en parallèle)
VCC → 3.3V
GND → GND
DATA → GPIO27 / D6
Résistance 4.7 kΩ entre 3.3V et GPIO27 / D6 (pull-up)
Important : Sans la résistance pull-up, les sondes retournent systématiquement −127°C.
Prérequis logiciels
- VS Code + extension PlatformIO
- Python 3 (requis par PlatformIO)
Installation et premier flash
1. Configurer le WiFi
Éditer include/config.h :
#define WIFI_SSID "VotreSSID"
#define WIFI_PASS "VotreMotDePasse"
2. Configurer le broker MQTT (optionnel)
Dans include/config.h :
#define MQTT_BROKER "192.168.1.x" // IP du broker Mosquitto
#define MQTT_PORT 1883
3. Compiler et téléverser par USB
# Compiler le firmware sans téléverser
pio run -e esp32dev
# Compiler l'image filesystem LittleFS sans téléverser
pio run -e esp32dev -t buildfs
# Téléverser le firmware par USB
pio run -e esp32dev -t upload --upload-port /dev/ttyUSB0
# Téléverser l'interface web LittleFS par USB
pio run -e esp32dev -t uploadfs --upload-port /dev/ttyUSB0
# Ouvrir le moniteur série
pio device monitor --port /dev/ttyUSB0 --baud 115200
Si PlatformIO détecte automatiquement le port USB, --upload-port /dev/ttyUSB0 peut être omis :
pio run -e esp32dev -t upload
pio run -e esp32dev -t uploadfs
4. Vérifier le boot
[BOOT] esp_jardin v1.0 — démarrage...
[WIFI] Connexion STA → SSID: VotreSSID
[WIFI] Connecté — IP: 192.168.1.42
[mDNS] Accessible via http://esp_jardin.local
[OTA] Prêt
[FS] LittleFS monté
[HTTP] Serveur web démarré sur port 80
[SONDES] 3 capteur(s) DS18B20 détecté(s) sur GPIO 27
Accès à l'interface
Une fois connecté à votre réseau :
http://esp_jardin.local # Via mDNS
http://192.168.1.42 # Via IP directe
Mode Access Point de secours
Si le WiFi est indisponible au démarrage, l'ESP crée automatiquement un point d'accès :
| Paramètre | Valeur |
|---|---|
| SSID | ESP_CHEF_JARDIN |
| Mot de passe | Jardin2026 |
| IP de l'interface | 192.168.4.1 |
L'interface web reste accessible. Le broker MQTT est désactivé en mode AP. L'ESP tente de se reconnecter au WiFi STA toutes les 60 secondes.
API REST
Les anciens endpoints /api/... restent disponibles pour compatibilité avec l'interface web. Les nouveaux endpoints recommandés pour un agent IA sont versionnés sous /api/v1/....
| Méthode | Endpoint | Description |
|---|---|---|
| GET | /api/status |
État système (WiFi, MQTT, RAM, uptime) |
| GET | /api/temperatures |
Températures instantanées |
| GET | /api/history |
Historique glissant 24h, moyennes 5 min |
| POST | /api/config |
Mise à jour configuration |
| POST | /api/restart |
Redémarrage logiciel de l'ESP |
| GET | /api/v1/info |
Identité, version, capacités |
| GET | /api/v1/status |
État système complet |
| GET | /api/v1/readings/latest |
Dernière valeur instantanée connue |
| GET | /api/v1/sensors |
Alias de la dernière lecture, avec noms de sondes |
| GET | /api/v1/history |
Historique glissant 24h en moyennes 5 min |
| GET | /api/v1/mqtt |
Broker actif et topics utilisés |
| POST | /api/v1/config/mqtt |
Met à jour broker/port et reconnecte MQTT |
| GET | /api/v1/agent |
Résumé compact pour agent IA |
Exemple /api/temperatures :
{ "sonde_1": "19.3", "sonde_2": "28.7", "sonde_3": null, "unit": "C" }
null = sonde en erreur ou déconnectée.
Exemple POST /api/config :
curl -X POST http://esp_jardin.local/api/config \
-H "Content-Type: application/json" \
-d '{"intervalleMs": 5000, "mqttBroker": "10.0.0.3", "mqttPort": 1883}'
Les paramètres MQTT sont sauvegardés dans /config.json sur LittleFS. Après sauvegarde depuis l'interface web, la connexion MQTT est coupée puis relancée avec le broker et le port enregistrés, sans attendre un redémarrage complet.
Exemple /api/v1/readings/latest :
{
"device": "esp_jardin",
"unit": "C",
"aggregation": {
"history_window_s": 300,
"samples_per_average": 30
},
"readings": [
{ "index": 0, "name": "T°C Ext", "error": false, "temperature": 19.3 }
]
}
Exemple /api/v1/history :
{
"device": "esp_jardin",
"unit": "C",
"range_s": 86400,
"resolution_s": 300,
"points_max": 288,
"sequence": 42,
"points": [
{
"ts": 12600,
"age_s": 120,
"window_s": 300,
"t": [19.3, 22.1, null],
"samples": [30, 30, 0]
}
]
}
L'historique est glissant sur 24h : 24 × 12 = 288 points. Chaque point est une moyenne de 5 minutes, soit 5 min × 60 s / 10 s = 30 mesures par sonde. Les valeurs sont exposées avec 1 chiffre après la virgule.
L'historique est gardé en RAM pour servir rapidement l'API. Il est sauvegardé dans /history.bin sur LittleFS une fois par heure, après 12 nouveaux points moyens. Le fichier est compact : environ 3.8 Ko pour 24h complètes (288 points × 3 sondes), très inférieur à la partition LittleFS de 128 Ko.
Le buffer RAM est circulaire : les nouveaux points remplacent automatiquement les points de plus de 24h. La sauvegarde horaire écrit l'état compact des dernières 24h ; en cas de coupure électrique, on perd au maximum environ 1h d'historique non encore persisté.
MQTT
Topics publiés pour les températures :
| Sonde | Topic | Cadence |
|---|---|---|
| T°C Extérieur | maison/jardin/ext/temperature |
moyenne 5 min |
| T°C Serre | maison/jardin/serre/temperature |
moyenne 5 min |
| T°C Sol | maison/jardin/sol/temperature |
moyenne 5 min |
Le topic d'état publie toujours un payload simple, compatible availability :
maison/jardin/status online
Ce topic est publié en retain=true. Le Last Will MQTT publie offline sur le même topic si la carte plante, perd le WiFi, ou disparaît brutalement. Le broker peut mettre quelques secondes à détecter la perte selon le keepalive MQTT.
Les topics température publient uniquement la moyenne 5 minutes validée, en JSON non retained. Les mesures brutes toutes les 10 secondes restent utilisées pour le live web, mais ne sont pas publiées en MQTT :
{
"device": "esp_jardin",
"index": 0,
"sensor": "T°C Ext",
"temperature": 19.3,
"unit": "C",
"kind": "avg",
"window_s": 300,
"samples": 30,
"ts": 12600,
"error": false,
"uptime_s": 123,
"rssi": -63
}
Les topics erreur publient un JSON retain=true, car ils représentent l'état courant d'une sonde :
{
"device": "esp_jardin",
"index": 0,
"sensor": "T°C Ext",
"error": true,
"uptime_s": 123,
"rssi": -63
}
Pour visualiser les interruptions dans les courbes, utiliser maison/jardin/status comme disponibilité de l'appareil. Quand le status passe à offline, la période doit être affichée comme indisponible plutôt que prolonger la dernière température.
Mise à jour OTA
L'OTA est disponible uniquement quand l'ESP est connecté en WiFi STA. Le mode AP de secours reste accessible pour l'interface web, mais les uploads OTA passent par le réseau WiFi principal. L'OTA n'utilise pas de mot de passe.
Les fichiers générés par PlatformIO sont :
| Type | Fichier |
|---|---|
| Firmware | .pio/build/esp32dev/firmware.bin |
| Filesystem LittleFS | .pio/build/esp32dev/littlefs.bin |
Ordre conseillé :
- Mettre à jour le firmware.
- Attendre le redémarrage de l'ESP.
- Mettre à jour le filesystem LittleFS.
- Recharger la page web et vérifier le footer
FW ... / UI ....
OTA via PlatformIO
# Compiler le firmware OTA sans téléverser
pio run -e esp32dev_ota
# Compiler l'image filesystem LittleFS OTA sans téléverser
pio run -e esp32dev_ota -t buildfs
# Firmware OTA via mDNS
pio run -e esp32dev_ota -t upload
# Firmware OTA via IP directe
pio run -e esp32dev_ota -t upload --upload-port 192.168.1.42
# Filesystem LittleFS OTA via mDNS
pio run -e esp32dev_ota -t uploadfs
# Filesystem LittleFS OTA via IP directe
pio run -e esp32dev_ota -t uploadfs --upload-port 192.168.1.42
OTA via interface web
Depuis l'interface web :
- Ouvrir
http://esp_jardin.local. - Cliquer sur l'icône engrenage.
- Dans
Mise à jour OTA firmware, sélectionner.pio/build/esp32dev/firmware.bin. - Envoyer le firmware et attendre le redémarrage.
- Revenir sur
http://esp_jardin.local. - Dans
Mise à jour OTA filesystem, sélectionner.pio/build/esp32dev/littlefs.bin. - Envoyer le filesystem et attendre le redémarrage.
Sécurités appliquées par l'ESP avant écriture flash :
- le champ firmware accepte uniquement un fichier nommé
firmware.bin, - le champ filesystem accepte uniquement un fichier nommé
littlefs.bin, - le firmware doit commencer par l'en-tête binaire ESP32 attendu,
- la taille du fichier doit tenir dans la partition cible,
- en cas d'erreur, l'ESP renvoie un message JSON et ne redémarre pas volontairement.
GPIO disponibles pour extensions futures
| GPIO | Usage futur | Interface |
|---|---|---|
| 21 / 22 | Capteur BH1750 (luminosité) ou SHT31 (T°/Humidité) | I2C |
| 32 / 33 | Capteur humidité sol | ADC1 (compatible WiFi) |
| 25 / 26 | Relais / électrovanne | Digital out |
| 14 | Pluviomètre à augets | Interruption |
Ne jamais utiliser ADC2 (GPIO 34–39) quand le WiFi est actif — conflit hardware ESP32.
Dépannage
| Symptôme | Cause probable | Solution |
|---|---|---|
| Sonde affiche −127°C | Résistance pull-up absente ou câble défectueux | Vérifier la résistance 4.7 kΩ sur GPIO27 / D6 |
| Sonde affiche 85.0°C | Sonde en court-circuit ou alimentation insuffisante | Vérifier l'alimentation 3.3V |
| Interface web inaccessible | LittleFS non flashé | pio run -t uploadfs |
esp_jardin.local ne répond pas |
mDNS non supporté sur certains réseaux | Utiliser l'IP directe |
| OTA échoue | ESP non connecté au WiFi STA ou fichier .bin incorrect |
Vérifier l'IP, la connexion WiFi et choisir firmware.bin ou littlefs.bin selon le champ utilisé |