Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Visualiseur LED temps réel des battements cardiaques piloté par ECG

Composants et fournitures

Composant Quantité
Périphérique uECG 1
Arduino Nano R3 1
Adafruit NeoPixel Ring : WS2812 5050 RGB LED 1
Batterie Li-Ion 1000 mAh 1

Outils nécessaires

À propos du projet

Depuis des années, je voulais créer quelque chose avec des LEDs qui clignote au rythme de mes battements cardiaques (pas seulement quand je reste parfaitement immobile, en ratant un battement ici ou là). Cela s'est avéré étonnamment difficile ; j'ai essayé et échoué pendant des ans. Mais plus maintenant !

Tout le travail lourd est fait par uECG – un petit dispositif ECG portable, open source, doté d'une broche de sortie compatible Arduino (cette broche passe haut/bas à chaque battement). Traiter ces états de broche est bien plus simple que de traiter le signal ECG brut, et j'ai cherché à en tirer le maximum.

Mise à jour : vous pourriez vouloir consulter la 2e itération de ce projet, qui reçoit les données par liaison radio.

1. Schéma

Puisque nous ne travaillons qu'avec des signaux numériques, c'est très simple. Mais en tant que dispositif portable, ce serait bien plus fiable (et compact) si la plupart des connexions sont soudées – pour un test rapide ce n'est pas nécessaire, mais si vous comptez le porter lors d'activités intenses, je le recommande vivement.

Visualiseur LED temps réel des battements cardiaques piloté par ECG

J'ai utilisé la batterie LiPo directement en entrée 5V – pas d'erreur : si connectée à Vin, ça ne marche pas fiablement (régulateur de tension sur Vin introduit une chute de tension qu'on ne peut pas se permettre ici). L'Arduino est stable tant que la tension d'entrée ne descend pas sous 3,4 V. Une LiPo pleinement chargée démarre à 4,2 V et n'atteint 3,4 V qu'à ~15 % de charge restante. Avec toute batterie > ~200 mAh, on obtient une autonomie correcte. Pensez à connecter la batterie via un connecteur pour pouvoir la recharger.

2. Code

Le programme fonctionne simplement : il lit en permanence la broche D3, et à chaque changement d'état, enregistre l'instant dans un tableau de 20 éléments. La différence entre le premier et le dernier élément, divisée par 20, donne le temps moyen par battement (ms). En divisant 60 000 ms (1 minute) par cette valeur, on obtient les BPM. Le nombre d'éléments du tableau est ajustable : plus petit = réponse plus rapide mais moins stable ; plus grand = plus stable mais réponse plus lente aux variations rapides de BPM.

Les BPM sont mappés en couleur (bleu → vert → jaune → rose → rouge quand BPM passe de bas à haut) et en nombre de LEDs allumées : 80 BPM = 8 segments, 110 BPM = 11, etc. (échelle ajustable dans le code).

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
// Broche DI de l'anneau LED
#define PIN 11
// Nombre de pixels dans l'anneau
#define NUMPIXELS 16
// Broche d'entrée pour uECG
int in_pin = 3;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();
  pinMode(in_pin, INPUT);
  digitalWrite(in_pin, 1); // Activer PULLUP : critique, uECG n'a pas de pull-up interne
}

#define BEAT_HIST 20
long beats[BEAT_HIST];

void push_beat(long ms) {
  for(int x = 0; x < BEAT_HIST-1; x++) beats[x] = beats[x+1];
  beats[BEAT_HIST-1] = ms;
}

int get_bpm() {
  long dt = beats[BEAT_HIST-1] - beats[0];
  long bpm = BEAT_HIST * 60000 / dt;
  return bpm;
}

long last_pix_upd = 0;
int prev_in_state = 0;

void loop() {
  long ms = millis();
  int in_state = digitalRead(in_pin); // 1 = pas de battement, 0 = battement
  if (in_state == 1 && prev_in_state == 0) { push_beat(ms); }
  prev_in_state = in_state;
  if (ms - last_pix_upd > 10) {
    int r, g, b;
    last_pix_upd = ms;
    int bpm = get_bpm();
    int max_bright = 120; // luminosité max (max 255, mais pas toujours au max)
    float dd = 20; // variation BPM entre tons de couleur
    float t1 = 90, t2, t3, t4; // t1 = BPM « base », en-dessous = bleu
    t2 = t1 + dd; t3 = t2 + dd; t4 = t3 + dd;
    if (bpm < t1) { r = 0; g = 0; b = max_bright; }
    else if (bpm < t2) { r = 0; g = max_bright * (bpm-t1)/dd; b = max_bright - g; }
    else if (bpm < t3) { r = max_bright * (bpm-t2)/dd; g = max_bright - r; b = r/4; }
    else if (bpm < t4) { r = max_bright; g = 0; b = max_bright/2 - max_bright * (bpm-t3)/(2*dd); }
    else { r = max_bright; g = 0; b = 0; }
    if (in_state) { r *= 0.25; g *= 0.25; b *= 0.25; } // hors battement = 1/4 intensité
    int on_pixels = (bpm + 5) / 10; // nb LEDs : 60 BPM = 6 LEDs, 120 = 12, etc.
    for (int i=0; i

3. Assemblage en version portable

Il est pratique de placer l'Arduino à l'intérieur de l'anneau – les tailles correspondent presque parfaitement. La batterie tient à côté. N'oubliez pas que l'uECG se place sur la poitrine – il faut un fil avec connecteurs : on place d'abord le capteur, puis on enfile le tee-shirt avec les autres composants, puis on branche le connecteur. Sinon c'est très peu pratique à mettre – croyez-moi, j'ai essayé !

Visualiseur LED temps réel des battements cardiaques piloté par ECG
Visualiseur LED temps réel des battements cardiaques piloté par ECG
Visualiseur LED temps réel des battements cardiaques piloté par ECG

Si tout est bien fait, dans les 30 secondes après branchement, ça clignote et indique les BPM.

4. Tests sur le terrain

Testé en marchant et en courant : pendant la course, la batterie rebondit sur le capteur ECG, faussant les lectures. En déplaçant le tout, le fil reliant uECG à l'Arduino s'est révélé trop court et tirait le capteur à chaque pas, faussant encore les lectures. Globalement, battements fiables seulement en marchant et immobile, pas en courant – mais je pense pouvoir améliorer. Le capteur seul, avec un autre tee-shirt, affichait correctement les BPM en course (vérifié via son application).

D'ailleurs, les LEDs sur la poitrine peuvent sembler cool mais sont pratiquement inutiles : regarder en bas pour vérifier son pouls est très inconfortable. Prochaine itération : bracelet poignet pour indiquer les battements.

P.S. Si uECG vous intéresse, consultez sa page Hackaday : détails techniques, PCB, discussions, logs de projet.

Code

  • uECG_pixel_ring.ino

uECG_pixel_ring.ino (Arduino)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 11
#define NUMPIXELS 16
int in_pin = 3;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();
  pinMode(in_pin, INPUT);
  digitalWrite(in_pin, 1);
}

#define BEAT_HIST 20
long beats[BEAT_HIST];

void push_beat(long ms) {
  for(int x = 0; x < BEAT_HIST-1; x++) beats[x] = beats[x+1];
  beats[BEAT_HIST-1] = ms;
}

int get_bpm() {
  long dt = beats[BEAT_HIST-1] - beats[0];
  long bpm = BEAT_HIST * 60000 / dt;
  return bpm;
}

long last_pix_upd = 0;
int prev_in_state = 0;

void loop() {
  long ms = millis();
  int in_state = digitalRead(in_pin);
  if (in_state == 1 && prev_in_state == 0) push_beat(ms);
  prev_in_state = in_state;
  if (ms - last_pix_upd > 10) {
    int r, g, b;
    last_pix_upd = ms;
    int bpm = get_bpm();
    int max_bright = 120;
    float dd = 20;
    float t1 = 90, t2, t3, t4;
    t2 = t1 + dd; t3 = t2 + dd; t4 = t3 + dd;
    if (bpm < t1) { r = 0; g = 0; b = max_bright; }
    else if (bpm < t2) { r = 0; g = max_bright * (bpm-t1)/dd; b = max_bright - g; }
    else if (bpm < t3) { r = max_bright * (bpm-t2)/dd; g = max_bright - r; b = r/4; }
    else if (bpm < t4) { r = max_bright; g = 0; b = max_bright/2 - max_bright * (bpm-t3)/(2*dd); }
    else { r = max_bright; g = 0; b = 0; }
    if (in_state) { r *= 0.25; g *= 0.25; b *= 0.25; }
    int on_pixels = (bpm + 5) / 10;
    for (int i=0; i

Schémas

Visualiseur LED temps réel des battements cardiaques piloté par ECG

Processus de fabrication

  1. Défibrillateur externe : histoire, conception et fabrication
  2. Le rouleau à pâtisserie : des origines étrusques à l'artisanat moderne
  3. Cœur artificiel : technologie, histoire et perspectives futures
  4. Contrôler une LED avec un capteur de mouvement PIR sur Raspberry Pi
  5. Surveiller la température de votre maison avec un tableau de bord Raspberry Pi
  6. Système de surveillance cardiaque à distance avec alertes AWS IoT
  7. Surveillance cardiaque sans contact via enceintes intelligentes : un système révolutionnaire
  8. Tatouage électronique à base de graphène : surveillance cardiaque continue et précise sur de longues périodes
  9. Articulation rotule (knuckle joint) : conception, applications, avantages et limites