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

Obtenir un ECG en temps réel sur un écran OLED

Composants et fournitures

Arduino UNO
× 1
appareil uECG
× 1
Module nRF24 (Générique)
× 1
Module d'affichage OLED 64x128 ElectroPeak 0.96"
× 1

À propos de ce projet


Il y a quelque temps, j'ai publié quelques projets démontrant comment obtenir des données à partir d'un appareil uECG - mais ils avaient beaucoup de code désordonné et n'utilisaient toujours que des données de base. Alors finalement, j'ai écrit une bibliothèque Arduino qui rend cette façon plus simple et beaucoup plus fiable, la voici :https://github.com/ultimaterobotics/uECG_library (veuillez noter que vous devez également installer la bibliothèque RF24 à partir de Library Manager, et si vous voulez afficher des données sur OLED comme dans ce projet - également la bibliothèque SSD1306) d'Adafruit).

1. Schémas

Le schéma est le même que pour tout autre projet utilisant le module nRF24 et OLED :nRF24 est connecté au bus SPI d'Arduino (D13, D12, D11) et à deux broches arbitraires pour les lignes du module CS et CE - j'ai choisi D10 et D9 pour plus de commodité. Le seul point important :le module nRF24 doit être connecté à 3,3V ligne, pas à 5V ! Il est également très utile d'ajouter un condensateur de 1 uF ou 10 uF entre 3,3 V et GND - ces modules nRF24 nécessitent une tension stable qu'Arduino ne peut pas toujours fournir sur sa ligne de 3,3 V, les condensateurs y contribuent.

OLED est connecté via I2C - SDA à A4, SCL à A5 et alimenté par une ligne 5V. Dans mon cas, le module OLED avait des résistances intégrées pour le protocole I2C. Au cas où votre module ne les aurait pas, vous devez ajouter des résistances de 4,7 k de SDA à 3,3 V et de SCL à 3,3 V, bien que la plupart des modules que j'ai vus récemment les aient déjà.

Vous pouvez voir les schémas ci-dessous, et voici une photo du projet assemblé :

2. Coder

La bibliothèque uECG nécessite quelques lignes de code pour un fonctionnement correct, à savoir :

dans setup(), vous devez appeler uECG.begin(pin_cs, pin_ce) - vous devez lui dire quels numéros de broche sont utilisés pour les lignes nRF24 CS et CE, il allumera le module et le mettra dans le bon mode en interne.

Dans loop(), vous devez appeler uECG.run() aussi souvent que possible :le périphérique uECG envoie beaucoup de données - un paquet toutes les quelques millisecondes - et si vous n'appelez pas uECG.run() avant la prochaine fois paquet arrive, ses données seront perdues. Cela signifie ne jamais appeler la fonction delay () à l'intérieur de la boucle et utiliser millis () pour les tâches qui nécessitent du minutage (j'en ai ajouté un exemple dans les exemples de bibliothèque).

Ce code de projet est disponible à titre d'exemple dans la bibliothèque et est également joint ci-dessous (s'il semble trop complexe - veuillez garder à l'esprit qu'ici 95% du code est dédié au dessin d'affichage optimisé, pour une impression simple des valeurs dans le moniteur série, vous besoin de quelques lignes) :

#include 
#include
#include

#define SCREEN_WIDTH 128 // OLED largeur d'affichage, en pixels
#define SCREEN_HEIGHT 64 // Hauteur d'affichage OLED, en pixels

// Déclaration pour un affichage SSD1306 connecté à I2C (broches SDA, SCL)
# définir OLED_RESET -1 // Réinitialiser la broche # (ou -1 si vous partagez la broche de réinitialisation Arduino)
Affichage Adafruit_SSD1306 (SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int rf_cen =9 ; // broche d'activation de la puce nRF24
int rf_cs =10 ; //nRF24 CS pin

void setup() {
Serial.begin(115200); //sortie série - très utile pour le débogage
while(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adresse 0x3D pour 128x64
Serial.println(F("L'allocation SSD1306 a échoué"));
}
display.display();
delay(100);
uECG.begin(rf_cs, rf_cen);
delay(100);

// Vide le tampon
display.clearDisplay();
display.setTextSize(1); // Échelle de pixel 1:1 normale
display.setTextColor(WHITE); // Dessine du texte blanc
display.cp437(true); // Utiliser la police 'Code Page 437' de 256 caractères
display.display();
delay(100);
Serial.println("after display");
}

uint32_t prev_data_count =0;
uint32_t prev_displ =0;

uint8_t ecg_screen[128];
int ecg_screen_len =128;
float ecg_avg =0;
float ecg_max =1;
float ecg_min =-1;
int ecg_size =40;

int displ_phase =0;

boucle vide()
{
uECG.run();
uint32_t data_count =uECG.getDataCount();
int new_data =data_count - prev_data_count;
prev_data_count =data_count;
if(new_data> 0)
{
uint32_t ms =millis();
int16_t ecg_data[8];
uECG.getECG(ecg_data, new_data);
for(int x =0; x Serial.println(ecg_data[x]);

for(int x =new_data; x ecg_screen[x-new_data] =ecg_screen[x];
for(int x =0; x {
ecg_avg *=0.99;
ecg_avg +=0.01*ecg_data[x];
ecg_max =ecg_max*0.995 + ecg_avg*0.005;
ecg_min =ecg_min*0.995 + ecg_avg*0.005;
if(ecg_data[x]> ecg_max) ecg_max =ecg_data[x];
if(ecg_data[x] int ecg_y =63-ecg_size*(ecg_data[x] - ecg_min) / (ecg_max - ecg_min + 1);
ecg_screen[ ecg_screen_len-1-new_data+x] =ecg_y;
}

if(ms - prev_displ> 30)
{
prev_displ =ms;
si (displ_phase ==0)
{
display.clearDisplay();
display.setCursor(0, 0);
display.print("BPM:");
display.println(uECG.getBPM());
display.print(" RR:");
display.println(uECG.getLastRR());
display.print( "steps:");
display.print(uECG.getSteps());
int batt_mv =uECG.getBattery();
int batt_perc =(batt_mv - 3300)/8;
if(batt_perc <0) batt_perc =0;
if(batt_perc> 100) batt_perc =100;
display.drawLine(110, 0, 127, 0, WHITE);
display.drawLine(110, 10, 127, 10, BLANC);
display.drawLine( 110, 0, 110, 10, WHITE);
display.drawLine(127, 0, 127, 10, WHITE);
int bat_len =batt_perc / 6;
for(int x =1; x <10 ; x++)
display.drawLine(110, x, 110+bat_len, x, WHITE);
}
if(displ_phase ==1)
{
for( int x =1; x display.drawLine(x-1, ecg_screen[x-1], x, ecg_screen[x], WHITE);
}
if(displ_phase ==2)
{
for(int x =ecg_screen_len/2; x display.drawLine(x-1, ecg_screen[x- 1], x, ecg_screen[x], WHITE);
}
if(displ_phase ==3)
display.display();
displ_phase++;
si (displ_phase> 3) displ_phase =0;
}
}
}

3. Traitement des données

De nombreux traitements sont effectués à bord et vous pouvez obtenir diverses statistiques calculées par l'appareil :BPM, GSR, dernier intervalle RR, paramètre HRV et 16 cases HRV (la première case représente le nombre de battements avec une variation <1 %, la deuxième case - variation entre 1 et 2 %, etc.), nombre de pas parcourus, lectures de l'accéléromètre (bien que le taux de rafraîchissement soit faible, il n'est donc bon que pour l'estimation de la pose).

Mais vous pouvez également obtenir des lectures ECG brutes - le flux de données n'est pas parfait, de temps en temps, certains paquets sont perdus, mais vous pouvez toujours obtenir quelque chose d'utilisable :

Eh bien, c'est tout - si vous aviez cet appareil qui ramassait la poussière dans un coin, il fonctionne maintenant sans trop de problèmes :)

Code

bibliothèque arduino uECG
A OLED et des exemples de série simples à l'intérieur https://github.com/ultimaterobotics/uECG_library

Schémas


Processus de fabrication

  1. Maxim :module de biocapteur PPG et ECG intégré pour appareils mobiles
  2. API de capteur environnemental avec un RPi
  3. Premiers pas avec TJBot
  4. Module Verilog
  5. Paramètres Verilog
  6. Java 9 - Système de modules
  7. Automates cellulaires basés sur Arduino et OLED
  8. Esquivez les défenses !
  9. Tutoriel Arduino 01 :Prise en main