Introduction
Présentation du Projet
Ce projet est né de mon intérêt pour l’électronique, la domotique, l’IoT et le travail artisanal. C’est un vieux rêve que j’ai de posséder toutes sortes d’automates connectés contrôlés à distance.
Objectif
Ces dispositifs doivent avoir un certain niveau d’autonomie, ils doivent fonctionner à l’énergie solaire et être dotés d’une forme de conscience énergétique pour agir en conséquence.
- Rapporter les données du capteur de manière régulière.
- Faible consommation d’énergie.
- Conscience énergétique et prise de mesures.
- Capacité de mises à jour via les ondes (sans fil).
Cartes ESP32 et Compatibilité
Cartes prises en charge
Espressif possède une plateforme appelée ESP-IDF qui est mise à jour avec leurs nouvelles annonces et matériels, ainsi qu’avec les nouvelles fonctionnalités et les changements de sécurité. Ces mises à jour sont ensuite reflétées en aval dans PlatformIO et le framework Arduino, mais avec un délai significatif. Cela entraîne des incompatibilités entre les fichiers de configuration. Une de ces incompatibilités s’est manifestée lorsque j’ai essayé d’utiliser le fichier de configuration d’un ESP32 sur une carte ESP32C3.
Référence Externe pour le Capteur ADC
Problème avec le Capteur ADC sur l’ESP32C3
Il y a un problème lors de l’utilisation de l’ADC sur le module ESP32C3. Le bug est lié au type d’entier utilisé dans la bibliothèque du module ADC pour l’ESP32, qui est différent de celui de l’ESP32C3, entraînant une incompatibilité.
Mise en place de la Référence Externe1
Le problème est rapidement résolu avec la ligne de code suivante dans le fichier YAML :
external_components:
- source: github://pr#5151
components: [adc]
Mise en Œuvre du Projet
Composants Matériels
- 1 Panneau solaire de 6 volts - lien vers le produit
- 1 batterie LiPo 18650 de 2000 mAh
- 1 microcontrôleur ESP32-C3 - lien vers le produit
- or 1 microcontrôleur ESP32 - lien vers le produit
- 1 capteur de température, de pression et d’humidité BME280 - lien vers le produit
- 1 module MPPT, régulateur d’alimentation solaire - lien vers le produit
- 1 régulateur pullup de 3,7 à 5 volts - lien vers le produit
- 1 chargeur de batterie LiPo de 5 volts via MicroUSB. - lien vers le produit
Je vous recommande vivement d’acquérir un adaptateur TTL UART ou un adaptateur série vers USB si vous ne l’avez pas déjà. Cela sera d’une grande aide pour le débogage. lien vers le produit
Je poste les liens vers ces produits uniquement à titre de référence technique. Je ne suis pas rémunéré pour les afficher, et je ne les recommande pas de manière particulière. Je les ai choisis pour leur fonctionnalité et leur prix à ce moment-là. La batterie est récupérée à partir d’un ancien module d’ordinateur portable.
Conception du Circuit
Le circuit est plutôt simple, j’ai 2 composants passifs, le panneau solaire et la batterie, puis j’ai les 3 composants actifs :
- Le MPPT ou régulateur du point de puissance maximale (paneau solaire)
L'énergie solaire est directement influencée par la couverture du soleil et l'intensité lumineuse. Par conséquent, un chargeur de batterie simple placé directement entre un panneau solaire et une batterie ne fonctionnera que pendant une heure par jour, le reste du temps, il consommera trop d'énergie et "court-circuitera le panneau" dans le processus. C'est là que le MPPT se démarque, le module correspond à la meilleure tension avec l'intensité maximale, puis la convertit en 4,2 volts, la tension de charge nécessaire pour les batteries Li-Po.
- L’élévateur de tension (step-up booster) de 3,7 à 5, 8 ou 12 volts
Les modules ESP32 fonctionnent à 3,3 volts ou à 5 volts, rien entre les deux, donc ils ont besoin d'une source de courant fiable. J'ai choisi ce module en raison des multiples options de tension de sortie.
- Le chargeur de batterie micro USB 5 volts
Sachant que l'hiver approche, j'ai choisi d'investir dans une méthode de charge de secours. C'est une option simple mais efficace et fiable.
Ensuite, il y a aussi le microcontrôleur: ESP32C3-wroom-mini et le capteur BME280 pour la température, la pression et l’humidité.
Configuration Logicielle
Comme mentionné, la plateforme utilisée pour ce projet est ESPHome. Elle fonctionne avec des fichiers de configuration au format YAML qui sont analysés, puis le projet est compilé et construit.
Après quelques semaines d’essais et d’erreurs, j’ai finalement abouti à un fichier de configuration pas si mal. Je vais montrer ici seulement les parties que je trouve intéressantes. Pour le fichier YAML complet, rendez-vous sur : https://git.cabivr.net/radu/solar-power_weather_station
La configuration commence avec la commande “on_boot” qui déclenche un script via un commutateur de variable globale (global variable switch).
esphome:
name: $device
friendly_name: $device
on_boot:
then:
- delay: 10s
- switch.turn_on: session_switch
Que nous trouvons déclaré ici :
- platform: template
id: session_switch
name: "session_switch"
lambda: |-
if (id(session)) {
return true;
} else {
return false;
}
turn_on_action:
- lambda: |-
id(session) = 1;
turn_off_action:
- lambda: |-
id(session) = 0;
on_turn_on:
then:
- logger.log: "'********************** Script en cours d'exécution *************************'"
- script.execute: check_stuff
Et ici:
globals:
- id: ota_mode
type: int
restore_value: True
initial_value: '0'
- id: session
type: int
restore_value: True
initial_value: '1'
- id: naptime
type: int
restore_value: True
initial_value: '15'
- id: updates
type: int
restore_value: no
initial_value: '0'
Le script déclenché active à nouveau la variable et commence à scanner les capteurs avec la condition d’attendre jusqu’à ce que tout soit terminé. Ensuite, il détermine le temps de sommeil après avoir vérifié le niveau de charge de la batterie.
script:
- id: check_stuff
then:
- logger.log: "Démarrage de l'exécution du script"
- lambda: |-
id(session) = 1;
- lambda: |-
id(updates) = 0;
id(bat).update();
id(bme280_sensor).update();
- wait_until:
lambda: |-
return(id(updates) >= 2);
- logger.log:
format: "Mises à jour terminées : %d"
args: ['id(updates)']
- lambda: |-
float df = abs(id(bat_lev).state);
if ((df <= 100) && (df >= 80)) { // 100% - 80% de charge restante
id(naptime) = $t_100;
} else if ((df <= 80) && (df >= 60)) { // 80% - 60% de charge restante
id(naptime) = $t_80;
} else if ((df <= 60) && (df >= 40)) { // 60% - 40% de charge restante
id(naptime) = $t_60;
} else if ((df <= 40) && (df >= 20)) { // 40% - 20% de charge restante
id(naptime) = $t_40;
} else if ((df <= 20) && (df >= 10)) { // 20% - 10% de charge restante
id(naptime) = $t_20;
} else if (df < 10) { // under 10% de charge restante
id(naptime) = $t_10;
- logger.log:
format: "En cours de mise en veille pour %d minutes | OTA : %d"
args: ['id(naptime)', 'id(ota_mode)']
Ensuite, on vérifie le drapeau OTA (Over-The-Air) qui, s’il est activé, empêchera l’appareil d’entrer en mode veille.
- if:
condition:
lambda: 'return id(ota_mode) == 0;'
then:
- logger.log:
format: "Condition remplie, entrée en mode veille. ota_mode = %d"
args: ['id(ota_mode)']
- sensor.template.publish:
id: nap
state: !lambda 'return id(naptime);'
- deep_sleep.enter:
id: deep_sleep_1
sleep_duration: !lambda |-
return id(naptime) * 60000;
else:
- logger.log:
format: "Condition remplie, la veille est empêchée. ota_mode = %d"
args: ['id(ota_mode)']
- deep_sleep.prevent: deep_sleep_1
Ici, le script se termine, ce qui suit sont les déclarations des capteurs qui ont l’attribut update_interval
défini sur never
, donc ils ne seront pas appelés. Par conséquent, l’appareil entrera soit en mode veille, soit il attendra une mise à jour du micrologiciel en annonçant sa présence en ligne via l’API.
sensor:
- platform: bme280
id: bme280_sensor
update_interval: never
temperature:
name: "BME280 Température"
id: temp
on_value:
lambda: |-
id(updates)++;
...
Implémentation de la mise à jour du micrologiciel via OTA
Créer un commutateur (switch) ciblant une variable globale nous offre l’opportunité de créer un service accessible depuis Home Assistant via l’API.
api:
encryption:
key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
services:
- service: start_ota
then:
- switch.turn_on: ota_switch
- logger.log: "Signal OTA reçu ! Démarrage de l'OTA"
- service: start_session
then:
- switch.turn_on: session_switch
- logger.log: "Signal de session reçu ! Démarrage de la session"
Le seul problème est que si nous activons le commutateur (switch) lorsque l’appareil est en veille, cela n’aura aucun effet. Effectivement, une automatisation peut venir à la rescousse.
J’ai créé un commutateur (input boolean) ou un assistant bascule (toggle helper) dans le menu de Home Assistant sous “Appareils, Intégrations et Aides”, puis j’ai créé une automatisation qui écoute l’état du commutateur lorsque celui-ci passe de la position “éteint” (off) à la position “allumé” (on), puis attend que l’appareil cible se connecte en ligne et active le mode ota_mode
via un appel de service.
Une fois la commande envoyée, elle effectue un appel de service au commutateur (toggle) et le remet dans la position initiale “éteint” (off
).
- id: '1690982182366'
alias: Start OTA w-station0
description: Attendre que l'appareil se connecte en ligne afin d'envoyer le drapeau de prévention du sommeil.
trigger:
- platform: state
entity_id:
- input_boolean.start_ota_w-station0
from: "off"
to: "on"
condition: []
action:
- wait_for_trigger:
- platform: state
entity_id:
- binary_sensor.w-station0.state
from: "off"
to: "on"
- service: esphome.w-station0_start_ota
data: {}
- service: input_boolean.turn_off
data: {}
target:
entity_id:
- input_boolean.start_ota_w-station0
mode: single
Tous ces paramètres fonctionnent à merveille, c’est très stable et fiable. Ce que j’ai trouvé être un obstacle, c’est le délai avant que le script ne démarre au démarrage, actuellement de 10 secondes. Avec seulement 5 secondes de délai, l’OTA n’est pas activé en permanence, ce qui le rend peu fiable.
Résultats du Projet
Même si ce n’est pas une station météo complète qui calcule la vitesse du vent, dispose d’un pluviomètre et de toutes les options avancées, ce projet est quand même très bien compte tenu du coût et de l’expérience d’apprentissage.
Voici quelques photos de l’une des stations météo que j’ai réalisées ainsi que du tableau de bord. J’en ai effectivement fabriqué 3 et j’ai l’intention d’en faire une autre sans panneau solaire pour la cave.
Conclusion
Leçons Apprises
J’ai appris à utiliser le framework ESPHome, un peu de soudure et la conception et mise en œuvre de circuits. Bien sûr, je n’aurais pas pu le savoir sans faire des recherches sur les problèmes que les panneaux solaires peuvent avoir et qui, s’ils ne sont pas pris en compte, pourraient les rendre inefficaces.
Améliorations Futures
Je prévois de créer un fichier commun comon.yaml qui contiendra toutes les configurations identiques pour tous les appareils. Et peut-être ajouter quelques capteurs supplémentaires.