Looking for a shorter, English version of this?
Try tldr.zotteljedi.de/heart-rate-monitoring/.
Für ein Experiment habe ich eine Möglichkeit zur Messung der Pulsfrequenz gesucht. Gefunden habe ich immer wieder Sensoren aus dem Sportbereich, so z.B. einen "Cardio Ohrclip" von Kettler zum Anschluss an deren Trainingsgeräte. Dieser besteht aus einer IR-LED und einem Fototransistor die eine Lichtschranke bilden, wobei das Ohrläppchen innerhalb dieser Lichtschranke liegt.
Wie im Wikipedia-Artikel Pulsoxymetrie beschrieben absorbiert mit Sauerstoff beladenes Blut Infrarotlicht. Die Menge des Bluts, das sich im Ohrläppchen und somit innerhalb der Lichtschranke befindet, ändert sich im Verlauf eines Herzschlags. Dadurch ändert sich auch die Absorption des Infrarotlichts und am Fototransistor lässt sich ein Signal gewinnen, das Rückschluss auf die Pulsfrequenz erlaubt. Zur Messung des absoluten Sauerstoffgehalts (der Sättigung) eignen sich diese einfachen Sensoren übrigens nicht. Die dafür gebräuchlichen Sensoren, die meistens einen ganzen Finger "packen", sind aufwändiger konstruiert und besser gegen Störlicht abgeschirmt.
Der genannte Ohrclip von Kettler (und diverse billigere Nachbauten) verwendet einen 3,5 mm Klinkenstecker. Die
Steckerbelegung hatte ich zuerst experimentell ermittelt. Bezüglich der genauen elektrischen Eigenschaften
habe ich dann bei Kettler nachgefragt und auch ein Datenblatt erhalten, das jedoch im Wesentlichen die
Steckerbelegung bestätigte, die elektrischen Eigenschaften aber weiterhin unbeantwortet ließ.
In meinen Experimenten habe ich die Infrarot-LED mit ca. 15 mA versorgt und bisher nichts kaputt gemacht.
Möglicherweise würde man mit einem stärkeren Strom allerdings ein besseres Signal gewinnen, die
15 mA sind ziemlich konservativ gewählt.
Mit einem Pullup-Widerstand von 18 kΩ am Fototransistor entsteht bei 5 V ein Signal, das gut weiterverarbeitet werden kann. Es besitzt einen großen Gleichanteil von ca. 3 V und ein Nutzsignal mit ca. 10 mV Spitze-Spitze-Spannung.
Man sieht recht gut den steilen Anstieg wenn frisches Blut in das Ohrläppchen gedrückt wird (d.h. der Fototransistor nicht mehr beleuchtet wird, sein scheinbarer Widerstand steigt und somit das Signal weniger stark in Richtung Masse gezogen wird). Man sieht aber auch gut, dass das Signal unruhig ist und einer Aufbereitung bedarf, die mittels einer Hysterese die Schwankungen "wegdigitalisiert".
Nach einer ausführlichen Webrecherche (siehe Links am Ende der Seite) und der Konsultation von The Art of Electronics habe ich folgende Schaltung entwickelt:
Um nicht auf eine bestimmte Betriebsspannung festgelegt zu sein, habe ich anstelle eines Vorwiderstands für die IR-LED eine einfache Stromquelle vorgesehen. Diese liefert ca. 16 mA bei 5 V, kann aber mit 3 V ebenso umgehen wie mit 10 V. Präzision ist hier ohnehin nicht gefragt, normale Kohleschichtwiderstände sind bestens geeignet. Die anschließende Signalverarbeitung gliedert sich in folgende Teilschritte:
Nach der Aufbereitung sieht das Signal ziemlich brauchbar aus: bei einer Versorgungsspannung von 5 V ergibt sich
ein Rechtecksignal mit ca. 4,8 V Spitze-Spitze. Der Schmitt-Trigger sorgt für steile Flanken, die auch
für die Aulösung von Interrupts geeignet sind (siehe unten).
Die Qualität des Signals ist umso erstaunlicher, wenn man sich dazu meinen Steckbrett-Aufbau ansieht. Als ich die Schaltung entwickelt hatte (2011), habe ich sie auf Lochraster gelötet. Jetzt (2020) für die Überarbeitung der Software und Auswertung konnte ich diese Schaltung nicht mehr finden und habe sie daher nur zusammengesteckt. Dabei habe ich die Beobachtung gemacht, dass bei den Messungen immer mal wieder größege Intervalle aufgetreten sind, die sich als verpasste Flanken herausgestellt haben. Dieses Problem ist verschwunden, nachdem ich die Schaltung vom PC entfernt aufgestellt hatte. Ich nehme an, dass hier irgendetwas in die langen Leitungen des fliegenden Aufbaus eingestreut hat.
Weiterhin suboptimal ist die Tatsache, dass bei diesem Aufbau die Versorgungsspannung des Operationsverstärkers dem Entwicklungsboard entnommen wird. Somit wird sie ebenfalls vom Mikrocontroller genutzt, der seinerseits hochfrequente Störungen produziert. Das Schlimmste verhindert der keramische 100nF-Kondensator zwischen VCC und GND, der möglichst dicht am IC platziert werden sollte. Besser wäre aber eine Versorgungsspannung die exklusiv für den analogen Teil genutzt wird (z.B. eine Batterie).
Das Rechtecksignal der Schaltung lässt sich mit einem Mikrocontroller auf verschiedene Arten auswerten:
Der Sampling-Ansatz setzt ein Signal voraus, das ausreichend lange HIGH- und LOW-Phasen hat (was hier der Fall ist), damit sie sicher erkannt werden ohne eine unanständig hohe Abtastfrequenz zu erfordern. Für den Interrupt-Ansatz ist die Qualität der Flanken (Flankensteilheit) entscheidend, die auf Grund des Schmitt-Triggers hier ebenfalls erfüllt ist.
Ich habe mich für die zweite Variante entschieden. Ich verwende einen internen Timer mit einer Auflösung von einer Millisekunde als Zeitbasis für eine Stoppuhr, mit der ich die Zeit messe, die zwischen zwei Aufrufen der Service-Funktion des externen Interrupts vergeht. Die ermittelten Zeiten zwischen den Herzschlägen werden per USART an den PC übertragen. Für eine einfache Darstellung der Pulsfrequenz kann jedes Mal, wenn etwas empfangen wird, ein Ton abgespielt werden. Außerdem kann leicht der Kehrwert des Intervalls gebildet werden, um auf die Frequenz zu kommen: angenommen es wurde ein Intervall von 958 Millisekunden gemessen, so ergibt sich eine Pulsfrequenz von (1000 / 958) * 60 = 62,6 Schläge pro Minute.
Die einzelnen Messwerte sind einer starken Streuung unterworfen (siehe nächster Abschnitt). Wenn die Software direkt ein Ergebnis anzeigen soll (z.B. auf einem Display) ist es ratsam, einen gleitenden Mittelwert zu bilden bzw. die Anzeige nur alle paar Sekunden zu aktualisieren.
Eine typische Ausgabe des Programms ist diese (die Zeilenumbrüche erfolgen alle 10 Werte und haben sonst keine Bedeutung):
Wait for first pulse... OK. 823 783 693 687 699 788 857 886 889 873 835 785 695 651 658 679 788 847 889 916 852 817 739 686 667 672 720 823 890 923 894 852 778 708 677 672 707 789 848 889 886 864 792 731 689 696 708 766 805 845 852 829 755 705 681 680 716 786 825 858
Die durchschnittliche Pulsfrequenz liegt bei ca. 77 Schlägen pro Minute. Das war direkt nach dem morgendlichen Kaffee und mit der stetigen Angst, mit einer falschen Kopfbewegung den ganzen Messaufbau in den Abgrund zu zerren. ;-)
Weiterhin sieht man, dass die höchste Frequenz in diesem Ausschnitt bei 92 und die niedrigste bei 65
Schlägen pro Minute liegt, also jeweils rund 15% über und unter dem Durchschnitt. Anfangs hatte ich
das für Messfehler gehalten, aber dafür war es zu regelmäßig; nach etwas Recherche bin ich
auf den Effekt der
Respiratorische Sinusarrhythmie
gestoßen. Die Grundaussage ist, dass die Herzfrequenz beim Einatmen steigt und beim Ausatmen sinkt. Wie
man sieht bleibt die Atemfrequenz während der Aufzeichnung bei ca. 8 Atemzügen pro Minute stabil,
wohingegen sich die Stärke des Effekts nach hinten raus etwas verringert. Darauf habe ich keine Antwort,
habe aber auch keine systematische Untersuchung gestartet.
Für die Auswertung habe ich ein Perl-Skript verwendet, das aus den gezeigten Rohdaten eine Reihe von Zeit/Frequenz-Pärchen bildet, die danach mit Gnuplot zu einem Diagramm verarbeitet werden. Etwas ähnliches bekommt man aber auch mit einem Tabellenkalkulationsprogramm wie Microsoft Excel oder LibreOffice hin; hier ist es ein "Punkt (XY)"-Diagramm das man haben möchte. Ein normales Balkendiagramm würde einen falschen Zusammenhang vermitteln, da die Messungen nicht im gleichen Abstand erfolgen, sondern der Abstand zwischen Messungen selbst die Information trägt.
Ich hatte zwei hervorragende Quellen, die mich auf den richtigen Weg gebracht haben:
Version | Datum | Änderungen | Datei | Beschreibung |
---|---|---|---|---|
2.0 | 2020-01-19 | Umbau auf C++ und automatische Auswertung | pulsemon-2.0.zip | Schaltplan im Eagle-Format (Version 9.2), Software |
1.0 | 2011-08-07 | Erstes Release | pulsemon-1.0.zip | Schaltplan im Eagle-Format (Version 5), Software |