Projet station météo

Bonjour à tous,

Comme beaucoup je me lance dans la création d’une station météo DIY. Cela permet de l’adapter a ses besoin et rajouter les capteurs que l’on souhaite.

Je créé ce sujet pour partager mon projet mais également pour centraliser mes questions/demandes d’aide.

La station est codée sous ESPHOME directement dans Home Assitant

Liste des composants à ce jour:

  • ESP32-WROOM-32U avec antenne externe
  • Capteur SHT35 pour température/humidité
  • Capteur LPS22HB pour la pression atmosphérique
  • Capteur BH1750 + TSL2561 pour la luminosité
  • Capteur pluviomètre MISOL
  • Capteur anémomètre MISOL
  • Capteur direction du vent MISOL
  • Des résistances, des câbles, PCB de prototypage
  • 1 convertisseur élévateur MT3608 DC-DC
  • 1 gestionnaire de charge solaire MPPT CN3791 (version 6V)
  • 2 panneaux solaires 6V, 3W (soit 6W)
  • un pistolet à colle

Le schéma de câblage:

L’intérieur en bazar

la station installée à l’extérieur

Pour les capteurs de luminosité voici ce que j’ai fait. Dans une petite boite de dérivation j’ai fait un trou dans le couvercle avec un scie cloche de 42 mm. J’ai ensuite découper dans une plaque de plexiglass un disque de 50 mm que j’ai collé sur le couvercle avec un pistolet à colle. Enfin vous collez le capteur sur le plexi.

État d’avancement :

  • fait : Intégration des capteurs I2C (SHT35, LPS22HB, BH1750 et TSL2561), anémomètre, direction du vent et pluviomètre
  • a faire : optimiser alimentation

J’ai acheté deux panneaux de 3W pour une tension de 6V en plein soleil. J’ai devrais avoir 6W pour 6V ==> 1A. Sur le site marchand je lis courant de fonctionnement de 0 à 240 mA. Soit la valeur de courant est erronée soit c’est la puissance du panneau. Idéalement il faudrait que les panneaux produisent au moins 2A pour optimiser la charge (valeur max de charge du CN3791).

Code ESPHOME :

substitutions:
  name: esphome-web-c6f7d4
  friendly_name: esp-station-meteo

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  min_version: 2024.6.0
  name_add_mac_suffix: false

  libraries:
    - SPI
    - Wire
    - Adafruit_Sensor=https://github.com/adafruit/Adafruit_Sensor.git
    - Adafruit_BusIO=https://github.com/adafruit/Adafruit_BusIO.git
    - Adafruit_LPS2x=https://github.com/adafruit/Adafruit_LPS2X.git
 
  project:
    name: esphome.web
    version: dev

external_components:
  # Use the LPS22 Sensor External Component from our GitHub
  - source: github://AeroSteveO/Air-Gradient-Extended
    components: [ lps22_sensor ]
    refresh: 0s

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret enc_key_rostock
# Allow Over-The-Air updates
ota:
- platform: esphome

# Allow provisioning Wi-Fi via serial
improv_serial:

wifi:
  # Set up a wifi access point
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: X
    gateway: X
    subnet: X

# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
captive_portal:

dashboard_import:
  package_import_url: github://esphome/example-configs/esphome-web/esp32.yaml@main
  import_full_config: true

# Sets up Bluetooth LE (Only on ESP32) to allow the user
# to provision wifi credentials to the device.
esp32_improv:
  authorizer: none

# To have a "next url" for improv serial
web_server:

i2c:
  id: bus_a
  sda: GPIO21
  scl: GPIO22
  scan: true

globals:
  - id: rainfall_total
    type: float
    initial_value: "0.0"  
    
sensor:
#########Capteur signal wifi#######  
  - platform: wifi_signal
    name: "Signal wifi"
    update_interval: 5s
    unit_of_measurement: dB
    accuracy_decimals: 0
    force_update: false
    icon: mdi:wifi

#########Capteur durée de fonctionnement#######  
  - platform: uptime
    id: uptime_seconds
    name: "Uptime Sensor"
    update_interval: 5s
    unit_of_measurement: s
    accuracy_decimals: 0
    force_update: false
    icon: mdi:timer

#########Capteur niveau batterie####### 
  - platform: adc
    id: level_battery
    pin: GPIO33
    name: "tension batterie"
    attenuation: 11db
    #internal: true
    update_interval: 5s
    accuracy_decimals: 3
    filters:
      - multiply: 1.47 #multiplicateur = Vin/Vout
      
  - platform: template
    name: "Niveau Batterie (%)"
    unit_of_measurement: "%"
    update_interval: 10s
    lambda: |-
      const float min_voltage = 3.2;
      const float max_voltage = 4.2; 
      float voltage = id(level_battery).state;
      return (voltage - min_voltage) / (max_voltage - min_voltage) * 100.0;      

#########Capteur température SHT35#######
  - platform: sht3xd
    i2c_id: bus_a
    temperature:
      name: "Température extérieure"
      device_class: "temperature"
      state_class: "measurement"
      unit_of_measurement: "°C"
      accuracy_decimals: 1
    humidity:
      name: "Humidité extérieure"
    address: 0x44
    update_interval: 5s

##########Capteur luminosité BH1750#######
  - platform: bh1750
    name: "Luminosité BH1750 "
    id: sensor_bh1750
    #internal: true
    address: 0x23
    update_interval: 5s

##########Capteur luminosité TSL2561#######
  - platform: tsl2561
    name: "Luminosité TSL2561"
    id: sensor_tsl2561
    #internal: true
    address: 0x39
    update_interval: 5s

##########Moyenne Capteur luminosité#######
  - platform: template 
    name: "Luminosité" 
    unit_of_measurement: "lx"
    icon: mdi:brightness-5
    update_interval: 5s
    lambda: |- 
          return (id(sensor_bh1750).state + id(sensor_tsl2561).state)/2;

##########Capteur pression LPS22HB#######   
  - platform: lps22_sensor
    temperature:
      name: "LPS22 Temperature"
      unit_of_measurement: °C
      state_class: "measurement"
      accuracy_decimals: 1
    pressure:
      name: "Pression atmosphérique"
      unit_of_measurement: hPa
      state_class: "measurement"
      accuracy_decimals: 2

##########Capteur vitesse du vent#######  
  - platform: pulse_meter
    pin:
      number: GPIO34
      mode: INPUT
    id: wind_speed
    unit_of_measurement: 'km/h'
    name: "vitesse du vent"
    icon: 'mdi:weather-windy'
    internal_filter: 13us
    timeout: 5s
    filters:
      - multiply: 0.04
      - sliding_window_moving_average:
          window_size: 10 
          send_every: 10
      - timeout: # pour remettre à 0 le capteur quand il arrête de tourner 
          timeout: 5s
          value: 0

##########Capteur pluviomètre#######   
  - platform: pulse_counter
    pin: GPIO35  
    name: "Précipitation"
    update_interval: 60s  
    filters:
      - multiply: 0.2794
    unit_of_measurement: "mm"
    on_value:
      then:
        - lambda: |-
            id(rainfall_total) += x;  // Ajoute la pluie mesurée au cumul
            ESP_LOGD("rain_gauge", "Cumul actuel: %.2f mm", id(rainfall_total));

  - platform: template
    name: "Cumul précipitation"
    unit_of_measurement: "mm"
    accuracy_decimals: 4
    update_interval: 60s
    lambda: |-
      return id(rainfall_total);

#########Capteur orientation du vent####### 
  - platform: adc
    id: wind_direction_adc
    pin: GPIO32
    name: "Direction du vent (tension)"
    attenuation: 11db
    #internal: true
    update_interval: 5s
    accuracy_decimals: 3
 
text_sensor:
  - platform: template
    name: "Direction du vent"
    icon: "mdi:weather-windy"
    id: wind_direction_text
    update_interval: 5s
    lambda: |-
      float direction = id(wind_direction_adc).state;
      if (direction > 2.2 && direction < 2.6) {
        return {"Nord"};
      } else if (direction > 1.15 && direction < 1.7) {
        return {"Nord-Est"};
      } else if (direction > 0.21 && direction < 0.35) {
        return {"Est"};
      } else if (direction > 0.35 && direction < 0.8) {
        return {"Sud-Est"};
      } else if (direction > 0.80 && direction < 1.15) {
        return {"Sud"};
      } else if (direction > 1.70 && direction < 2.2) {
        return {"Sud-Ouest"};
      } else if (direction > 2.9 && direction < 3.1) {
        return {"Ouest"};
      } else if (direction > 2.6 && direction < 2.9) {
        return {"Nord-Ouest"};
      } else {
        return {"Unknown"};
      }
    
1 « J'aime »

Je dois commander le matériel pour l’alimentation mais j’avoue avoir du mal a bien tout identifier.

Je possède déjà 2 batteries 18650 de 3000mAh chacune. L’idée c’est donc d’alimenter l’ESP32 avec des panneaux solaires + les 2x18650. Je partirai sur 2 panneaux 5V 500mA et un régulateur de charge TP4056. La question se pose sur l’ tension de sortie en direction de l’ESP32.
Je me disais alimenter l’ESP32 via l’USB avec une tension stable de 5V. Dans ce cas de figure, il va me falloir amplifier la tension si j’utilise mes 18650 en en dérivation (3,7V) ou la réduire si je les utilise en série (7,4V).

Quel serait la meilleure solution pour alimenter mon ESP32 et quel composant pour augmenter ou réduire la tension à 5V ?

Merci

Salut,
C’est un sujet que j’avais fait il y a quelques temps sur un ESP12 et j’avais beaucoup travaillé sur l’optimisation de la batterie, car cela va dépendre de l’endroit ou tu habites, car si comme à Lyon, tu peux passer plusieurs jours sans soleil, les panneaux ne servent à rien.
Après à tester sur pile chez toi, mais tu peux avoir beaucoup d’optimisation :

  • Utilisé par exemple un BME680 (temp, humidité et pression) plutôt que plusieurs capteurs
  • Voir la remplacement de la carte ESP32-WROOM (même si sa consommation est assez réduite). Plutôt que passer par l’USB qui va consommer encore plus, par par un simple LDO (type LM7850) pour alimenter tout ton circuit et l’alimenter en 5V, plutôt qu’un amplificateur de tension, qui va te limiter en intensité.
  • Intégrer du deepsleep entre tes mesures (tu divises par 10 minimum - en fonction des cartes- la consommation)
  • Intégrer un pont diviseur pour connaitre ta tension de tes piles et donc la capacité restante de tes piles.

A bientôt

Attention, ce n’est que des conseils, mais je suis preneur de tes retours.

Hello,

J’utilise pas, mais il est aussi possible de passer en 3V3, j’étais tombé sur ça il y a quelques temps

cdt

salut

j’ai identifié cela pour ta question relative a l’alimentation

bonnes fetes

Je suis en région parisienne donc a part l’été le soleil c’est compliqué. Je suis conscient que les panneaux solaires ne permettront pas de recharger complétement la batterie surtout en hiver mais plutôt de prolonger au maximum leur durée de vie (je ne suis pas fermé à une recharge de temps en temps sur secteur de la batterie).

Pour les capteurs c’est un choix de précision. J’ai préféré avoir plusieurs capteurs précis plutôt que un avec une grosse incertitude (± 1°C c’est déjà trop).

L’info sur le niveau de batterie je souhaite l’avoir (j’ai pas encore regardé comment intégrer cela dans HA).

Sur le net il y a des tutos pour générer du 3V3. On est d’accord que ça se branche directement sur le PIN VIN de l’ESP32 ? (j’utilise que l’USB pour mes autres projets)

Je viens de regarder les broches de mon ESP et je ne vois pas de VIN:

Sur quel pin je dois faire arriver le 3,3V ?

Bonjour,

J’ai mis en standby la partie alimentation pour finaliser l’intégration des capteurs.
Je m’attaque à la girouette pour la direction du vent. Pour le câblage j’ai suivi la fiche technique.

J’ai ensuite calculé la tension Vout pour une tension Vin de 3,3V sachant que le constructeur donne les valeurs pour 5V.

.

J’ai contrôlé mon montage avec un multimètre et j’ai bien les bonnes tensions Vout quand je tourne la girouette.

La partie code est un peu plus compliqué pour moi. De ce que j’ai compris, il faut utiliser la platform ADC pour récupérer la valeur de tension en fonction de la direction. Voici le code que j’ai écrit et qui me remonte bien la valeur de tension dans HA.

  - platform: adc
    id: wind_direction_adc
    pin: GPIO32
    name: "direction du vent (RAW)"
    attenuation: 11db
    #internal: true
    update_interval: 5s
    accuracy_decimals: 3

Sur internet j’ai vu qu’il faut utiliser ensuite la platform : resistance. Sincèrement je ne comprend pas l’utilité. En effet, j’ai déjà la correspondance entre tension et direction. Pour moi, je dois mettre dans le code le lien entre la tension au GPIO32 et la direction mais je ne sais absolument pas quel platform utiliser et comment l’écrire sous esphome.

Merci pour votre aide

finalement avec chatGPT j’ai réussi. Voici le code:

  - platform: adc
    id: wind_direction_adc
    pin: GPIO32
    name: "direction du vent (RAW)"
    attenuation: 11db
    #internal: true
    update_interval: 5s
    accuracy_decimals: 3
 
text_sensor:
  - platform: template
    name: "Direction du vent"
    icon: "mdi:weather-windy"
    id: wind_direction_text
    update_interval: 5s
    lambda: |-
      float direction = id(wind_direction_adc).state;
      if (direction > 2.2 && direction < 2.6) {
        return {"Nord"};
      } else if (direction > 1.15 && direction < 1.7) {
        return {"Nord-Est"};
      } else if (direction > 0.21 && direction < 0.35) {
        return {"Est"};
      } else if (direction > 0.35 && direction < 0.8) {
        return {"Sud-Est"};
      } else if (direction > 0.80 && direction < 1.15) {
        return {"Sud"};
      } else if (direction > 1.70 && direction < 2.2) {
        return {"Sud-Ouest"};
      } else if (direction > 2.9 && direction < 3.1) {
        return {"Ouest"};
      } else if (direction > 2.6 && direction < 2.9) {
        return {"Nord-Ouest"};
      } else {
        return {"Unknown"};
      }
    
1 « J'aime »

C’est encore moi :laughing:
Dernier capteur à coder : le pluviomètre à bascule. Voici le code que j’ai écris avec mon copain chatGPT:

globals:
  - id: rainfall_total
    type: float
    initial_value: "0.0"  
sensor:
  - platform: pulse_counter
    pin: GPIO35  
    name: "Rainfall (Current Interval)"
    update_interval: 5s  
    filters:
      - multiply: 0.2794
    unit_of_measurement: "mm"
    on_value:
      then:
        - lambda: |-
            id(rainfall_total) += x;  // Ajoute la pluie mesurée au cumul
            ESP_LOGD("rain_gauge", "Cumul actuel: %.2f mm", id(rainfall_total));

  - platform: template
    name: "Cumulative Rainfall"
    unit_of_measurement: "mm"
    accuracy_decimals: 4
    update_interval: 5s
    lambda: |-
      return id(rainfall_total);

Le code fonctionne en me remontant une valeur rainfall et le cumule. Cependant, j’ai un problème sur la valeur rainfall. En effet, sur la notice du pluviomètre chaque bascule correspond à 0,2794 mm d’eau.
Je m’attendais donc à avoir dans HA 0,2794 mm à la première bascule puis 0,5588 mm à la deuxième bascule et ainsi de suite. Or dans HA, chaque bascule correspond à 3,3535 mm.

Je ne comprends pas d’où provient cet écart d’un facteur 12 sachant que j’ai bien mis 0,2794 dans le multiplicateur.

Merci pour votre aide

Salut…
Surement à l’update_interval de 5s !
C’est la bascule qui doit faire l’incrément !

1 « J'aime »

effectivement dans une minute il y a 12 x 5s qui est comme par hasard le coefficient entre 3,33535 mm et 0,2794 mm.
Dans mon esprit update interval c’était simplement le temps entre deux consultations du sensor mais qui est indépendant de la mesure.

Edit: j’ai mis update_interval à 60s (valeur par defaut du pulse-counter) et maintenant ca fonctionne correctement. Merci Doubledom.

J’ai mis a jour mon code sur mon premier poste.

Concernant l’alimentation je suis parti sur ça comme suggéré:

J’ai branché mes deux accu 18650 et en sortie j’ai mis un câble USB pour me brancher sur l’USB C de l’ESP32.

Ça fonctionne très bien. Avant de tout souder j’ai mesuré le courant. Au démarrage de l’ESP32 je consomme environ 140 mA puis ça descend à 70mA. On va voir avec les panneaux solaires mais en hiver ça va être chaud vu ma consommation.

Hello,

Voici mes dernières aventures. J’ai donc alimenté ma station avec avec 2 anciens accu 18650 3000mAh en parallèle soit un total de 6000mAh.

Comme je monitore la tension je peux remonter à la capacité des batteries: avec un courant de 70mA, les batteries sont vides (3,2 V) en 24h soit une autonomie d’environ 1700 mAh ==> les batteries sont mortes

J’ai également connecté deux panneaux de 3W/5V. En plein soleil, la tension que je mesure est proche de 6V. Une fois les panneaux branchés au module MH-CD42, si la luminosité est suffisante l’alimentation de l’ESP32 est coupé.

Je suppose une mise en sécurité du MH-CD42 lorsque la tension en provenance des panneaux est supérieure à 5,5 V. Une solution serait d’abaisser la tension des panneaux avec une diode type 1N5822.

Si vous avez d’autre idée je suis preneur

Salut …

Regarde plus tôt vers une régulateur de tension type 7805 ou diode Zéner (tension adequat) avec charge. Il y aura une consommation de plus !

j’avais vu ce type de régulateur :

Ça devrait faire l’affaire et au moins il y aura une tension stable de 5V comparé à la diode

Salut @brocopike

Ton sujet m’intéresse et je pense me pencher sur l’installation d’une station météo dans un futur proche.
Néanmoins, je peux également t’apporter une autre idée concernant l’alimentation.
Tu peux viser un mix entre batterie plus grosse et panneau solaire.

Personnellement, j’utilise un ESP32 dans le fond de mon jardin qui contrôle une électrovanne. Donc loin de toute alimentation électrique.
Cet ESP32 est connecté à un contrôleur de charge solaire (il me sort du 5v), qui est lui même alimenté par une batterie 12V relié à un panneau solaire 12v.

Panneau solaire → Contrôleur de charge
Batterie 12v → Contrôleur de charge
Contrôleur de charge => ESP32

Sans deep sleep, il tient très longtemps et s’éteint seulement lorsqu’il y a plusieurs jours de mauvais temps sans assez de soleil pour recharger la batterie.

Tout est encapsulé dans un grosse boite de dérivation. C’est très étanche, après plus d’un an d’utilisation, j’ai réouvert la boite dernièrement et il n’y avait aucune trace d’humidité.

Tu peux même te passer du contrôleur de charge solaire et opter pour un petit circuit te convertissant du 12v en 5v.

L’idée c’est donc de partir sur une batterie plus grosse, qui encaissera mieux les périodes où le panneau solaire ne pourra pas bien faire son rôle. Tu peux ensuite abaisser la tension pour alimenter l’ESP32 facilement.

Merci pour les infos. A la base je voulais une solution pas trop encombrante qui tient sur le mat de la station.

Jattends la livraison des dernieres pieces avant de tester et j’aviserais ensuite.

Voici les dernières nouveautés.
mon schéma de câblage est le suivant:


le module MP1584 permet de ramener la tension des panneaux solaires de 6V à 5V. Le module MH-CD42 gère la charge et décharge des accus 18650.

En l’absence de lumière sur les panneaux l’ESP32 est bien alimenté par les accus. Si les panneaux produisent alors l’ESP32 s’éteint (plus d’alimentation). Si je débranche l’ESP32, alors les panneaux commence à charger les accus.

En gros, il semble ne pas y avoir de gestion, c’est soit de l’alimentation (décharge) soit de la charge mais pas les deux en même temps. Pourtant le module MH-CD42 doit gérer les deux simultanément.

J’ai enfin résolu mon problème avec l’achat du CN3791 MPTT qui gère vraiment les panneaux solaires. J’ai mis le schéma dans mon premier post