Home    DE    EN
Projekte
Netzfrequenz
Stimme der Protonen
MCP3201 ADC -> RPI
Protonen-Mag I
Protonen-Mag II
Proton-Marine-Mag
UV Platinenbelichter
Labornetzteil
Mess-Lichtschranke
Seltsamer Sensor
Solar-Regler Hack
Pedal mit 270° Poti
ABPM50
Sonstiges
China!
Über mich
 

Dateiformat des ABPM50 24h-Blutdruckmessgerätes

Hinweis: Leider ist diese Seite nicht mehr aktuell. Der Hersteller hat offenbar das Fileformat geändert. Wenn sich in Ihrer .awp-Datei die Zeilen "FileVersion_Main=2" und "FileVersion_Sub=0" finden, sollte dieses Macro funktionieren: ReadAbpm50FileNewFF.txt. Vielen Dank an Christoph für die Anpassungen!

Beim Thema Blutdruckmessungen gibt es zwei Dinge, die mich immer wieder ärgern:

  1. Einzelne Messungen, die man "kommen sieht". Bei der extremen Variabilität von Blutdruckmessungen, Aufregung durch "Weisskitteleffekt" usw., halte ich Einzelmessungen, auch zu Hause, für nahezu nutzlos. Nur periodische Messungen, die sozusagen ohne Vorwarnung erfolgen, haben, ab einer gewissen Anzahl, Aussagekraft. Sogar Selbstmessungen halte ich für fragwürdig, da es meiner Meinung nach nicht nur einen Weisskitteleffekt, sondern auch einen "Messgeräte-Anblick/Pumpgeräusch-Effekt" gibt. Letztendlich sogar die Angst, dass wieder eine hohe Zahl herauskommt und jemand sagt "das ist aber hoch" - Ein Teufelskreis.

  2. Praktisch jedes Oberarm-Blutdruckmessgerät könnte zeitgesteuerte Messungen durchführen. In einfacher Form wäre das mit wenigen Codezeilen in den eingesetzten Mikrocontrollern machbar. Selbst mit einer simplen "Memory-Funktion" ohne Exportmöglichkeit hätte man so eine günstige Möglichkeit, wirklich sinnvolle Werte zu ermitteln. Aber alle typischen Messgeräte bieten diese Möglichkeit nicht. Wenigstens eine Funktion, die mit einer zufälligen Verzögerung eine "Überraschungsmessung" durchführt, wäre schon eine interessante Sache. Aber offensichtlich traut sich da keine Firma heran, vermutlich da sich niemand mit den Herstellern der Höchstpreis-24h-Messgeräte und der Ärtztelobby, die ja Langzeitmessungen durchführen, anlegen möchte.

Mein Lob gilt daher der Firma Contec, die mit ihrem ABPM50 den anderen, exorbitant teuren Langzeitmessgeräten zeigt, was für relativ wenig Geld machbar ist:

ABPM50

Ich möchte jetzt gar nicht lange auf das Gerät selbst eingehen, im Internet finden sich genug Berichte darüber. Meine Kritikpunkte sind schnell aufgezählt: Die Markierung des aktiven Menüpunktes, mit einem fast nicht sichtbaren Wechsel eines weissen auf einen gelben Rahmen, ist nur bei genauem Hinsehen erkennbar. Der zweite Punkt betrifft die Software. Sie ist nicht wirklich schön, der Report könnte mal eine Überarbeitung brauchen,... viele kosmetische Punkte. Aber wirklich schade: Ich habe keine Möglichkeit für den Datenexport gefunden!

Die Messwerte werden in Dateien mit der Endung ".awp" gespeichert. Ich habe nun durch "Reverse-Engineering" das Datenformat zumindest teilweise analysiert und ein Excel-Macro geschrieben, welchen den Import in Excel ermöglicht. Da ich annehme, dass sich auch andere Anwender dafür interessieren, möchte ich hier meine Erkenntnisse vorstellen.

Die .awp-Dateien sind erfreulicherweise recht übersichtliche Textdateien, die z.B. mit "notepad" gesichtet werden können. Leicht ist zu erkennen, dass die Messungen in Zeilen mit Hexadezimalzahlen gespeichert werden. Nach einem tiefen Blick darauf, konnte ich das Geheimnis lüften. Ein Lob an die Entwickler, es ist pragmatisch und einfach zu verarbeiten. Das Zeilenformat ist offenbar wie folgt aufgebaut:

     Messungsnummer
     |       Systolischer Druck in mmHg (2-stellige Hexadezimalzahl), 74(hex) = 116(dez)
     |       | Diastolischer Druck, 43(hex) = 67(dez)
     |       | | Pulsrate in Schlägen pro Minute, 44(hex) = 68(dez)
     |       | | | Mittlerer arterieller Druck, 52(hex) = 82(dez)
     |       | | | | Minuten seit Messungsstart (4-stellige Hexadezimalzahl), 04C4(hex) = 1220(dez)
     |       | | | | |
     |       ssddppaammmm??
     149=00007443445204C4030000000
     148=000072433A4F04BF030000000
     147=0000784B3B5904BA030000000
     146=00007947395504B5030000000

Unklar bleiben die beiden "??", vermutlich handelt es sich hierbei um Markierungsbits für nachträglich im Download-Programm von Contec nachbearbeitete Messungen. Die Information über die Minuten seit Messungsstart erfordert nun den eigentlichen Startzeitpunkt, das tatsächliche Datum mit Uhrzeit berechnen zu können. Dieser findet sich in folgenden Zeilen:

     MinBegin=40
     HourBegin=14
     DayBegin=25
     MonthBegin=7
     YearBegin=2008

Die Sprache, Visual Basic, in der Excel-Macros verfasst werden können, bietet alle notwendigen Funktionen, um die Daten einlesen zu können: Dateien öffnen und lesen, Zeichenketten durchsuchen und zerschneiden, Hexadezimalzahlen in Dezimalzahlen konvertieren.

Hier ein einfaches Excel-Macro, welches .awp-Dateien liesst und die Messdaten in eine Tabelle mit folgenden Spalten einträgt (MAP = Mittlerer arterieller Druck, HR = Pulsrate):

     Nummer Datum/Zeit Sys Dia MAP HR

Das Macro kann einfach über den Visual-Basic Editor in eine Excel-Datei eingefügt werden:

Sub ReadAbpm50File()
'
' Einfaches Macro zum Einlesen einer Messwertdatei des ABPM50
'
    fName = Application.GetOpenFilename("ABPM50 Dateien (*.awp), *.awp")
    If fName = "" Or fName = False Then
        MsgBox "Dateiauswahl - Abbruch"
        Exit Sub
    End If
    Columns("A:F").Select    ' Achtung!
    Selection.ClearContents  ' Hier wird beim Lauf des Macros geloescht!
    i = 1
    Cells(i, 1).Value = "Nummer"         ' Spaltenueberschriften
    Cells(i, 2).Value = "Datum/Zeit"
    Cells(i, 3).Value = "Sys"
    Cells(i, 4).Value = "Dia"
    Cells(i, 5).Value = "MAP"
    Cells(i, 6).Value = "HR"
    i = i + 1
    Open fName For Input As #1                                    ' Datei zum Lesen oeffnen
        Do Until EOF(1)                                           ' So lange bis Dateiende erreicht:
            Line Input #1, txt                                    ' Zeile aus Datei lesen
            If InStr(txt, "=") Then                               ' Zeile mit Gleichzeichen?
            txtL = Left(txt, InStr(txt, "=") - 1)                 ' Text links vom Gleichzeichen
            txtR = Right(txt, Len(txt) - InStr(txt, "="))         ' Text rechts vom Gleichzeichen
            If IsNumeric(txtL) Then                               ' Zahl links? Dann Messung gefunden!
                Cells(i, 1).EntireRow.Clear                       ' Zeile in Tabelle loeschen
                Cells(i, 1).Value = Val(txtL)                     ' Nummer
                Cells(i, 2).Value = Val("&H" + Mid(txtR, 13, 4))  ' Minuten seit Start (mit Hex-Dez-Umwandlung)
                Cells(i, 3).Value = Val("&H" + Mid(txtR, 5, 2))   ' Sys (mit Hex-Dez-Umwandlung)
                Cells(i, 4).Value = Val("&H" + Mid(txtR, 7, 2))   ' Dia (mit Hex-Dez-Umwandlung)
                Cells(i, 5).Value = Val("&H" + Mid(txtR, 11, 2))  ' MAP (mit Hex-Dez-Umwandlung)
                Cells(i, 6).Value = Val("&H" + Mid(txtR, 9, 2))   ' HR  (mit Hex-Dez-Umwandlung)
                i = i + 1
            ElseIf txtL = "MinBegin" Then    ' Start Minuten gefunden
                minBegin = txtR              ' Merken
            ElseIf txtL = "HourBegin" Then   ' Start Stunden gefunden
                hourBegin = txtR             ' Merken
            ElseIf txtL = "DayBegin" Then    ' Start Tag gefunden
                dayBegin = txtR              ' Merken
            ElseIf txtL = "MonthBegin" Then  ' Start Monat gefunden
                monthBegin = txtR            ' Merken
            ElseIf txtL = "YearBegin" Then   ' Start Jahr gefunden
                yearBegin = txtR             ' Merken
            End If
         End If
      Loop
   Close
   startDate = yearBegin + "-" + monthBegin + "-" + dayBegin + " " + hourBegin + ":" + minBegin
   If IsDate(startDate) = False Then        ' Gefundenes Startdatum pruefen
      MsgBox "Abbruch - Kein Startdatum"
      Exit Sub
   End If
   While i > 2        ' Tabelle rueckwaerts durchlaufen und Minuten in echtes Datum umwandeln
        i = i - 1
        minutes = Cells(i, 2).Value
        Cells(i, 2).Value = CDate(startDate) + minutes / 24 / 60
        Cells(i, 2).NumberFormat = "DD.MM.YYYY hh:mm"
   Wend
   Columns("A:F").Select   ' Vorsichtshalber sortieren
   Selection.Sort Key1:=Range("A2"), Order1:=xlAscending, Header:=xlGuess, OrderCustom:=1, Orientation:=xlTopToBottom
   Range("A1").Select
End Sub

Sicher kann man noch viel verfeinern, von Variablendeklarationen bis hin zur automatische Erzeugung eines Diagramms. Ich möchte hier aber bewusst nur ein möglichst übersichtliches Grundgerüst für eigene Erweiterungen vorstellen.

Oktober 2017

© 2024 Alexander Mumm