Sonde Météorologique
Analyse et gestion thermique en milieu éducatif.
L'objectif de ce projet est d'étudier la gestion thermique dans une salle de classe. Les données environnementales (UV et luminosité) sont captées par un microcontrôleur STM32 WB55, transmises en Bluetooth Low Energy vers un Raspberry Pi, acheminées via MQTT vers un VPS, stockées en base de données et visualisées sur Grafana et un afficheur M5Stack.
1. Objectif et Problématique
Comment mesurer et analyser en temps réel les conditions environnementales d'une salle de classe (UV, luminosité, température, humidité, pression) pour optimiser le confort thermique des occupants ? La démarche s'appuie sur un diagramme des exigences qui modélise notre problématique centrale.
┌──────────────────────────────────────────────────────────────┐
│ Sonde Météorologique SAE:204 │
│ Gestion thermique en salle de classe │
└──────────────────┬───────────────────────────────────────────┘
│
┌───────────┼────────────┐
▼ ▼ ▼
┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Acquisition │ │ Transmission │ │ Affichage │
│ des données │ │ sans fil │ │ des données │
│ (capteurs) │ │ (BLE) │ │ (M5Stack + │
│ │ │ │ │ Grafana) │
└──────┬───────┘ └──────────────┘ └─────────────────┘
│
┌────┴──────────────┐
▼ ▼
Mesurer UV Mesurer Temp.
& Luminosité Humidité & Pression
2. Matériel nécessaire
L'ensemble du matériel est fourni par l'IUT (kit environnement prêté), à l'exception du VPS utilisé pour le broker MQTT.
2× STM32 WB55 (Nucleo)
Microcontrôleur principal du projet. Il lit les capteurs Grove (UV + lumière) et émet les données via Bluetooth Low Energy sous le nom Sonde_V3. Bibliothèque STM32duinoBLE v1.4.1. Firmware BLE coprocesseur RF v16.12.0.27.
- ADC 12 bits (valeurs 0–4095)
- Broche UV :
PA0(capteur GUVA-S12D) - Broche lumière :
PA1(capteur Grove v1.2) - Upload via STM32CubeProgrammer (SWD)
Kit Environnement (prêté)
Ensemble de capteurs analogiques montés sur shield :
- Capteur UV Grove GUVA-S12D — sortie tension → indice UV 0–12 via table Seeed officielle
- Capteur de lumière Grove v1.2 — luminosité en pourcentage
- 2 câbles shield de connexion
Raspberry Pi 3B+
Passerelle BLE → MQTT. Il reçoit les données en Bluetooth Low Energy depuis la STM32 (via bleak) et les publie sur le broker Mosquitto du VPS (via paho-mqtt). Stocke également un historique CSV horodaté sur carte microSD 32 Go.
- OS : Raspberry Pi OS 64-bit Lite
- Python 3 + bleak + paho-mqtt
- Connecté via hotspot mobile (eduroam incompatible)
- Accès VPS via clé SSH ed25519
Afficheur 2Core M5Stack
Interface visuelle temps réel. Affiche l'indice UV et la luminosité. Passe en mode alerte si déconnecté du broker MQTT.
- Connexion Wi-Fi → broker Mosquitto VPS
- Abonnement au topic
sonde/meteo - Reconnexion automatique si perte réseau
- Interface designée et codée par Unsal
Infrastructure VPS + VMs
Un VPS Ionos (broker MQTT Mosquitto central) héberge le point de collecte des données. Quatre machines virtuelles KVM/QEMU tournent sur le réseau privé de l'IUT (10.144.x.x) :
- VM MariaDB — stockage SQL des mesures brutes
- VM InfluxDB — séries temporelles
- VM Grafana — dashboards temps réel (port 3000)
- VM Icinga2 — supervision réseau + IcingaWeb2
Stockage local
Carte microSD 32 Go insérée dans le Raspberry Pi pour la persistance locale des données en cas de coupure réseau.
- Fichiers CSV horodatés :
sonde_YYYY-MM-DD.csv - Répertoire :
./data_sonde/ - Publication simultanée sur MQTT et écriture CSV
3. Architecture technique — Flux de données
Les données traversent cinq couches depuis les capteurs physiques jusqu'aux dashboards de visualisation. Chaque étape a été testée et validée par le membre responsable.
┌─────────────────────────────────────────────────────────────────────┐
│ STM32 WB55 │
│ Capteurs : UV (GUVA-S12D) · Luminosité (Grove v1.2) │
│ ↓ Émission BLE (nom : "Sonde_V3", 2 caractéristiques GATT) │
└──────────────────────────────┬──────────────────────────────────────┘
│ Bluetooth Low Energy
┌──────────────────────────────▼──────────────────────────────────────┐
│ Raspberry Pi 3B+ │
│ Script ble-rpi.py (bleak) → lit les 2 chars GATT │
│ ↓ Publication MQTT (topic : sonde/meteo) │
│ ↓ Écriture CSV horodatée sur microSD 32 Go │
└──────────────────────────────┬──────────────────────────────────────┘
│ MQTT via réseau mobile / internet
┌──────────────────────────────▼──────────────────────────────────────┐
│ VPS Ionos — Broker Mosquitto │
│ Auth. par login/mot de passe · accès anonyme désactivé │
│ Script vps-bridge.py → monitoring temps réel en console │
│ ↓ Distribution aux VMs (réseau privé) │
└──────┬───────────────────────────────────────────────┬─────────────┘
│ │
┌──────▼──────────────┐ ┌──────────▼──────────────┐
│ VM MariaDB │ │ VM InfluxDB │
│ Stockage SQL brut │ │ Séries temporelles │
└──────┬──────────────┘ └──────────┬──────────────┘
└──────────────────┬────────────────────────────┘
│
┌────────▼────────┐ ┌─────────────────────────┐
│ VM Grafana │ │ M5Stack (Wi-Fi MQTT) │
│ Dashboards │ │ UV · Luminosité │
│ port :3000 │ │ Reconnexion auto │
└─────────────────┘ └─────────────────────────┘
│
┌────────▼────────┐
│ VM Icinga2 │
│ Supervision │
│ IcingaWeb2 │
└─────────────────┘
4. Code Source
Voici l'intégralité des scripts développés par l'équipe, dans leur version finale déposée sur HUBJ Teams le 11 juin 2026. Les données sensibles (identifiants, adresses réseau) ont été retirées.
// Projet : SAE 204 - Sonde Météo (Mode UV & Lumière)
#include <STM32duinoBLE.h>
#define PIN_A A0 // Capteur UV (GUVA-S12D)
#define PIN_B A1 // Capteur Lumière (Grove v1.2)
// ── Service BLE et 2 caractéristiques GATT ──────────────────────────
BLEService meteoService("19B10000-E8F2-537E-4F6C-D104768A1214");
BLEFloatCharacteristic uvCharacteristic ("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify);
BLEFloatCharacteristic lightCharacteristic("19B10002-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify);
// ── Table officielle Seeed GUVA-S12D : tension (mV) → indice UV ─────
int tensionVersUVIndex(float mV) {
if (mV < 50) return 0; else if (mV < 227) return 1;
else if (mV < 318) return 2; else if (mV < 408) return 3;
else if (mV < 503) return 4; else if (mV < 606) return 5;
else if (mV < 696) return 6; else if (mV < 795) return 7;
else if (mV < 881) return 8; else if (mV < 976) return 9;
else if (mV < 1079) return 10; else if (mV < 1170) return 11;
else return 12;
}
// ── Lecture lissée (moyenne sur N itérations) ────────────────────────
float lireMoyenne(int pin, int iterations) {
long somme = 0;
for (int i = 0; i < iterations; i++) {
somme += analogRead(pin);
delay(5);
}
return (float)somme / iterations;
}
void setup() {
Serial.begin(115200);
unsigned long debut = millis();
while (!Serial && millis() - debut < 3000);
Serial.println("\n=== SAE 204 Sonde V3 — Mode UV & Lumière ===");
analogReadResolution(12); // ADC 12 bits → 0 à 4095
pinMode(PIN_A, INPUT);
pinMode(PIN_B, INPUT);
// Initialisation BLE
if (!BLE.begin()) {
Serial.println("[ERREUR] BLE en panne !");
while (1);
}
BLE.setLocalName("Sonde_V3");
BLE.setAdvertisedService(meteoService);
meteoService.addCharacteristic(uvCharacteristic);
meteoService.addCharacteristic(lightCharacteristic);
BLE.addService(meteoService);
uvCharacteristic.writeValue(0.0);
lightCharacteristic.writeValue(0.0);
BLE.advertise();
Serial.println("[OK] BLE actif — En attente de connexion...");
}
void loop() {
BLEDevice central = BLE.central();
if (central) {
Serial.print("Connecté : ");
Serial.println(central.address());
while (central.connected()) {
float rawA = lireMoyenne(PIN_A, 10);
float rawB = lireMoyenne(PIN_B, 10);
float mV_A = rawA * (3300.0 / 4095.0);
float indiceUV = (float)tensionVersUVIndex(mV_A);
float lumPct = (rawB / 4095.0) * 100.0;
// Envoi BLE
uvCharacteristic.writeValue(indiceUV);
lightCharacteristic.writeValue(lumPct);
// Diagnostic série
Serial.println("─────────────────────────────────────────");
Serial.print("A0 brut: "); Serial.print(rawA, 0);
Serial.print(" | A1 brut: "); Serial.println(rawB, 0);
Serial.print("UV (A0): "); Serial.print(indiceUV, 0);
Serial.print(" | Lum (A1): "); Serial.print(lumPct, 1); Serial.println("%");
delay(1000);
}
Serial.println("Déconnecté.");
}
}
// Auteur : Unsal
// Projet : SAE 204 - Affichage Météo sur M5Core2 (Wi-Fi + MQTT VPS)
#include <M5Core2.h>
#include <WiFi.h>
#include <PubSubClient.h>
// --- Configuration Réseau Wi-Fi ---
const char* ssid = "VOTRE_SSID"; // Remplacer par votre réseau
const char* password = "VOTRE_PASSWORD"; // Remplacer par votre mot de passe
// --- Configuration MQTT (Mosquitto sur VPS) ---
const char* mqtt_server = "ADRESSE_VPS"; // IP du VPS Ionos
const int mqtt_port = 1883;
const char* mqtt_user = "sae204";
const char* mqtt_pass = "VOTRE_PASS"; // Mot de passe MQTT
// --- Topic MQTT ---
const char* topic_meteo = "sonde/meteo";
WiFiClient espClient;
PubSubClient client(espClient);
// --- Interface Graphique ---
void dessinerInterface() {
M5.Lcd.clear(BLACK);
M5.Lcd.setTextSize(2);
// Bandeau Titre
M5.Lcd.fillRect(0, 0, 320, 30, BLUE);
M5.Lcd.setTextColor(WHITE, BLUE);
M5.Lcd.setCursor(10, 5);
M5.Lcd.print("Sonde Meteo V3 - R&T");
// Labels fixes
M5.Lcd.setTextColor(YELLOW, BLACK);
M5.Lcd.setCursor(20, 80);
M5.Lcd.print("Indice UV :");
M5.Lcd.setTextColor(CYAN, BLACK);
M5.Lcd.setCursor(20, 140);
M5.Lcd.print("Luminosite :");
}
// --- Callback : déclenché à chaque message MQTT reçu ---
void callback(char* topic, byte* payload, unsigned int length) {
// Reconstruction du message texte
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Message recu [");
Serial.print(topic);
Serial.print("] : ");
Serial.println(message);
// Traitement uniquement sur le bon topic
if (String(topic) == topic_meteo) {
int indexVirgule = message.indexOf(',');
if (indexVirgule != -1) {
// Découpage "UV:4,LUM:36.3"
String partieUV = message.substring(0, indexVirgule);
String partieLum = message.substring(indexVirgule + 1);
partieUV.replace("UV:", "");
partieLum.replace("LUM:", "");
// Mise à jour de l'écran
M5.Lcd.fillRect(180, 80, 100, 30, BLACK);
M5.Lcd.setCursor(180, 80);
M5.Lcd.setTextColor(YELLOW, BLACK);
M5.Lcd.print(partieUV);
M5.Lcd.fillRect(180, 140, 100, 30, BLACK);
M5.Lcd.setCursor(180, 140);
M5.Lcd.setTextColor(CYAN, BLACK);
M5.Lcd.print(partieLum);
M5.Lcd.print(" %");
} else {
Serial.println("Format non reconnu (virgule manquante).");
}
}
}
// --- Reconnexion MQTT automatique ---
void reconnect() {
while (!client.connected()) {
Serial.print("Connexion au broker Mosquitto...");
M5.Lcd.fillRect(0, 210, 320, 30, BLACK);
M5.Lcd.setTextColor(RED, BLACK);
M5.Lcd.setCursor(10, 215);
M5.Lcd.print("MQTT Deconnecte...");
if (client.connect("M5Core2_sae204", mqtt_user, mqtt_pass)) {
Serial.println("Connecte !");
M5.Lcd.fillRect(0, 210, 320, 30, BLACK);
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.setCursor(10, 215);
M5.Lcd.print("MQTT Connecte (VPS) !");
client.subscribe(topic_meteo);
} else {
Serial.print("Echec, code : ");
Serial.print(client.state());
Serial.println(" → Nouvel essai dans 5s");
delay(5000);
}
}
}
void setup() {
M5.begin();
dessinerInterface();
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.setCursor(10, 215);
M5.Lcd.print("Connexion Wi-Fi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
M5.Lcd.fillRect(0, 210, 320, 30, BLACK);
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.setCursor(10, 215);
M5.Lcd.print("Wi-Fi OK !");
delay(1500);
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
void loop() {
M5.update();
if (!client.connected()) {
reconnect();
}
client.loop();
}
import asyncio
import struct
import paho.mqtt.client as mqtt
from bleak import BleakClient, BleakScanner
# ── Configuration BLE ────────────────────────────────────────────────
DEVICE_NAME = "Sonde_V3"
UV_CHAR_UUID = "19B10001-E8F2-537E-4F6C-D104768A1214"
LIGHT_CHAR_UUID = "19B10002-E8F2-537E-4F6C-D104768A1214"
# ── Configuration MQTT ───────────────────────────────────────────────
MQTT_BROKER = "localhost" # IP du VPS Ionos en prod
MQTT_PORT = 1883
try:
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
except AttributeError:
mqtt_client = mqtt.Client()
async def main():
try:
mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60)
mqtt_client.loop_start()
print(f"✅ Connecté au broker MQTT ({MQTT_BROKER})")
except Exception as e:
print(f"❌ Erreur MQTT : {e}")
return
print(f"🔍 Recherche de la sonde BLE '{DEVICE_NAME}'...")
devices = await BleakScanner.discover(timeout=10.0)
target_device = None
for d in devices:
if d.name == DEVICE_NAME:
target_device = d
break
if not target_device:
print("❌ Sonde introuvable.")
mqtt_client.loop_stop()
return
print(f"✅ Sonde trouvée ! Connexion BLE en cours...")
async with BleakClient(target_device, timeout=20.0) as client:
print("🚀 Connecté ! Transfert des données vers Mosquitto...")
while True:
try:
# Lecture des 2 caractéristiques GATT
uv_bytes = await client.read_gatt_char(UV_CHAR_UUID)
light_bytes = await client.read_gatt_char(LIGHT_CHAR_UUID)
# Décodage float little-endian
uv_val = struct.unpack('<f', uv_bytes)[0]
light_val = struct.unpack('<f', light_bytes)[0]
# Formatage payload → "UV:4,LUM:36.3"
payload = f"UV:{uv_val:.0f},LUM:{light_val:.1f}"
mqtt_client.publish("sonde/meteo", payload)
print(f"[MQTT ✅] {payload}")
except Exception as e:
print(f"[⚠] Erreur lecture BLE : {e}")
break
await asyncio.sleep(1)
asyncio.run(main())
#!/usr/bin/env python3
"""
SAE 204 — Monitoring VPS Mosquitto
Affiche en temps réel les données reçues du RPi.
Jonathan
"""
import paho.mqtt.client as mqtt
from datetime import datetime
MQTT_HOST = "localhost"
MQTT_PORT = 1883
MQTT_TOPIC = "sonde/meteo"
# Identifiants définis via variables d'environnement sur le VPS
compteur = 0
def on_connect(client, userdata, connect_flags, reason_code, properties=None):
if reason_code == 0:
print("╔══════════════════════════════════════════════════╗")
print("║ SAE204 — Monitoring VPS Mosquitto ║")
print("╚══════════════════════════════════════════════════╝")
print(f"[✅] Connecté au broker ({MQTT_HOST}:{MQTT_PORT})")
client.subscribe(MQTT_TOPIC)
print(f"[📡] En écoute sur : {MQTT_TOPIC}")
print("[⏳] En attente des données du RPi...\n")
else:
print(f"[❌] Erreur connexion : {reason_code}")
def on_message(client, userdata, msg):
global compteur
compteur += 1
payload = msg.payload.decode("utf-8")
ts = datetime.now().strftime("%H:%M:%S")
try:
parties = dict(p.split(":") for p in payload.split(","))
uv = parties.get("UV", "—")
lum = parties.get("LUM", "—")
print(f"┌─ [{ts}] Message #{compteur} reçu du RPi ──────────────")
print(f"│ 📦 Payload brut : {payload}")
print(f"│")
print(f"│ ☀️ UV Index : {uv}")
print(f"│ 💡 Luminosité : {lum}%")
print(f"│")
print(f"│ → Dispatché aux VMs (MariaDB, InfluxDB) ✅")
print(f"│ → Dispatché au M5Stack (WiFi MQTT) ✅")
print(f"└───────────────────────────────────────────────────\n")
except Exception as e:
print(f"[⚠] Données mal formées : {payload} ({e})")
try:
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
except AttributeError:
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_HOST, MQTT_PORT, 60)
client.loop_forever()
5. Répartition des Rôles
Chaque membre est responsable d'un domaine technique précis, couvrant à la fois le volet Programmer et Administrer de la SAE.
| Membre | Rôle | Responsabilités détaillées |
|---|---|---|
| Helina | Expert Hardware & Acquisition | Câblage propre des capteurs Grove (UV GUVA-S12D + lumière v1.2) sur le WB55. Lecture analogique via ADC 12 bits (PA0/PA1). Formatage des données pour l'envoi BLE. Mise en place, installation et configuration de la VM Grafana (visualisation, dashboards InfluxDB + MariaDB, port 3000, IP statique, VNC). |
| Mohamed-Bedis | Spécialiste Communication BLE | Configuration du protocole Bluetooth Low Energy sur le WB55 (bibliothèque STM32duinoBLE v1.4.1, firmware RF v16.12.0.27). Définition du service GATT et des 5 caractéristiques (UV, lumière, humidité, pression, température). Vérification de la réception côté Raspberry Pi et M5Stack. |
| Jonathan | Maître Infrastructure & Stockage |
Configuration Raspberry Pi 3B+ (OS, réseau, accès VPS). Adaptation du script BLE de Bédis pour le RPi (asyncio, gestion erreurs, mode démo). Écriture CSV horodatée sur microSD. VPS Ionos — broker Mosquitto (auth. activée, accès anonyme désactivé). VM Icinga2 (supervision réseau, IcingaWeb2). Script vps-bridge.py de monitoring temps réel. Sauvegardes rsync.
|
| Unsal | Designer UI / Affichage |
Programmation de l'afficheur 2Core M5Stack. Interface de visualisation claire et lisible des données en temps réel. Mode alerte (fond rouge) si température > 30°C. Contribution au code STM32 final (temp2.ino).
|
6. Journal d'Avancement
Suivi semaine par semaine des étapes clés du projet, avec les problèmes rencontrés et les solutions apportées.
Lancement du projet & répartition des rôles
- Réunion d'équipe : validation du sujet Sonde Météorologique, répartition des 4 rôles.
- Récupération du matériel IUT : WB55, M5Stack 2Core, Raspberry Pi 3B+, capteurs Grove, microSD 32 Go.
- Lecture de la documentation technique du WB55 et des bibliothèques Grove.
- Rédaction du diagramme des exigences (analyse thermique en salle).
- [Jonathan] Flash du Raspberry Pi OS 64-bit Lite sur microSD via Raspberry Pi Imager. Activation SSH.
- [Jonathan] Configuration réseau RPi via hotspot mobile (eduroam WPA2-Enterprise incompatible). Accès SSH VPS via clé ed25519.
- [Jonathan] Installation Python 3 +
bleak+paho-mqttsur le RPi. - Mise en place du journal de projet sur Benelos par Jonathan.
Configuration Arduino IDE & premiers tests capteurs
- Installation d'Arduino IDE sur macOS (VM Parallels Windows) + support STM32 WB55 via STM32duino.
- Premiers tests de lecture des capteurs Grove — problème de broches inversées (PA0/PA1) résolu.
- Correction du coefficient UV : passage à la table officielle Seeed GUVA-S12D (résultat conforme UV 4).
- Résolution problème upload ST-LINK : configuration STM32CubeProgrammer (SWD) + passage USB à Windows via Parallels.
- Installation bibliothèque STM32duinoBLE v1.4.1. Vérification firmware BLE RF → v16.12.0.27 déjà présent ✅
Première tentative Arduino IDE · Création du projet HUBJ
- [Jonathan — 20/05] Tentative : Arduino IDE ne trouve pas la carte. Abandon de cette approche, bascule vers STM32CubeProgrammer (SWD) uniquement.
- [Jonathan — 19/05] Création du projet "SAE204" sur Skynium HUBJ Teams.
- Définition de l'architecture complète du volet Administrer : VPS Ionos, VMs MariaDB/InfluxDB/Grafana/Icinga2.
- Identification du problème eduroam → solution VPS Ionos comme broker MQTT central.
Intégration BLE complète · Validation de la chaîne MQTT
- [Unsal — 01/06] Configuration indice UV et température sur la STM32 — dépôt du code sur HUBJ.
- [Jonathan — 02/06] Réception du script BLE de Bédis. Adaptation pour RPi 3B+ : correction asyncio, gestion erreurs, ajout mode
--demo. - [Jonathan — 02/06] Validation chaîne complète en mode démo : données simulées → CSV horodaté généré sur microSD ✅
- [Jonathan — 02/06] Test MQTT : publish depuis RPi → subscribe sur VPS Ionos Mosquitto → données reçues en temps réel ✅
- Code affichage M5Stack finalisé par Unsal (interface temps réel + alertes rouge si T° > 30°C).
- [Jonathan — 05/06] Rédaction note de préparation à l'oral (sommaire, ODD, démonstration).
Codes finaux · Documentation wiki
- [Jonathan — 08/06] Dépôt de
vps-bridge.py(monitoring Mosquitto en temps réel). - [Unsal — 08/06] Finalisation de
ble-rpi.py. - [Unsal — 09/06] Dépôt du code STM32
temp2.ino(Sonde_V3). - [Jonathan — 09/06] Ajustements finaux sur les scripts STM32 et
vps-bridge.py. - Mise à jour du wiki Benelos — documentation complète des parties Programmer et Administrer.
- [10/06/2026] Rapport PDF généré et diffusé à tous les membres via HUBJ.
Soutenance · Livraison finale · Projet terminé ✅
- [Unsal — 11/06 matin] Dépôt de
m5stack.ino— version finale de l'afficheur M5Core2 (Wi-Fi + MQTT VPS, reconnexion automatique, interface UV + Luminosité). - [Unsal — 11/06 matin] Mise à jour finale de
helina.ino— version propre avec uniquement UV et Luminosité via BLE. - [Jonathan — 11/06] Suppression de
temp2.ino(remplacé parhelina.inoversion finale). - [Helina & Unsal — 11/06] Réalisation des wikis Benelos et Trappist — documentation finale partagée.
- [11/06/2026] Soutenance orale du projet SAE204 — présentation de 30 minutes + démonstration.
- [Jonathan — 11/06 11:42] Projet marqué comme Terminé sur HUBJ Teams — 8/8 tâches à 100%.
7. Difficultés rencontrées & Solutions
Un projet d'intégration réel rencontre toujours des obstacles. Voici les principaux et comment l'équipe les a surmontés.
Le Board part number affichait "Generic WB15CCUx" — l'upload échouait avec "No debug probe detected".
WPA2-Enterprise de l'IUT ne peut pas être configuré sur RPi OS Lite sans interface graphique.
Les premières lectures donnaient l'UV sur la broche de lumière et vice-versa.
#define dans le code.Le capteur de température/humidité nécessite un temps de chauffe avant d'être stable.
delay(2000) après l'Enable() dans le setup + vérification de l'ID (0xBC attendu).La base IDO était vide, le schéma n'avait pas été importé, et le mot de passe n'était pas au bon format bcrypt.
ido-mysql.conf, injection SQL directe du hash bcrypt correct.Développement modulaire en parallèle → incompatibilités lors de la mise en commun des modules.
8. État des tâches (HUBJ Teams)
Projet terminé le 11 juin 2026 — 8/8 tâches à 100%.
9. L'Équipe du Projet
Unsal
Designer UI / Affichage
M5Stack · STM32 (temp2.ino)
Helina
Hardware & Acquisition
Capteurs Grove · VM Grafana
Mohamed-Bedis
Communication BLE
STM32duinoBLE · GATT
Jonathan
Infrastructure & Stockage
RPi · VPS Mosquitto · Icinga2