DocsPour les développeursConventions ESP32
Conventions — Firmware ESP32
Standards de code C++ utilisés dans le projet aurora-home-esp32.
Conventions de nommage
camelCase + préfixe— Fonctions API publiques (préfixe module)sensorsInitBh1750()sensorsReadScd30()netBegin()netMqttPublish()fusionAverage()AURORA_UPPER_SNAKE_CASE— Constantes de configuration (AURORA_)AURORA_MQTT_PORTAURORA_I2C_SDAAURORA_PUBLISH_INTERVAL_MScamelCase— Variables locales & objets internesco2PpmavgTempCmqttBackoffMshaveScdDataStructure du projet
aurora-home-esp32/
aurora-home-esp32/
platformio.ini# Configuration build & dépendances
include/# Headers publics
Config.h# Paramètres firmware (gitignored)
Config.h.example# Template — cp → Config.h
Logger.h# Macros LOG_INFO / LOG_WARN / LOG_ERROR
sensors.h# API capteurs I2C
net.h# API WiFi Soft-AP + MQTT + mDNS
telemetry.h# Sérialisation JSON (ArduinoJson)
fusion.h# Fusion capteurs (header-only)
src/
main.cpp# Orchestration setup() + loop()
sensors.cpp# Drivers BH1750 / SCD30 / BME280
net.cpp# Soft-AP WiFi, mDNS, MQTT, LWT
telemetry.cpp# Format JSON payload
test/# Tests Unity natifs (sans hardware)
stubs# Stubs Arduino / WiFi / PubSubClient
test_native_fusion
test_native_contracts
test_native_net
test_native_telemetry
examples# Exemples par capteur
scripts# Scripts CI (coverage)
Organisation de main.cpp
main.cpp ne contient que setup() et loop(). La logique métier est répartie dans sensors.cpp, net.cpp et telemetry.cpp :
src/main.cpp
#include "Config.h"
#include "Logger.h"
#include "fusion.h"
#include "net.h"
#include "sensors.h"
#include "telemetry.h"
// setup() — Wire.begin → sensorsInit*() → netBegin() → watchdog
void setup() { ... }
// loop() — netMqtt*() → sensorsRead*()
// → fusionAverage() → telemetryFormat() → netMqttPublish()
void loop() { ... }Pattern init / read
Chaque capteur a deux fonctions dédiées retournant un bool :
include/sensors.h
// Initialisation — retourne true si OK
bool sensorsInitBme280(); // essai 0x76 puis 0x77
bool sensorsInitScd30(); // reset + firmware check
bool sensorsInitBh1750();
// Lecture — retourne true UNIQUEMENT si données disponibles
bool sensorsReadScd30(float& co2Ppm, float& tempC, float& humPct);
bool sensorsReadBme280(float& tempC, float& humPct, float& pressureHpa);
bool sensorsReadBh1750(float& lux);Gestion des erreurs
Erreur critique (setup)
Si un capteur obligatoire (SCD30, BME280) échoue à l'initialisation, fatalReboot() log l'erreur et redémarre l'ESP32 :
if (!sensorsInitScd30()) fatalReboot("SCD30 init");
if (!sensorsInitBme280()) fatalReboot("BME280 init");
// fatalReboot() : LOG_ERROR → delay(2000) → ESP.restart()Erreur non-critique (loop)
Les erreurs de lecture dans la boucle sont loguées via LOG_WARN mais n'interrompent pas le cycle :
if (!sensorsReadBme280(bmeTempC, bmeHumPct, pressureHpa))
LOG_WARN("BME280 read failed");
if (!sensorsReadBh1750(lux))
LOG_WARN("BH1750 read failed");Boucle non-bloquante
src/main.cpp — loop()
void loop() {
esp_task_wdt_reset();
const uint32_t now = millis();
// 1. Attendre client WiFi
if (!netHasClient()) { delay(500); return; }
// 2. Reconnexion MQTT avec backoff exponentiel (1s → 60s)
if (!netMqttConnected()) {
if (now - mqttLastAttemptMs < mqttBackoffMs) { delay(50); return; }
mqttLastAttemptMs = now;
if (!netMqttTryConnect()) { // mDNS d'abord, puis scan IPs
mqttBackoffMs = min(mqttBackoffMs * 2, kMqttBackoffMaxMs);
return;
}
mqttBackoffMs = kMqttBackoffInitialMs;
}
netMqttLoop();
// 3. Lire SCD30 si donnée prête (~toutes les 2s, non-bloquant)
float c = 0, t = 0, h = 0;
if (sensorsReadScd30(c, t, h)) { co2Ppm = c; scdTempC = t; haveScdData = true; }
// 4. Publier selon AURORA_PUBLISH_INTERVAL_MS (défaut 30s)
if (!haveScdData || now - lastPublishMs < AURORA_PUBLISH_INTERVAL_MS) {
delay(10); return;
}
lastPublishMs = now;
sensorsReadBme280(bmeTempC, bmeHumPct, pressureHpa);
sensorsReadBh1750(lux);
const float avgTempC = fusionAverage(scdTempC, bmeTempC);
const float avgHumPct = fusionAverage(scdHumPct, bmeHumPct);
telemetryFormat(payload, sizeof(payload), avgTempC, avgHumPct, ...);
netMqttPublish(AURORA_MQTT_TOPIC_DATA, payload);
}Configuration I2C
src/main.cpp — setup()
Wire.begin(AURORA_I2C_SDA, AURORA_I2C_SCL); // GPIO21 (SDA), GPIO22 (SCL)
// SCD30 : adresse 0x61 — BH1750 : 0x23 — BME280 : 0x76/0x77 (auto)Commandes PlatformIO
platformio run -e esp32devplatformio run -e esp32dev -t uploadplatformio device monitor --baud 115200platformio run -e esp32dev -t clean