EKGUI 2 - Projektstart
Zunächst sollen hier einige Anforderungen definiert werden, damit ich konkrete Ziele habe auf die ich hinarbeiten kann, und dann werden erste Funktionen implementiert.
Anforderungen
Funktionen
- Kann die zu verwendende USB-UART Schnitstelle auswählen (/de/ttyUSBx)
- Kann den Puls messen
- Zeigt die EKG-Kurven in Echtzeit auf dem Bildschirm an
- hat eine Möglichkeit Messkurven zu speichern
- komplett mit jedem einzelnen Messwert
- nur Puls + Timestamp
- CSV
Technik
- Soll auf Python 3 und verbreiteten Erweiterungen basierten.
- Soll ohne root verwendbar sein. (Ggf. setup Skript mit root Rechten)
- Gute Erweiterbarkeit, so das später weitere Projekte auf die Software aufbauen können.
Schrittweise Implementierung
Das Protokoll
Da das EKG Gerät auf Standardlogikbausteinen basiert ist das Protokoll extrem einfach. Nacheinander werden vier Bytes übertragen, und dann wird der nächste Satz Werte übertragen. Die vier Bytes enthalten die drei Werte der drei Kanäle, und einmal konstant (circa?) den Wert 127 um zuordnen zu können wann ein neues Viererpaket beginnt.
In einem seriellen Terminal ist die Struktur des Datenstroms mit bloßem Auge gut zu erkennen.
Zunächst muss also in Python eine serielle Schnittstelle geöffnet werden, und die Bytes ausgelesen werden. Dazu wird pyserial verwendet.
Anschließend muss das Markerbyte erkannt werden und entsprechend jeweils die anderen drei Bytes in in ein Tupel (oder anderer Datentyp?) gespeichert. Dann können aufeinanderfolgende Tupel in eine Liste gespeichert werden.
Das ganze ist in Python erfreulich einfach:
#!/usr/bin/python3
import serial
# python3 -m pip install pyserial
ser = serial.Serial('/dev/ttyUSB0' , 9600) # Schnittstelle öffnen.
print(ser.name) # Kontrollieren welcher Port verwendet wurde.
# Auf korrekte Startposition warten:
dump = 0
while dump < 230:
dump = ser.read(1)[0]
print(".")
# Testweise eine Liste mit korrekt angeordneten Unterlisten erstellen.
testliste = []
fensterbreite = 1000
for j in range(0,fensterbreite):
test1 = []
for i in range(0,4):
test1.append(ser.read(1)[0])
del test1[-1]
testliste.append(test1)
print(testliste)
ser.close() # Schnittstelle schließen.
Eine statische Anzeige
Jetzt stellt sich die Frage wie die eingelesenen Daten angezeigt werden. Das vermutlich bekannteste Tool zum plotten von Graphen ist die matplotlib.
Ein erster Schritt ist es die 3x10 Werte aus der “testliste” statisch in drei übereinander dargestellten Plots anzuzeigen.
import numpy as np
import matplotlib.pyplot as plt
# Das 3xN array in 3 1xN arrays aufteilen:
testlistea = np.array(testliste)
testliste1 = testlistea[:,0]
testliste2 = testlistea[:,1]
testliste3 = testlistea[:,2]
plt.figure(1)
plt.subplot(311)
plt.plot(testliste1)
plt.subplot(312)
plt.plot(testliste2)
plt.subplot(313)
plt.plot(testliste3)
plt.show()
Das funktioniert bereits erwartungsgemäß. Möglicherweise lässt sich noch ein etwas saubereres Ergebnis erzielen wenn die Verstärker auf dem Board nachjustiert werden. (Schließlich lag das Ding die letzten paar Jahre unbenutzt herum.)
Eine dynamische Anzeige
Damit das ganze mit dem Auge angenehm zu verfolgen ist soll sich die Kurve bei der Echtzeitanzeige nicht bewegen, sondern kontinuierlich nach rechts erweitert werden. Ist dann ein Plot gefüllt, wird er durch einen neuen leeren Plot ersetzt der dann wieder von links nach rechts gefüllt wird.
Notizen:
- Datenrate: 9600 Baud 8bit Pro Symbol; 1200 Byte/s; 4 Byte / Datensatz; 300 Datensätze/s