bunex-industries

Cardio Fréquencemètre

Application interactive et ludique de mesure du rythme cardiaque par pléthysmographie, embarqué sur Raspberry Pi 3. Projet développé pour la Fondation de l'avenir

Description du projet

L'idée est d'inviter le public à réaliser deux activités physiques d'intensité croissante et de mesurer l'évolution de leur fréquence cardiaque (FC) par rapport à leur FC au repos. Leur âge leur est demandé afin d'estimer une FC max théorique selon la formule :

$$FC max = 0.8 * (220- age)$$

La mesure des battements de coeur est faite par un procédé optique suivant le principe de la Pléthysmographie : la modification de la réflectance et de la transmittance des tissus selon l'afflux de sang et sa teneur en oxygène.

Installation du Raspberry Pi 3

Après avoir remplacé une micro SD Samsung 8 Go déclarée défectueuse suite à d'incessantes erreurs de "file check" par une mirco SD SanDisk de qualité, j'ai installé NOOBS 1.9.2 sans problème.

J'ai utilisé le logiciel ApplePi-Baker qui est bien pratique pour préparer la carte mais aussi faire des images disques de sauvegarde.

SSH, SFTP sont lancés au démarrage par défaut dans cette version de NOOBS. J'ai ajouté le lancement d'une instance de tightvncserver afin de prendre la main à distance avec un client VNC (simplissime depuis un Mac).

J'ai ensuite installé l'IDE Arduino, Google Chromium et enfin NodeJS.

Configuration en point d'accès WIFI

Le RPI3 est équipé d'une puce combinée WIFI-Bluetooth. Par défaut Raspbian ne donne pas de quoi créer un réseau WIFI (facilement, via le GUI). J'ai suivi ce tutoriel qui a parfaitement fonctionné.

Le RPI3 ouvre donc un réseau WIFI dont il est le routeur et distribue l'accès Internet éventuellement reçu par ethernet vers les machines WIFI connectées.

J'ai ajouté quelques actions comme configurer le routage des requêtes HTTP (80) vers le port 3000 (nécessaire dans notre application) et enrichi le fichier /etc/hosts pour donner un nom de domaine à l'application Web locale servie par NodeJS.

L'application Cardio - NodeJS

Cette application exploite les modules suivants :

Elle sert deux pages : le moniteur et le contrôleur.

Le moniteur affiche les écrans pour le public (information, diagramme de mesures, compte à rebours, résultats...). Cette page web est lancée en mode kiosk (plein écran) et reste constamment en connexion avec le serveur via un Web socket. Elle reçoit notamment les données en temps réel issues du capteur et transmises par l'Arduino. (En fait c'est le serveur NodeJS qui reçoit les données via serialport. Il les transfert par Web socket à la page du moniteur).

L'utilisateur n'interagit pas directement avec cette page (pas de souris ni de clavier). C'est l'animateur qui pilote le déroulement du jeu via la page du contrôleur ouverte sur son smartphone (connecté au réseau Wifi créé par le RPI3). Le smartphone devenant ainsi une télécommande.

Détails sur le capteur et l'électronique associée

Le capteur en lui-même est un CNY 70. Il est constitué une LED infra-rouge, d'un photo-transistor infra-rouge et d'un filtre qui atténue la lumière visible. C'est un capteur optique en réflexion utilisé pour la détection, notamment dans les photocopieurs. Sa distance usuelle de détection se situe entre 2 et 5 mm.

Dans notre application, le doigt sera collé au capteur. Les IR vont se propager dans 1 à 2 mm de tissus et le phototransistor va percevoir les IR diffusés.

Le signal brut du capteur sera ensuite filtré 2 fois autour de la bande des fréquences cardiaques humaines (grosso-modo entre 0.5 et 4 Hz) et amplifié. Il sera ensuite numérisé 100x par secondes dans l'Arduino et transmis en série via l'USB.

J'ai préféré utiliser un Arduino plutôt que les ports du GPIO car ils ne sont pas dotés de convertisseur analogique numérique. Cela aurait pu être réalisé par un composant externe mais Il y aurait aussi eu la question des tensions 5.0V vs. 3.3V. L'un dans l'autre l'Arduino règle beaucoup de choses et apporte des avantages pour un coût (argent, temps) minimal.

Extraction de la valeur en BPM. Lutte contre le bruit

Le filtre électronique en lui-même met quelques secondes à "accrocher" les battements de coeur. Il émet des signaux erratiques sinon.

Ensuite, les mouvements du candidats, de son doigt sur le capteur, sa respiration, etc influencent défavorablement les lectures.

100x par seconde, le système compare l'amplitude du signal à un seuil. Ce seuil est dépassé lors de la détection d'un battement de coeur. Néanmoins, il est aussi dépassé aléatoirement par les divers bruits associés à la mesure en conditions réelles.

On peut tenir une liste des x dernières dates de dépassement de seuil, faire une moyenne des intervalles temporels, etc.

Si le signal est reçu "5 sur 5" (pas de bruit, le filtre a accroché) pendant au moins quelques battements réguliers de coeur, une valeur en BPM fiable peut-être déterminée.

Pour se protéger contre le bruit, on peut exclure du calcul de la moyenne les BPM non réalistes.

Mais jusqu'ici, la meilleure approche que j'ai pu trouver jusqu'ici, est de calculer quelque chose comme la "moyenne relative des écarts par rapport à la moyenne" sur une série de quelques intervalles "glissants". C'est la variance. Si cette variance est faible, les mesures sont sans doute justes, si elle est élevée, la mesure est mauvaise ou le filtre n'a pas accroché.

On observe que la variance descend à une valeur très faible lorsque la mesure est stable. Elle augmente aussitôt et fortement sinon ce qui permet de discriminer très efficacement le signal par rapport au bruit.

Suites

Étudier ce qui peut être fait avec le GPIO (usage de la librairie PIGPIO, éventuellement avec NodeJs via ce node-module?), s'initier à l'électronique 3.3V, à la basse consommation en général car il est vraisemblable de faire fonctionner ce dispositif sur batterie.

Il y a aussi sans doute la possibilité d'acquérir le signal par le jack audio et Web audio API (FSK ?). L'Arduino deviendrait superflu, le dispositif complet serait nettement moins cher, moins gourmand en énergie et plus compact !