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

Moniteur de fréquence cardiaque (portable et sans fil avec ECG)

Composants et fournitures

appareil uECG
Pour mesurer réellement le BPM. Il peut envoyer des données via le protocole compatible nRF24
× 1
Arduino Nano R3
× 1
Module nRF24 (Générique)
N'importe quel module fonctionnerait ici. Obligatoire pour recevoir les données BPM de uECG
× 1
Anneau Adafruit NeoPixel :WS2812 5050 LED RVB
× 1
Batterie LiPo
Toute batterie d'une capacité de plus de 200 mAh
× 1

Outils et machines nécessaires

Fer à souder (générique)

À propos de ce projet

Il s'agit d'une deuxième itération de mon projet de surveillance cardiaque, le précédent montrait des battements cardiaques sur une poitrine et était connecté à uECG via un fil. Cela a l'air cool, mais n'est pas du tout pratique - vous ne pouvez pas voir exactement combien de LED sont actuellement allumées, c'est hors de votre champ de vision normal, et le fil qui le connecte à l'appareil uECG crée beaucoup de problèmes pour le capteur lui-même , donc cela ne fonctionne pas lorsque vous exécutez.

Cette version résout tous ces problèmes :elle se porte au poignet, vous pouvez donc la voir tout en gardant les yeux sur la route, et elle est sans fil, donc pas de distorsion des lectures, elle fonctionne vraiment pour courir et vous permet de suivre la charge cardiaque.

1. Composants

Comme dans le projet précédent, tout le travail est effectué par uECG - il mesure les données et calcule le BPM à bord. Mais aussi, lorsqu'il passe en mode lien direct, il envoie toutes ces informations (ainsi que les données ECG haute résolution, que nous n'utilisons pas ici) via un protocole radio compatible avec la puce générique nRF24. Le deuxième composant critique est donc le module nRF24. Et Arduino Nano a juste la bonne taille pour s'adapter sous un petit anneau LED, donc je l'utilise comme contrôleur (mais vraiment tout fonctionnerait aussi bien ici).

2. Schémas

La connexion du module nRF24 n'est pas simple, vous devez connecter tous les fils SPI (MISO, MOSI, SCK, CS), ainsi que le fil d'activation de la puce et l'alimentation. Et si vous le voulez dans une taille raisonnablement petite, tous les en-têtes de broches doivent être retirés et les fils soudés directement aux pastilles. Donc, la connexion nRF à elle seule prend 7 fils, 14 points de soudure. La bonne nouvelle est que tout le reste est simple :l'anneau LED nécessite 1 fil de données et 2 fils d'alimentation, et 2 autres fils d'alimentation vont dans le connecteur de la batterie.

La liste de connexion est la suivante :
nRF24 broche 1 (GND) - GND d'Arduino
nRF24 broche 2 (Vcc) - 3.3v d'Arduino
nRF24 broche 3 (Chip Enable) - D9 d'Arduino
nRF24 broche 4 (SPI:CS) - D8 d'Arduino
nRF24 broche 5 (SPI:SCK) - D13 d'Arduino
nRF24 broche 6 (SPI:MOSI) - D11
nRF24 broche 7 d'Arduino ( SPI:MISO) - Anneau LED D12 de l'Arduino
Alimentation de l'anneau LED - 5V de l'Arduino
Anneau de LED GND - GND de l'Arduino
Anneau de LED DI - D5 de l'Arduino
Batterie positive (rouge) - 5V de l'Arduino
Négatif de la batterie (noir) - GND d'Arduino
(notez que la batterie nécessite un connecteur, elle peut donc être déconnectée et chargée)

Remarque importante :vous ne pouvez pas connecter les fils MOSI, MISO, SCK à d'autres broches Arduino. Le matériel SPI se trouve sur D11, D12, D13 et ne fonctionnera pas s'il n'y est pas connecté. Toutes les autres broches peuvent être modifiées (si vous effectuez les modifications correspondantes dans le programme).

3. Programme

La seule chose compliquée à propos du logiciel ici est la configuration des canaux RF. J'ai passé un bon bout de temps à essayer de le faire fonctionner avant de réaliser que uECG et nRF24 utilisent un ordre de bits différent pour l'adresse de canal. Lorsque j'ai corrigé cela, tout a commencé à fonctionner immédiatement :) En gros, nous lisons simplement les paquets entrants, utilisons leur 5e octet comme BPM et le filtrons (le canal RF est bruyant, donc de temps en temps, vous obtenez une valeur aléatoire au lieu d'une lecture correcte, et le CRC matériel est désactivé pour des raisons de compatibilité). Après cela, le BPM est converti en couleur et en nombre de pixels actifs, et c'est tout.

#include 
#ifdef __AVR__
#include
#endif
#include
#include
#include
#include
int rf_cen =9; //puce nRF24 activer la broche
int rf_cs =8 ; //nRF24 CS pin
RF24 rf(rf_cen, rf_cs);
//adresse du tuyau - codée en dur côté uECG
uint8_t pipe_rx[8] ={0x0E, 0xE6, 0x0D, 0xA7, 0 , 0, 0, 0} ;
// Quelle broche de l'Arduino est connectée aux NeoPixels ?
#define PIN 5
// Combien de NeoPixels sont connectés à l'Arduino ?
#define NUMPIXELS 16
Adafruit_NeoPixel pixels =Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
uint8_t swapbits(uint8_t a){ //l'adresse du canal uECG utilise l'ordre des bits échangés
// inverse l'ordre des bits sur un seul octet
uint8_t v =0;
if(a &0x80) v |=0x01;
if(a &0x40) v |=0x02;
if(a &0x20) v |=0x04;
if(a &0x10) v |=0x08;
if(a &0x08) v |=0x10;
if(a &0x04) v |=0x20;
if(a &0x02) v |=0x40;
if(a &0x01) v |=0x80;
retourner v;
}
configuration vide() {
pixels.begin(); // Ceci initialise la bibliothèque NeoPixel.
for(int i=0;ipixels.setPixelColor(i, pixels.Color(1,1,1));
}
pixels.show();
//nRF24 nécessite un SPI relativement lent, fonctionnerait probablement aussi à 2MHz
SPI.begin();
SPI.setBitOrder(MSBFIRST );
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
for(int x =0; x <8; x++) //nRF24 et uECG ont un ordre de bits différent pour l'adresse du canal
pipe_rx[x] =swapbits(pipe_rx[x]);
//configurer les paramètres radio
rf.begin();
rf.setDataRate(RF24_1MBPS);
rf.setAddressWidth(4);
rf.setChannel(22);
rf.setRetries(0, 0);
rf.setAutoAck(0);
rf.disableDynamicPayloads( );
rf.setPayloadSize(32);
rf.openReadingPipe(0, pipe_rx);
rf.setCRCLength(RF24_CRC_DISABLED);
rf.disableCRC();
rf.startListening(); //écouter les données uECG
//Notez que uECG doit être basculé en mode données brutes (via un appui long)
//afin d'envoyer des paquets compatibles, par défaut, il envoie des données en mode BLE
//qui ne peut pas être reçu par nRF24
}
long last_pix_upd =0;
byte in_pack[32];
int rf_bpm =0;
int bpm_hist [5] ; //depuis que nous avons désactivé le CRC, nous devons filtrer les données entrantes
boucle vide()
{
if(rf.available())
{
rf.read( in_pack, 32);
int bb =in_pack[5]; //BPM est situé au 5ème octet du paquet
//la structure détaillée du paquet est dans la documentation uECG
//puisque nous n'avons pas de CRC pour des raisons de compatibilité, nous devons filtrer
// données entrantes, le canal radio peut être bruyant. Nous comparons les 5 dernières
//valeurs BPM reçues et n'en utilisons qu'une seule si les 5 étaient identiques.
//Étant donné que uECG envoie environ 100 paquets par seconde, cela ne causera pas
// tout retard notable dans l'affichage des données
for(int n =0; n <5-1; n++) //décaler le tableau d'historique bpm de 1
bpm_hist[n] =bpm_hist[n+1];
bpm_hist[4] =bb; //ajouter une nouvelle valeur bpm
for(int n =0; n <5; n++) //vérifier si tous sont égaux
if(bpm_hist[n] !=bb) bb =-1;
if(bb> 0) //si oui - le stocker comme nouveau BPM reçu
rf_bpm =bb;
}
long ms =millis();
if( ms - last_pix_upd> 10) //ne pas mettre à jour les pixels trop souvent
{
int r, g, b;
last_pix_upd =ms;
int bpm =rf_bpm;
int max_bright =160 ; //valeur de la luminosité maximale, max 255. Mais vous ne la voulez pas toujours au max :)
float dd =25; //changement de BPM entre les tons de couleur (bleu->vert->jaune->rose->rouge)
float t1 =90, t2, t3, t4 ; //t1 - "base" BPM, inférieur à t1 serait bleu
t2 =t1 + dd;
t3 =t2 + dd;
t4 =t3 + dd;
/ /code pour changer de couleur selon dans quelle plage t1...t4 nous sommes maintenant
if(bpm sinon if(bpm else if(bpm else if(bpm else {r =max_bright; g =0 ; b =0 ; }
int on_pixels =(bpm-80)/8; //puisqu'il est destiné à la course, je ne
//montre rien de moins que 80 BPM, de cette façon il est plus sensible dans
//zone de charge élevée
for(int i=0;i{
//les pixels sont définis du dernier au premier sans raison particulière,
//fonctionneraient aussi bien s'ils étaient définis du premier au dernier
if(i else pixels.setPixelColor(NUMPIXELS-i-1, pixels.Color(0, 0,0)); //éteindre toutes les autres LED
}
pixels.show();
}
}

4. Assemblage du bracelet

Lorsque tous les fils sont soudés, le programme clignote et vous confirmez que les données uECG sont reçues - il est temps de tout rassembler.

J'ai choisi un moyen très simple de tenir le tout ensemble - la colle thermique. Étant donné que les pièces elles-mêmes s'adaptent déjà presque (Nano s'adapte à la taille de la bague extérieure, le module nRF24 s'adapte à la taille de la bague interne et la batterie, bien qu'elle ne s'adapte à aucune pièce, ne gêne pas beaucoup - je ne sais pas comment cela fonctionne, mais je viens de coller c'est là et d'une manière ou d'une autre, c'était vraiment bien :) Ensuite, je l'ai cousu sur un bracelet aléatoire que j'avais sous la main (reste du pack de station de soudure, une bande qui est utilisée pour la mise à la terre pendant le soudage), et c'est tout !

5. Tests

Pour les tests, je suis allé courir, et cela a très bien fonctionné à l'exception d'une surprise. J'ai utilisé des paramètres tels qu'à 192 BPM, toutes les LED étaient allumées, car selon toutes les recommandations, cette fréquence cardiaque est trop élevée pour mes paramètres. La surprise, c'est que je l'ai dépassé en quelques minutes de course, sans même m'en rendre compte. J'ai même pensé qu'il pouvait s'agir d'une erreur de capteur, mais non - lorsque je me suis arrêté, il n'a pas immédiatement baissé, mais il y a eu une lente relaxation (le capteur est fiable à 100% lorsqu'il n'y a pas beaucoup de mouvement). Il s'avère donc que pendant un certain temps, je m'entraîne bien au-dessus de mon seuil de santé (au moins ce qui est censé être sain pour un adulte standard de mon âge/poids). C'est intéressant :je suis assez sportif (amateur) depuis l'enfance, mais j'ai eu des problèmes cardiaques à l'adolescence et ils semblaient disparaître avec le temps. Mais je sais par expérience que toute charge supérieure à une marche rapide était vraiment difficile pour moi, mais j'ai continué à m'entraîner - et cela a augmenté ma limite au fil du temps, au point que maintenant je me considère plutôt en forme. Et maintenant, j'ai une question :est-ce que mon BPM est juste supérieur à la normale en raison de ces problèmes cardiaques à l'adolescence, ou est-ce que je pousse vraiment trop fort sans m'en rendre compte ? Quoi qu'il en soit, je vais devoir faire quelque chose avec ça - soit augmenter le BPM max sur le moniteur, soit m'entraîner moins intensément. :)

P.S. étonnamment, uECG s'est très bien comporté en tant que capteur EMG - vous pouvez lire à ce sujet dans mon projet Robotic Hand Control

Code

  • bpm_watch.ino
bpm_watch.inoArduino
#include #ifdef __AVR__ #include #endif#include #include #include #include int rf_cen =9; // La puce nRF24 active le pinint rf_cs =8; //nRF24 CS pinRF24 rf(rf_cen, rf_cs);//adresse du tuyau - codée en dur sur uECG sideuint8_t pipe_rx[8] ={0x0E, 0xE6, 0x0D, 0xA7, 0, 0, 0, 0} ; // Quelle broche sur le Arduino est connecté aux NeoPixels ?#define PIN 5// Combien de NeoPixels sont connectés à l'Arduino ?#define NUMPIXELS 16Adafruit_NeoPixel pixels =Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);uint8_t swapbits(uintu8_EC a) l'adresse utilise l'ordre des bits échangés // inverse l'ordre des bits sur un seul octet uint8_t v =0; si(a &0x80) v |=0x01; si(a &0x40) v |=0x02; si(a &0x20) v |=0x04; si(a &0x10) v |=0x08; si(a &0x08) v |=0x10; si(a &0x04) v |=0x20; si(a &0x02) v |=0x40; si(a &0x01) v |=0x80; return v;}void setup() { pixels.begin(); // Ceci initialise la bibliothèque NeoPixel. for(int i=0;i 0) //si oui - le stocker comme nouveau BPM reçu rf_bpm =bb; } ms long =millis(); if(ms - last_pix_upd> 10) //ne met pas à jour les pixels trop souvent { int r, g, b; last_pix_upd =ms; int bpm =rf_bpm; int max_brillant =160 ; //valeur de la luminosité maximale, max 255. Mais vous ne voulez pas toujours qu'elle soit au max :) float dd =25; //changement de BPM entre les tons de couleur (bleu->vert->jaune->rose->rouge) float t1 =90, t2, t3, t4; //t1 - "base" BPM, inférieur à t1 serait bleu t2 =t1 + dd; t3 =t2 + jj ; t4 =t3 + jj ; //code pour changer de couleur en fonction de la plage t1...t4 dans laquelle nous sommes maintenant if(bpm  

Schémas

Aucun document.

nrf24_led_ring_o2Gij5oigT.fzz

Processus de fabrication

  1. Renesas et Altran développent un chipset portable en utilisant 3db Access UWB
  2. Moniteur DIY Environnement et Qualité de l'Air
  3. Capteur de température Python et Raspberry Pi
  4. Surveillez la température de votre maison à l'aide de votre Raspberry Pi
  5. Moniteur de fréquence cardiaque à distance
  6. Créer un moniteur Ambilight à l'aide d'Arduino
  7. Voltmètre DIY utilisant Arduino et Smartphone
  8. Capteurs intégrés aux vêtements Moniteur de fréquence cardiaque
  9. Matériaux et composants fabriqués à l'aide de machines CNC