KY-039 Herzschlag Sensor Modul: Unterschied zwischen den Versionen

Aus Linkerkit.de

Wechseln zu: Navigation, Suche
(Codebeispiel Arduino)
(Codebeispiel Arduino)
Zeile 43: Zeile 43:
 
Das folgende Code-Beispiel stammt aus der Feder von Dan Truong, welcher diesen Code unter [[Https://forum.arduino.cc/index.php?topic=209140.msg2168654| folgenden Link]] veröffentlicht hat. Dieser steht unter der MIT OpenSource Lizenz zur Verfügung. Die unten stehende Version ist die übersetzte deutsche Fassung - das original steht unten zum Download zur Verfügung.
 
Das folgende Code-Beispiel stammt aus der Feder von Dan Truong, welcher diesen Code unter [[Https://forum.arduino.cc/index.php?topic=209140.msg2168654| folgenden Link]] veröffentlicht hat. Dieser steht unter der MIT OpenSource Lizenz zur Verfügung. Die unten stehende Version ist die übersetzte deutsche Fassung - das original steht unten zum Download zur Verfügung.
  
 +
Dieser Code stellt eine sog. Peak-Detection dar. Es wird kein Herzschlagverlauf aufgezeichnet, sondern es
 +
wird innerhalb der aufgezeichneten Daten nach "Peaks" (Spitzen) gesucht, als Herschlag erkannt und per LED angezeigt. Mittels der bekannten Delay Abstände, kann somit grob der Puls errechnet werden.
  
 +
Wird der Finger beim messen neu aufgelegt oder stark bewegt, so kann es etwas dauern, bis das Programm sich auf die neue Gegebenheit kalibriert und wieder den richtigen Wert ausgibt.
  
<pre class="brush:cpp">////////////////////////////////////////////////////////////////////////
+
<pre class="brush:cpp">
 +
////////////////////////////////////////////////////////////////////////
 
/// Copyright (c)2015 Dan Truong
 
/// Copyright (c)2015 Dan Truong
 
/// Permission is granted to use this software under the MIT
 
/// Permission is granted to use this software under the MIT
Zeile 52: Zeile 56:
 
///
 
///
 
/// KY039 Arduino Heartrate Monitor V1.0 (April 02, 2015)
 
/// KY039 Arduino Heartrate Monitor V1.0 (April 02, 2015)
////////////////////////////////////////////////////////////////////////<br /><br />// German Comments by Joy-IT
+
////////////////////////////////////////////////////////////////////////
 +
 
 +
// German Comments by Joy-IT
 +
 
  
 
////////////////////////////////////////////////////////////////////////
 
////////////////////////////////////////////////////////////////////////
/// @param[in] IRSensorPin Analog pin on which IR detector is connected
+
/// @param[in] IRSensorPin Analog PI an welchen der Sensor angeschlossen ist
/// @param[in] delay (msec) delay between calls to this method. It is
+
/// @param[in] delay (msec) Die Verzoegerung zwischen den Aufrufen der Abtastfunktion.
///                  best to call it at least 5 times per beat, aka
+
//                   Die besten Ergebnisse erhaelt man, wenn man 5 mal Pro Herzschlag abtastet.
///                  no slower than 150msec for 70bpm. An ideal value
+
///                  Nicht langsamer als 150mSec für z.B. 70 BPM Puls
///                  is 60ms or faster to handle up to 200 BPM.
+
///                  Besser waere 60 mSec für z.B. bis zu einen Puls von 200 BPM.
 
///
 
///
/// @brief
+
/// @Kurzbeschreibung
/// True if heartbeat is detected on the sensor.
+
/// Dieser Code stellt eine sog. Peak-Detection dar.
/// This code is trivial and just does a peak detection, instead of
+
/// Es wird kein Herzschlagverlauf aufgezeichnet, sondern es
/// trying to detect the heart's pulse waveform.
+
/// wird innerhalb der aufgezeichneten Daten nach "Peaks" (Spitzen) gesucht,  
/// Note: I am fudging sensor data with the delay to make the integer
+
/// und per LED angezeigt. Mittels der bekannten Delay Abstaende, kann somit
/// math after that uses constants, somewhat independant of the sleep
+
/// grob der Puls errechnet werden.
/// delay used in the main loop. Otherwise if maxValue decays too slow
+
/// or too fast, it causes glitches and false beat detection.
+
 
////////////////////////////////////////////////////////////////////////
 
////////////////////////////////////////////////////////////////////////
  
Zeile 79: Zeile 84:
 
   static int maxValue = 0;
 
   static int maxValue = 0;
 
   static bool isPeak = false;
 
   static bool isPeak = false;
 +
 
 
    
 
    
 
   bool result = false;
 
   bool result = false;
 
      
 
      
 
   rawValue = analogRead(IRSensorPin);
 
   rawValue = analogRead(IRSensorPin);
   // Separated because analogRead() may not return an int
+
   // Hier wird der aktuelle Spannungswert am Fototransistor ausgelesen und in der rawValue-Variable zwischengespeichert
 
   rawValue *= (1000/delay);
 
   rawValue *= (1000/delay);
  
 
+
  // Sollte der aktuelle Wert vom letzten maximalen Wert zu weit abweichen
   // If sensor shifts, then max is out of whack.
+
   // (z.B. da der Finger neu aufgesetzt oder weggenommen wurde)
   // Just reset max to a new baseline.
+
   // So wird der MaxValue resetiert, um eine neue Basis zu erhalten.
   if (rawValue * 4L < maxValue) {   <br />  maxValue = rawValue * 0.8;   <br />  rawValue = rawValue *4L;
+
   if (rawValue * 4L < maxValue) {   maxValue = rawValue * 0.8;
   
+
 
   }
 
   }
 
    
 
    
 
   // Detect new peak
 
   // Detect new peak
 
   if (rawValue > maxValue - (1000/delay)) {
 
   if (rawValue > maxValue - (1000/delay)) {
     // Only change peak if we find a higher one.
+
     // Hier wird der eigentliche Peak detektiert. Sollte ein neuer RawValue groeßer sein
 +
// als der letzte maximale Wert, so wird das als Spitze der aufgezeichnten Daten erkannt.
 
     if (rawValue > maxValue) {
 
     if (rawValue > maxValue) {
 
       maxValue = rawValue;
 
       maxValue = rawValue;
 
     }
 
     }
     // Only return true once per peak.
+
     // Zum erkannten Peak soll nur ein Herzschlag zugewiesen werden
 
     if (isPeak == false) {
 
     if (isPeak == false) {
 
       result = true;
 
       result = true;
      }
+
    }
 
     isPeak = true;
 
     isPeak = true;
 
   } else if (rawValue < maxValue - (3000/delay)) {
 
   } else if (rawValue < maxValue - (3000/delay)) {
 
     isPeak = false;
 
     isPeak = false;
     // Decay max value to adjust to sensor shifting
+
     // Hierbei wird der maximale Wert bei jeden Durchlauf
     // Note that it may take a few seconds to re-detect
+
     // etwas wieder herabgesetzt. Dies hat den Grund, dass
     // the signal when sensor is pushed on meatier part
+
     // nicht nur der Wert sonst immer stabil bei jedem Schlag
     // of the finger. Another way would be to track how
+
     // gleich oder kleiner werden wuerde, sondern auch,
     // long since last beat, and if over 1sec, reset
+
     // falls der Finger sich minimal bewegen sollte und somit
     // maxValue, or to use derivatives to remove DC bias.
+
     // das Signal generell schwaecher werden wuerde.
 
     maxValue-=(1000/delay);
 
     maxValue-=(1000/delay);
 
  }
 
  }
Zeile 126: Zeile 132:
 
void setup()
 
void setup()
 
{
 
{
   // Built-in arduino board pin for the display LED
+
   // Die eingebaute Arduino LED (Digital 13), wird hier zur Ausgabe genutzt
 
   pinMode(ledPin,OUTPUT);
 
   pinMode(ledPin,OUTPUT);
 
    
 
    
   // Init serial console
+
   // Serielle Ausgabe Initialisierung
 
   Serial.begin(9600);
 
   Serial.begin(9600);
   Serial.println("Heartbeat detection sample code.");
+
   Serial.println("Heartbeat Detektion Beispielcode.");
 
}
 
}
  
 
const int delayMsec = 60; // 100msec per sample
 
const int delayMsec = 60; // 100msec per sample
  
// The main loop blips the LED and computes BPMs on serial port.
+
// Das Hauptprogramm hat zwei Aufgaben:
 +
// - Wird ein Herzschlag erkannt, so blinkt die LED kurz aufgesetzt
 +
// - Der Puls wird errechnet und auf der serriellen Ausgabe ausgegeben.
 +
 
 
void loop()
 
void loop()
 
{
 
{
Zeile 144: Zeile 153:
 
   if (heartbeatDetected(analogPin, delayMsec)) {
 
   if (heartbeatDetected(analogPin, delayMsec)) {
 
     heartRateBPM = 60000 / beatMsec;
 
     heartRateBPM = 60000 / beatMsec;
 +
// LED-Ausgabe bei Herzschlag
 
     digitalWrite(ledPin,1);
 
     digitalWrite(ledPin,1);
  
     // Print msec/beat and instantaneous heart rate in BPM
+
     // Serielle Datenausgabe
 
     Serial.print(rawValue);
 
     Serial.print(rawValue);
 
     Serial.print(", ");
 
     Serial.print(", ");
Zeile 155: Zeile 165:
 
     digitalWrite(ledPin,0);
 
     digitalWrite(ledPin,0);
 
   }
 
   }
  // Note: I assume the sleep delay is way longer than the
 
  // number of cycles used to run the code hence the error
 
  // is negligible for math.
 
 
   delay(delayMsec);
 
   delay(delayMsec);
 
   beatMsec += delayMsec;
 
   beatMsec += delayMsec;
Zeile 163: Zeile 170:
  
 
</pre>
 
</pre>
 +
 +
'''Anschlussbelegung Arduino:'''
 +
 +
{| style="height: 58px; padding-left: 30px;" width="228"
 +
|-
 +
||Sensor Signal
 +
||=
 +
||[Pin 0]
 +
|-
 +
||Sensor +V
 +
||=
 +
||[5V]
 +
|-
 +
||Sensor -
 +
||=
 +
||[Pin GND]
 +
|}
 +
 +
'''Beispielprogramm Download'''
 +
 +
[[Medium:KY-006_Buzzer.zip|KY-006_Buzzer.zip]]

Version vom 1. April 2016, 15:29 Uhr

Bild

ky-039.jpg

Technische Daten / Kurzbeschreibung

Wird ein Finger zwischen der Infrarot-Leuchtdiode und dem Foto-Transistor gehalten, so kann am Signalausgang der Puls detektiert werden.


Die Funktionsweise eines Fototransistors ist wie folgt erklärt: Dieser funktioniert in der Regel wie ein normaler Transistor - so wird ein höherer Strom durch ihn durchgelassen, je höher die Steuerspannung ist, die an ihn angelegt wird. Bei einem Fototransistor stellt jedoch das einfallende Licht die Steuerspannung dar - je höher das einfallende Licht, so höher der durchgelassene Strom. 


Phototransistor.png
Schaltet man vor dem Transistor einen Widerstand in Reihe, so ergibt sich folgendes Verhalten, wenn man die Spannung über den Transistor misst: Scheint auf den Transistor viel Licht bzw. ist es außen hell, so kann man eine niedrige Spannung nahe 0V gemessen - ist der Transistor im Dunklen, so lässt dieser einen relativ kleinen Strom durch und man misst eine Spannung nahe +V.


Der bei diesem Sensormodul aufgebaute Messaufbau mit Infrarotdiode und Fototransistor ermöglicht uns nun den Puls zu messen, indem ein Finger zwischen Diode und Transistor gelegt wird. Erklärung: Genau so wie man es von der Taschenlampe kennt, kann die Haut an der Hand durchleuchtet werden. Trifft man beim Durchleuchten auf eine Blutader, so kann man ganz schwach das Pumpen des Blutes erkennen. Dieses Pumpen erkennt man, da das Blut an unterschiedlichen Stellen in der Ader eine andere Dichte besitzt und somit Helligkeitsunterschiede beim Blutfluss erkennbar sind. Genau diese Unterschiede in der Helligkeit kann man mit dem Sensormodul aufnehmen und somit den Puls erkennen. Deutlich wird dieses beim Betrachten des folgenden Oszilloskop-Bildes.


DS1Z QuickPrint1.png


Dieses zeigt auf der Y-Achse die Veränderung der Spannung am Fototransistor - somit die Helligkeitsveränderungen hervorgerufen durch das fließende Blut. Die oben gekennzeichneten Spitzen ergeben somit das Schlagen vom Herz. Rechnet man nun die registrierten Schläge pro aufgenommener Zeit, so kommt man auf einen Puls von ca. 71 Schläge/Minute (bpm)


Wie man auf dem oberen Oszilloskop-Bild zudem sehen kann, ist das aufgenommene Signal relativ klein bzw. der Transistor sehr empfindlich, um das schwache Signal aufnehmen zu können.Um ein optimales Ergebnis zu erhalten, empfehlen wir das Modul zum messen so vorzubereiten, wie im folgenden Bild gezeigt:

KY-0039 1.jpg


Zudem sollte beim messen am besten der kleine Finger verwendet werden, sowie darauf geachtet werden, dass zwischen Diode und Transistor kein blockierender Knochen sondern eher größenteils die Haut aufgenommen wird.


KY-0039 2.jpg



Pin-Belegung

3 G V S.png

Codebeispiel Arduino

Das folgende Code-Beispiel stammt aus der Feder von Dan Truong, welcher diesen Code unter [folgenden Link] veröffentlicht hat. Dieser steht unter der MIT OpenSource Lizenz zur Verfügung. Die unten stehende Version ist die übersetzte deutsche Fassung - das original steht unten zum Download zur Verfügung.

Dieser Code stellt eine sog. Peak-Detection dar. Es wird kein Herzschlagverlauf aufgezeichnet, sondern es wird innerhalb der aufgezeichneten Daten nach "Peaks" (Spitzen) gesucht, als Herschlag erkannt und per LED angezeigt. Mittels der bekannten Delay Abstände, kann somit grob der Puls errechnet werden.

Wird der Finger beim messen neu aufgelegt oder stark bewegt, so kann es etwas dauern, bis das Programm sich auf die neue Gegebenheit kalibriert und wieder den richtigen Wert ausgibt.

////////////////////////////////////////////////////////////////////////
/// Copyright (c)2015 Dan Truong
/// Permission is granted to use this software under the MIT
/// licence, with my name and copyright kept in source code
/// http://http://opensource.org/licenses/MIT
///
/// KY039 Arduino Heartrate Monitor V1.0 (April 02, 2015)
////////////////////////////////////////////////////////////////////////

// German Comments by Joy-IT


////////////////////////////////////////////////////////////////////////
/// @param[in] IRSensorPin Analog PI an welchen der Sensor angeschlossen ist
/// @param[in] delay (msec) Die Verzoegerung zwischen den Aufrufen der Abtastfunktion.
//                   Die besten Ergebnisse erhaelt man, wenn man 5 mal Pro Herzschlag abtastet.
///                  Nicht langsamer als 150mSec für z.B. 70 BPM Puls
///                  Besser waere 60 mSec für z.B. bis zu einen Puls von 200 BPM.
///
/// @Kurzbeschreibung
/// Dieser Code stellt eine sog. Peak-Detection dar.
/// Es wird kein Herzschlagverlauf aufgezeichnet, sondern es
/// wird innerhalb der aufgezeichneten Daten nach "Peaks" (Spitzen) gesucht, 
/// und per LED angezeigt. Mittels der bekannten Delay Abstaende, kann somit
/// grob der Puls errechnet werden.
////////////////////////////////////////////////////////////////////////

int rawValue;


bool
heartbeatDetected(int IRSensorPin, int delay)
{
  static int maxValue = 0;
  static bool isPeak = false;
  
  
  bool result = false;
    
  rawValue = analogRead(IRSensorPin);
  // Hier wird der aktuelle Spannungswert am Fototransistor ausgelesen und in der rawValue-Variable zwischengespeichert
  rawValue *= (1000/delay);

  // Sollte der aktuelle Wert vom letzten maximalen Wert zu weit abweichen
  // (z.B. da der Finger neu aufgesetzt oder weggenommen wurde)
  // So wird der MaxValue resetiert, um eine neue Basis zu erhalten.
  if (rawValue * 4L < maxValue) {    maxValue = rawValue * 0.8;
  }
  
  // Detect new peak
  if (rawValue > maxValue - (1000/delay)) {
    // Hier wird der eigentliche Peak detektiert. Sollte ein neuer RawValue groeßer sein
	// als der letzte maximale Wert, so wird das als Spitze der aufgezeichnten Daten erkannt.
    if (rawValue > maxValue) {
      maxValue = rawValue;
    }
    // Zum erkannten Peak soll nur ein Herzschlag zugewiesen werden
    if (isPeak == false) {
      result = true;
    }
    isPeak = true;
  } else if (rawValue < maxValue - (3000/delay)) {
    isPeak = false;
    // Hierbei wird der maximale Wert bei jeden Durchlauf
    // etwas wieder herabgesetzt. Dies hat den Grund, dass
    // nicht nur der Wert sonst immer stabil bei jedem Schlag
    // gleich oder kleiner werden wuerde, sondern auch,
    // falls der Finger sich minimal bewegen sollte und somit
    // das Signal generell schwaecher werden wuerde.
    maxValue-=(1000/delay);
 }
  return result;
}


////////////////////////////////////////////////////////////////////////
// Arduino main code
////////////////////////////////////////////////////////////////////////
int ledPin=13;
int analogPin=0;

void setup()
{
  // Die eingebaute Arduino LED (Digital 13), wird hier zur Ausgabe genutzt
  pinMode(ledPin,OUTPUT);
  
  // Serielle Ausgabe Initialisierung
  Serial.begin(9600);
  Serial.println("Heartbeat Detektion Beispielcode.");
}

const int delayMsec = 60; // 100msec per sample

// Das Hauptprogramm hat zwei Aufgaben: 
// - Wird ein Herzschlag erkannt, so blinkt die LED kurz aufgesetzt
// - Der Puls wird errechnet und auf der serriellen Ausgabe ausgegeben.

void loop()
{
  static int beatMsec = 0;
  int heartRateBPM = 0;
      Serial.println(rawValue);
  if (heartbeatDetected(analogPin, delayMsec)) {
    heartRateBPM = 60000 / beatMsec;
	// LED-Ausgabe bei Herzschlag
    digitalWrite(ledPin,1);

    // Serielle Datenausgabe
    Serial.print(rawValue);
    Serial.print(", ");
    Serial.println(heartRateBPM);
    
    beatMsec = 0;
  } else {
    digitalWrite(ledPin,0);
  }
  delay(delayMsec);
  beatMsec += delayMsec;
}

Anschlussbelegung Arduino:

Sensor Signal = [Pin 0]
Sensor +V = [5V]
Sensor - = [Pin GND]

Beispielprogramm Download

KY-006_Buzzer.zip