Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Echtzeit-EKG auf dem OLED-Bildschirm abrufen

Komponenten und Verbrauchsmaterialien

Arduino UNO
× 1
uEKG-Gerät
× 1
nRF24-Modul (generisch)
× 1
ElectroPeak 0,96" OLED 64x128 Anzeigemodul
× 1

Über dieses Projekt


Vor einiger Zeit habe ich ein paar Projekte veröffentlicht, die demonstrieren, wie man Daten von einem uECG-Gerät erhält - aber sie hatten ziemlich viel unordentlichen Code und verwendeten immer noch nur grundlegende Daten davon. Schließlich habe ich eine Arduino-Bibliothek geschrieben, die diesen Weg einfacher und zuverlässiger macht, hier ist sie:https://github.com/ultimaterobotics/uECG_library (bitte beachten Sie, dass Sie auch die RF24-Bibliothek vom Bibliotheksmanager installieren müssen, und wenn Sie Daten zu OLED wie in diesem Projekt anzeigen möchten - auch die SSD1306-Bibliothek von Adafruit).

1. Schaltpläne

Der Schaltplan ist der gleiche wie bei jedem anderen Projekt mit nRF24-Modul und OLED:nRF24 ist mit dem SPI-Bus von Arduino (D13, D12, D11) und zwei beliebigen Pins für die CS- und CE-Leitungen des Moduls verbunden - ich habe der Einfachheit halber D10 und D9 gewählt. Der einzige wichtige Punkt :nRF24-Modul muss an 3.3V angeschlossen werden Leitung, nicht an 5V! Es hilft auch sehr, einen 1uF- oder 10uF-Kondensator zwischen 3.3V und GND hinzuzufügen - diese nRF24-Module benötigen eine stabile Spannung, die Arduino nicht immer auf seiner 3.3V-Leitung bereitstellen kann, Kondensatoren helfen dabei.

OLED wird über I2C - SDA an A4, SCL an A5 angeschlossen und über eine 5-V-Leitung mit Strom versorgt. In meinem Fall hatte das OLED-Modul eingebaute Widerstände für das I2C-Protokoll. Falls Ihr Modul sie nicht hat, müssen Sie 4,7k-Widerstände von SDA auf 3,3 V und von SCL auf 3,3 V hinzufügen, obwohl die meisten Module, die ich in letzter Zeit gesehen habe, sie bereits haben.

Sie können die unten angehängten Schaltpläne sehen, und hier ist ein Foto des zusammengebauten Projekts:

2. Code

Die uECG-Bibliothek benötigt für den ordnungsgemäßen Betrieb einige Codezeilen, nämlich:

in setup() müssen Sie uECG.begin(pin_cs, pin_ce) aufrufen - Sie müssen ihm mitteilen, welche Pin-Nummern für nRF24 CS- und CE-Leitungen verwendet werden, es schaltet das Modul ein und versetzt es intern in den richtigen Modus.

In loop() müssen Sie uECG.run() so oft wie möglich aufrufen:Das uECG-Gerät sendet viele Daten - ein Paket alle paar Millisekunden - und wenn Sie uECG.run() nicht bis zum nächsten aufrufen Paket ankommt, gehen seine Daten verloren. Das bedeutet, dass Sie die Funktion delay() niemals innerhalb der Schleife aufrufen und millis() für Aufgaben verwenden, die ein Timing erfordern (ich habe ein Beispiel dafür in Bibliotheksbeispielen hinzugefügt).

Dieser Projektcode ist als Beispiel in der Bibliothek verfügbar und wird auch unten angehängt (wenn er zu komplex aussieht - denken Sie bitte daran, dass hier 95% des Codes für die optimierte Anzeigezeichnung vorgesehen sind, um Werte einfach in den seriellen Monitor zu drucken brauchen nur ein paar Zeilen):

#include 
#include
#include

#define SCREEN_WIDTH 128 // OLED Displaybreite, in Pixel
#define SCREEN_HEIGHT 64 // OLED Displayhöhe, in Pixel

// Deklaration für ein SSD1306 Display verbunden mit I2C (SDA, SCL Pins)
# define OLED_RESET -1 // Reset Pin # (oder -1 wenn Arduino Reset Pin geteilt)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int rf_cen =9; // nRF24-Chip-Aktivierungsstift
int rf_cs =10; // nRF24 CS-Pin

void setup () {
Serial.begin(115200); // serielle Ausgabe - sehr nützlich zum Debuggen
while(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {// Adresse 0x3D für 128x64
Serial.println(F("SSD1306 Zuweisung fehlgeschlagen"));
}
display.display();
delay(100);
uECG.begin(rf_cs, rf_cen);
delay(100);

// Puffer löschen
display.clearDisplay();
display.setTextSize(1); // Normaler Pixelmaßstab von 1:1
display.setTextColor(WHITE); // Weißen Text zeichnen
display.cp437(true); // Vollständige 256-stellige 'Codepage 437'-Schriftart verwenden
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 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;
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;
display.drawLine(110, 0, 127, 0, WHITE);
display.drawLine(110, 10, 127, 10, WEISS);
display.drawLine( 110, 0, 110, 10, WEISS);
display.drawLine(127, 0, 127, 10, WEISS);
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++;
if (displ_phase> 3) displ_phase =0;
}
}
}

3. Daten verarbeiten

Viele Verarbeitungen werden an Bord durchgeführt und Sie können verschiedene Statistiken vom Gerät berechnen lassen:BPM, GSR, letztes RR-Intervall, HRV-Parameter und 16 HRV-Bins (erster Bin stellt die Anzahl der Schläge mit einer Abweichung von <1% dar, zweiter Bin - Variation zwischen 1 und 2 % usw.), Anzahl der Schritte, Beschleunigungsmesser-Messwerte (obwohl die Aktualisierungsrate niedrig ist, sodass sie nur für die Posenschätzung geeignet ist).

Aber Sie können auch Roh-EKG-Messwerte erhalten - der Datenstrom ist nicht perfekt, hin und wieder gehen einige Pakete verloren, aber Sie können immer noch etwas Brauchbares erhalten:

Nun, das war's - wenn Sie dieses Gerät hätten, das Staub in einer Ecke sammelt, funktioniert es jetzt tatsächlich ohne großen Aufwand :)

Code

uECG Arduino-Bibliothek
Hat OLED und einfache Serienbeispiele im Innerenhttps://github.com/ultimaterobotics/uECG_library

Schaltpläne


Herstellungsprozess

  1. Maxim:Integriertes PPG- und EKG-Biosensormodul für Mobilgeräte
  2. Umgebungssensor-API mit einem RPi
  3. Erste Schritte mit TJBot
  4. Verilog-Modul
  5. Verilog-Parameter
  6. Java 9 - Modulsystem
  7. Arduino Pong-Spiel - OLED-Display
  8. Arduino- und OLED-basierte zelluläre Automaten
  9. Weiche den Defs aus!
  10. Arduino-Tutorial 01:Erste Schritte