Pulssensor

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

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 <form>-Bereichs wird mit dem Befehl „?php echo $_SERVER['PHP_SELF']; ?“ ein neues Laden der angezeigten Website erwirkt. Mit dem sich ganz unten befindenden Knopf „Messung“, wird die Website also neugeladen und die Patientenstammdaten werden auf dem zweiten Website-Teil angezeigt.

2. Auf dem Patienten-Ausgabe-Bereich werden bei jedem Laden der Website die Patientenstammdaten und der gemessene Puls ausgegeben. Da beides bei einem erstmaligen Laden der Seite noch nicht existiert beziehungsweise logischerweise noch keines der Eingabefelder befüllt wurde, würde die Seite eigentlich eine Fehlermeldung anzeigen. Über die dreifache „empty($_POST[„*Feldname*“])-Bedingung wird dieser Vorgang allerdings verhindert, sodass der PHP-Skript-Teil erst ausgeführt wird, wenn das Formular mit allen drei befüllten Feldern abgeschickt wurde. Unter der Werteübergabe der Felder wird im Anschluss das Pulsmessungs-Python-Skript ausgeführt, welches, wie bereits oben beschrieben, 15 Sekunden läuft. Dementsprechend dauert es nach dem Drücken des Messungs-Knopfs 15 Sekunden, bis die Website neu geladen wurde. Nach dem erfolgreichen Ausführen des Skripts wurde der BPM in die entsprechende TXT-Datei übertragen, welche nun noch durch den Befehl „include ‚bpm.txt‘;“ auf der Website angezeigt wird.