====== Pulssensor ======
{{ ::pulssensor_schn.jpg?nolink&400 |}}
====== Projekt======
Der Pulssensor hat die Aufgabe den Puls zu messen und diesen auf einem LED-Display und auf einer Website auszugeben. Er wird durch ein auf dem RaspberryPi liegendes Python-Skript aktiviert, welches wiederrum durch ein in die Website integriertes PHP-Skript aktiviert wird. Das PHP-Skript der Website wird aktiviert, sobald ein Benutzer alle Formularfelder (Name, Vorname und Geburtsdatum) befüllt hat und den Knopf „Messung“ gedrückt hat. Das Python-Skript wird gestartet, läuft ca. 15 Sekunden, nach Ablaufen der Zeit lädt die Website neu und zeigt die Patientenstammdaten und den gemessenen Puls in Puls/Minute (BPM) auf der rechten Seite an.
Der Pulssensor misst den Puls indem er die Helligkeitsunterschiede zwischen den Herzschlägen misst. Wenn viel Licht vom Transistor aufgenommen wird misst der Sensor eine niedrige Spannung. Sobald Blut gepumpt wird erkennt der Transistor einen Helligkeitsunterschied und man misst eine höhere Spannung. Diese Werte werden vom ADC Wandler in Digitale Werte zwischen 0 und 4095 verarbeitet (0 = Keine Spannung, 4095 = 3,3 Volt). Der RaspberryPi kann von Haus aus keine analogen Werte interpretieren, sondern nur Digitale. Deshalb muss zum Auslesen der Pulssensor-Werte der beschrieben ADC-Wandler zwischengeschaltet werden. Es handelt sich um einen 12-Bit-ADC-Wandler, das bedeutet, dass er Werte von 0 bis 2^12, also 4095 ausgibt.
====== Bauteile======
Verwendete Teile:
* Raspberry Pi 3
* Breadboard 200 Pin
* 2-Zeilen-LCD-Display
* ADC Wandler 2^12 Bit
* KY-039 Herzschlagsensor
* (Tablet als Eingabegerät)
====== Aufbau======
{{ :20062022-1700.png?nolink&400 |}}
====== Code======
====Pulssensor====
Beim Starten des Python-Skripts werden (falls vorhanden) die alten CSV- und TXT-Dateien gelöscht, damit das Skript nach dem Aufzeichnen der Werte wieder problemlos eine neue Datei anlegen kann.
Wir sprechen den Channel 0 des ADC-Wandlers an, also den Channel ganz unten am Board. Um die ADC-Werte auszulesen, läuft eine While-Schleife mit einer Abfrage-Clock des ADC-Wandlers 250 Durchläufe in 15 Sekunden. Die Werte werden dann jeweils in einem Array und in einer CSV Datei abgespeichert. Sobald der Mittelwert ausgerechnet wurde, definiert man die Peaks und Troughs. Um auf einen Schwellenwert zu kommen, welcher ein Peak/Trough definiert, haben wir viele verschiedene Werte ausprobiert und sind zum Entschluss gekommen, dass man mit +- 80 vom Mittelwert die realistischsten Werte erhält.
Nach dem Sammeln der Werte wird ausgerechnet, welche Liste mehr Einträge enthält, Peaks oder Troughs. Der höhere Wert wird verwendet, damit die Pulsmessung durch möglichst viele Werte genauer wird. Ist die Summe der Peaks jedoch beispielsweise über 60 nimmt er die Summe der Troughs und dasselbe funktioniert auch umgekehrt. Dies ist ein weiterer Vorgang um einen genauere BPM zu bestimmen, da Werte > 60 auf 15 Sekunden gerechnet schon einen unrealistischen Ruhepuls von 240 (4 * 60) bedeuten. Sollte sowohl die Anzahl der Peaks, als auch die Anzahl der Troughs > 60 sein, ist die Messung mit einem Ruhepuls von über 240 als unrealistisch anzusehen und auf der Website und dem LCD-Display wird die Meldung „Unrealistischer Werte, bitte Messung erneut durchführen“ ausgegeben.
try: #Loeschen der vorherigen CSV und TXT Dateien
os.remove('adc_werte.csv')
except FileNotFoundError:
time.sleep(1)
try:
os.remove('bpm.txt')
except FileNotFoundError:
time.sleep(1)
i = 0 #Variable zum Hochzaehlen der Schleife
a = [] #Leerer Array
while i < 250: #250 Werte -> 15 Sekunden messen
word=[1,1,0,0,0,1,1]
gp.output(24, False)
anip=0 #Variable neu initialisieren, dass sie wieder leer ist
#Clock out of 7 bits to select channel => AD-Wandler kann von 0 bis Channel 7 angepsrochen werden
#for k in range (0,1000): #1000 Werte, die ich in der CSV Datei abspeichern moechte
for x in range (0,7):
gp.output(19, word[x])
time.sleep(0.0001)
gp.output(23, True)
time.sleep(0.0001)
gp.output(23, False)
#Clock in 11 bits of data
for x in range (0,12):
gp.output(23, True) #Clock auf high
time.sleep(0.0001)
bit=gp.input(21) #Read Input
time.sleep(0.0001)
gp.output(23, False) #Clock of low
value=bit*2**(12-x-1) #Work out of value des Bits
anip=anip+value #Fuegt der vorherigen Summe hinzu
time.sleep(0.06)
#print (anip)
#Werte in den Array speichern
a.append(anip)
#tup1 = ("",anip)
#ADC-Werte werden in CSV Datei abgespeichert
writer = csv.writer(f)
writer.writerow([anip])
f.close
i = i + 1
#Erster Ansatz vom CSV Writer
#k = (anip) #Tupel = Sequenz von unveraenderlichen Python Objekten
#writer = csv.writer(f)
#writer.writerow(str(k))
gp.output(24, True) #Chip disablen
min = min(a)
max = max(a)
mean = statistics.mean(a)
print(min) #Minimum, Maximum und Mittelwert im Terminal ausgeben
print(max)
print(mean)
T = mean - 80 #Definition Tal
P = mean + 80 #Definition Peak
count_t = sum(1 for i in a if i < T) #Summe Taeler:
print(count_t)
count_p = sum(1 for i in a if i > P) #Summe Peaks:
print(count_p)
if count_t > count_p:
wert = count_t
else:
wert = count_p
if wert == count_p and wert > 60: #Wenn die Peaks groesser sind als 60 soll er Taeler nehmen und andersherum.
wert = count_t
elif wert == count_t and wert > 60:
wert = count_p
====LCD-Display====
Das LCD-Display ermöglicht es uns auf zwei Zeilen zwei kurze Nachrichten auszugeben. Nachdem die Pulsmessung abgeschlossen ist, wird der gemessen Wert sowohl in eine TXT-Datei geschrieben (damit diese von der Website ausgewertet und angezeigt werden kann), als auch auf dem LCD-Display angezeigt. Auch hier wird bei einem unrealistischen Ruhepuls eine Meldung eingeblendet, welche darum bittet die Messung erneut durchzuführen.
#Display Ausgabe
#Wenn Werte realistisch dann werden sie ausgegeben
if wert > 10 and wert < 60:
lcd.lcd_display_string("BPM:", 1)
#Um auf Beats per Minute zu kommen
wert = wert * 4
lcd.lcd_display_string(str(wert), 2)
print (wert)
with open ("bpm.txt", 'a') as file:
file.write("Ihre BPM: " + str(wert))
file.close
#wert an server schicken
#Sonst wird man aufgeforder noch einmal zu messen
else:
lcd.lcd_display_string("Bitte noch", 1)
lcd.lcd_display_string("einmal messen", 2)
with open ("bpm.txt", 'a') as file:
file.write("Bitte nochmal messen.")
file.close
time.sleep(4)
lcd.lcd_clear()
====Website====
Die Website funktioniert im Grunde ganz simple, sie ist ein zwei Bereiche aufgeteilt:
1. Den Patientendaten-Eingabe-Bereich: Es existieren die notwendigen Eingabefelder für die Patientenstammdaten Name, Vorname und Geburtsdatum. Im Kopf der des