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

Affichage ECG temps réel sur OLED avec Arduino UNO

Composants et fournitures

Arduino UNO ×1
Dispositif uECG ×1
Module nRF24 (générique) ×1
Module OLED 0,96" 64×128 (ElectroPeak) ×1

À propos du projet

J'avais déjà publié quelques projets montrant comment récupérer les données du dispositif uECG, mais le code était complexe et n'utilisait que les données basiques. J'ai finalement écrit une bibliothèque Arduino qui simplifie grandement l'usage et le rend plus fiable : https://github.com/ultimaterobotics/uECG_library (il faut aussi installer la bibliothèque RF24 via le gestionnaire de bibliothèques, et pour l'affichage OLED comme ici, la bibliothèque Adafruit SSD1306).

1. Schéma de câblage

Le schéma est standard pour tout projet utilisant un module nRF24 et un OLED :

Photo du montage assemblé ci-dessus. Schéma joint en bas.

2. Code

La bibliothèque uECG nécessite quelques lignes pour fonctionner correctement :

Le code de ce projet est disponible comme exemple dans la bibliothèque, et ci-dessous (95 % du code sert à l'affichage optimisé sur OLED ; pour un simple affichage série, quelques lignes suffisent) :

#include <uECG.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int rf_cen = 9;  // nRF24 CE pin
int rf_cs = 10;  // nRF24 CS pin

void setup() {
  Serial.begin(115200);
  while(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
  }
  display.display();
  delay(100);
  uECG.begin(rf_cs, rf_cen);
  delay(100);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.cp437(true);
  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;

void loop() {
  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 < new_data; x++) Serial.println(ecg_data[x]);
    
    // Décalage du buffer d'affichage
    for (int x = new_data; x < ecg_screen_len; x++)
      ecg_screen[x - new_data] = ecg_screen[x];
    
    // Traitement des nouvelles données
    for (int x = 0; x < new_data; 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] < ecg_min) ecg_min = 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;
    }
    
    // Affichage par phases (toutes les 30 ms)
    if (ms - prev_displ > 30) {
      prev_displ = ms;
      if (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;
        // Indicateur batterie
        display.drawLine(110, 0, 127, 0, WHITE);
        display.drawLine(110, 10, 127, 10, WHITE);
        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 < ecg_screen_len/2; 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 < ecg_screen_len-1; x++)
          display.drawLine(x-1, ecg_screen[x-1], x, ecg_screen[x], WHITE);
      }
      if (displ_phase == 3) display.display();
      displ_phase++;
      if (displ_phase > 3) displ_phase = 0;
    }
  }
}

3. Traitement des données

Beaucoup de traitement est fait sur le dispositif uECG lui-même. Vous pouvez récupérer diverses statistiques calculées :

Les données ECG brutes sont aussi accessibles – le flux n'est pas parfait (pertes de paquets occasionnelles), mais on obtient un signal exploitable (voir capture d'écran).

Si vous aviez ce dispositif au fond d'un tiroir, il fonctionne maintenant sans trop de tracas !

Code

Bibliothèque uECG Arduino (inclut exemples OLED et série simple) : https://github.com/ultimaterobotics/uECG_library

Schématiques

Schéma de câblage joint dans les fichiers du projet.

Processus de fabrication

  1. MAX86150 de Maxim : Module PPG et ECG Intégré pour Surveillance Santé Mobile
  2. Créer une API robuste de température et capteurs sur Raspberry Pi avec le module GY‑91
  3. Démarrage avec TJBot : Construire, Configurer et Contrôler par la Voix Votre Propre Robot IA
  4. Bases des modules Verilog : Structure et syntaxe
  5. Maîtriser les Paramètres Verilog : Construire des Modules Réutilisables et Évolutifs
  6. Système de modules Java 9 : Création, link-time et images d'exécution personnalisées
  7. Automates Cellulaires Temps Réel sur Arduino avec Écran OLED 128x64
  8. Projet Arduino LCD DIY : Assemblage avec résistances, bouton poussoir et afficheur 16x2
  9. Tutoriel Arduino Débutant 01 : Démarrez votre Premier Projet