From bb913bc3ab10048195b41d44f0ba26fa0b594186 Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Sat, 23 May 2026 16:28:47 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20module=20capteurs=20DS18B20=20=E2=80=94?= =?UTF-8?q?=20acquisition=20non-bloquante,=20buffer=20circulaire=2024h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- include/sensors.h | 8 ++++++ src/main.cpp | 3 +++ src/sensors.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 include/sensors.h create mode 100644 src/sensors.cpp diff --git a/include/sensors.h b/include/sensors.h new file mode 100644 index 0000000..9185f05 --- /dev/null +++ b/include/sensors.h @@ -0,0 +1,8 @@ +#pragma once + +// Initialise le bus OneWire et les capteurs DallasTemperature +void sensors_init(); + +// À appeler à chaque loop() : acquisition non-bloquante toutes les MESURE_INTERVALLE ms +// Retourne true si une nouvelle mesure vient d'être enregistrée +bool sensors_update(); diff --git a/src/main.cpp b/src/main.cpp index 4ecd6c9..edcb79d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include #include "config.h" #include "network.h" +#include "sensors.h" SondeConfig sondesConfig[NB_SONDES] = { { "T°C Ext", "maison/jardin/ext/temperature", 60000, 0.2f }, @@ -16,8 +17,10 @@ void setup() { Serial.begin(115200); Serial.println("[BOOT] esp_jardin démarrage..."); network_init(); + sensors_init(); } void loop() { network_update(); + sensors_update(); } diff --git a/src/sensors.cpp b/src/sensors.cpp new file mode 100644 index 0000000..785c98b --- /dev/null +++ b/src/sensors.cpp @@ -0,0 +1,67 @@ +#include "sensors.h" +#include "config.h" +#include +#include + +static OneWire _oneWire(ONE_WIRE_BUS); +static DallasTemperature _sensors(&_oneWire); + +// États de la machine non-bloquante +static uint32_t _derniereMesureMs = 0; +static uint32_t _demandeMs = 0; +static bool _demandeEnCours = false; + +// Conversion 12 bits = 750 ms +static const uint32_t CONVERSION_MS = 750; + +void sensors_init() { + _sensors.begin(); + _sensors.setWaitForConversion(false); // mode non-bloquant + uint8_t nb = _sensors.getDeviceCount(); + Serial.printf("[SONDES] %u capteur(s) DS18B20 détecté(s) sur GPIO %d\n", nb, ONE_WIRE_BUS); +} + +bool sensors_update() { + uint32_t maintenant = millis(); + + // ── Lancement de la demande de conversion ──────────────────────── + if (!_demandeEnCours && maintenant - _derniereMesureMs >= MESURE_INTERVALLE) { + _sensors.requestTemperatures(); + _demandeMs = maintenant; + _demandeEnCours = true; + return false; + } + + // ── Attente de la fin de conversion (750 ms) ───────────────────── + if (_demandeEnCours && maintenant - _demandeMs >= CONVERSION_MS) { + _demandeEnCours = false; + _derniereMesureMs = maintenant; + + // Lecture et validation de chaque sonde + for (uint8_t i = 0; i < NB_SONDES; i++) { + float t = _sensors.getTempCByIndex(i); + + // Rejeter les valeurs d'erreur DS18B20 + if (t == DEVICE_DISCONNECTED_C || t == 85.0f) { + sondesEtat[i].erreur = true; + sondesEtat[i].tempActuelle = NAN; + Serial.printf("[SONDE %u] ERREUR — valeur rejetée: %.1f\n", i, t); + } else { + sondesEtat[i].erreur = false; + sondesEtat[i].tempActuelle = t; + Serial.printf("[SONDE %u] %s = %.1f°C\n", i, sondesConfig[i].nom, t); + } + } + + // Enregistrement dans le buffer circulaire + historique[histIdx].timestamp = maintenant; + for (uint8_t i = 0; i < NB_SONDES; i++) { + historique[histIdx].temps[i] = sondesEtat[i].tempActuelle; // NAN si erreur + } + histIdx = (histIdx + 1) % HIST_TAILLE; + + return true; // nouvelle mesure disponible + } + + return false; +}