Home Trainer Ouverture Critique - ayaabidghozy13/Syst-me-Embarqu-Biom-dicaux GitHub Wiki
Cette page prend du recul sur le prototype : comment il s'intègre dans le projet global Home Trainer, quelles améliorations sont possibles, et quelles sont ses limites.
Le Home Trainer est un vélo d'appartement instrumenté. Notre montage peut en devenir le module « cardio » :
| Fonction CardioTrack | Usage sur le Home Trainer |
|---|---|
| Badge RFID | Identifier le cycliste et charger son profil (âge, FC max, historique) |
| Bouton start/stop | Démarrer et terminer une séance d'entraînement |
| BPM estimé | Afficher la fréquence cardiaque et la zone d'effort en temps réel |
| Seuil d'alarme | Alerter si la FC dépasse la FC max du cycliste (ex. formule 220 − âge) |
| Lampe / buzzer | Signal visuel et sonore pour ralentir |
| Messages MQTT | S'intégrer au même broker que les autres modules (vitesse, cadence, puissance, résistance) |
flowchart LR
CARDIO["Module cardio<br/>(CardioTrack)"] -- "fréquence cardiaque" --> BROKER(("Broker MQTT<br/>Home Trainer"))
CAPT["Capteurs vélo<br/>(cadence, vitesse, puissance)"] --> BROKER
BROKER --> NR["Node-RED<br/>(logique de séance)"]
NR -- "consigne de résistance" --> FREIN["Frein / résistance<br/>du vélo"]
NR --> DASH["Dashboard<br/>de séance"]
Le scénario visé est une séance guidée par la fréquence cardiaque : Node-RED compare la FC à la zone cible du cycliste et ajuste automatiquement la résistance du vélo.
- Mesure pendant l'effort. Pédaler crée beaucoup d'artefacts de mouvement sur un ECG à électrodes adhésives. Nous l'avons déjà constaté à l'arrêt : le moindre mouvement des câbles perturbe le signal. Il faudra une ceinture thoracique avec électrodes textiles, ou remplacer l'AD8232 par une ceinture cardio Bluetooth (BLE) ou un capteur optique (PPG).
- Fréquence d'échantillonnage. 50 Hz suffisent pour un BPM approximatif, mais un ECG exploitable demande 250 à 500 Hz. À cette cadence, envoyer un message MQTT par échantillon n'est plus possible : il faudra envoyer les échantillons par paquets (ex. 25 échantillons par message) ou calculer le BPM directement sur l'Arduino.
-
Format des topics. Nos topics
health/...sont trop génériques. Ils devront suivre la convention commune du projet, par exemplehometrainer/<id_velo>/cardio/hr, avec des messages JSON contenant l'identifiant du cycliste et un horodatage. -
Identification. L'UID du badge devra être associé à un profil utilisateur pour retrouver l'âge, la FC max et les zones d'entraînement. Aujourd'hui, le dashboard affiche seulement l'UID brut (ex.
AC:C9:6B:04). - Bouton physique. Le bouton start/stop pourrait être partagé avec le reste du vélo, ou remplacé par un démarrage automatique dès que le pédalage commence.
Traitement du signal
- Filtrer le signal ECG (passe-bande 0,5–40 Hz, réjection 50 Hz du secteur) avant la détection des pics.
- Remplacer notre seuil fixe par un algorithme de détection QRS reconnu, comme Pan-Tompkins.
- Lisser le BPM (moyenne glissante sur 5 à 8 battements) pour éviter les valeurs aberrantes qui déclenchent l'alarme à tort.
- Calibrer le seuil automatiquement au début de chaque session.
Simplifier le flow Node-RED
- Fusionner les 3 nœuds MQTT de la carte patient avec ceux déjà utilisés par le reste du flow, au lieu de s'abonner deux fois aux mêmes topics.
- Remplacer les nombreux nœuds inject d'initialisation (« Initial badge », « Initial alarm state », etc.) par une seule fonction d'initialisation.
- Regrouper la logique de session (badge, bouton, état) dans une seule fonction, au lieu de la répartir entre plusieurs nœuds qui partagent le contexte
flow. - Utiliser des link nodes et des groupes pour rendre le flow plus lisible.
Exploiter davantage le matériel
- Utiliser la matrice LED intégrée à l'UNO R4 WiFi pour afficher un cœur qui bat ou l'état de la session, sans dashboard.
- Afficher le nom du patient associé à son badge sur le dashboard, plutôt que l'UID.
- Enregistrer chaque session (UID, date, durée, BPM min/moyen/max) pour suivre l'historique de chaque patient.
Défis à relever
- Obtenir un signal fiable malgré les mouvements et les interférences.
- Garantir la confidentialité des données de santé.
-
Prise en main rapide de Node-RED. Les cours ayant été accélérés, nous avons dû nous adapter très rapidement à Node-RED et au Dashboard 2.0. Il a fallu apprendre en peu de temps les nœuds function , le contexte
flow, et le nœud ui-template pour le bandeau et la carte patient. - Mise en page du dashboard. L'ordre et la largeur des groupes ne se mettaient pas toujours à jour après un import. Nous avons dû les régler à la main dans l'onglet Dashboard 2.0.
- Synchronisation Arduino / Node-RED. La carte patient restait sur « Aucun patient » alors que le badge était bien détecté. Nous avons résolu le problème en la resynchronisant avec le heartbeat envoyé par l'Arduino toutes les 2 s.
- Logique du bouton. Dans la première version, l'ECG était envoyé en continu dès le démarrage. Nous avons dû repenser le programme en machine à états (badge → bouton → acquisition) pour que la mesure ne démarre qu'après identification.
- Signal ECG saturé. Sur nos captures réelles, le signal alterne brutalement entre ~20 et ~700 (ADC) au lieu de montrer des complexes QRS nets. Cela vient de la saturation de l'AD8232 et du contact des électrodes. L'algorithme compte alors ces fronts comme des battements, ce qui donne des BPM faux (ex. 145 BPM).
- La machine à états rend l'utilisation claire : impossible de lancer une mesure sans patient identifié.
- Le firmware est entièrement non bloquant et se reconnecte seul après une coupure Wi-Fi ou MQTT.
- L'état de connexion est fiable grâce au heartbeat et au Last Will.
- Le dashboard est lisible et réinitialise tout proprement à la fin d'une session.
| Limite | Conséquence |
|---|---|
| Échantillonnage à 50 Hz | Les pics R sont mal résolus : le BPM est approximatif et l'ECG affiché est déformé (visible sur le graphe). |
| Un message MQTT par échantillon | 50 messages par seconde : charge réseau inutile, et la perte d'un message crée un trou dans le signal. |
BPM calculé avec Date.now() côté Node-RED |
Le BPM dépend de l'heure d'arrivée des messages, pas de l'heure de mesure. La latence réseau fausse les intervalles. Il aurait fallu utiliser le champ time envoyé par l'Arduino. |
| Seuil de détection fixe (18) | Il doit être réajusté selon la personne et le placement des électrodes. |
| Flow Node-RED trop chargé | Beaucoup de nœuds et de fils croisés : difficile à relire et à modifier pour un autre étudiant. |
| Broker public partagé | D'autres groupes utilisant des topics health/... pourraient perturber notre système. |
| UID RFID non vérifié | Tout badge est accepté : il n'y a pas de liste de patients autorisés. |
| Pas de stockage | Les données disparaissent à la fin de la session. |
| Alimentation par USB | Le patient est relié électriquement à un ordinateur branché sur le secteur. Pour un usage réel, une alimentation isolée (batterie) est indispensable. |
- Calculer le BPM sur l'Arduino et n'envoyer que le BPM (1 message par seconde) et des paquets d'ECG, pour une mesure plus précise et moins de trafic.
- Concevoir le flow Node-RED plus simplement dès le départ, avec moins de nœuds et une seule fonction pour la logique de session.
- Utiliser des topics plus spécifiques (ex.
cardiotrack/groupeX/...) pour éviter les conflits sur le broker public, et prévoir une convention compatible avec le projet Home Trainer. - Tester le signal ECG plus tôt pour calibrer le capteur avant de développer le dashboard.