From 92812e5ad255452535c0d95e4427df443d2ec134 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Wed, 5 May 2021 21:06:39 +0100 Subject: [PATCH] apps: heart: Implement a debug mode to copy out raw data Signed-off-by: Daniel Thompson --- wasp/apps/heart.py | 40 +++++++++++++++++++++++++++++++++++++++- wasp/ppg.py | 18 ++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/wasp/apps/heart.py b/wasp/apps/heart.py index 541e57d..5d181b0 100644 --- a/wasp/apps/heart.py +++ b/wasp/apps/heart.py @@ -8,6 +8,28 @@ A graphing heart rate monitor using a PPG sensor. .. figure:: res/HeartApp.png :width: 179 + +This program also implements some (entirely optional) debug features to +store the raw heart data to the filesystem so that the samples can be used +to further refine the heart rate detection algorithm. + +To enable the logging feature select the heart rate application using the +watch UI and then run the following command via wasptool: + +.. code-block:: sh + + ./tools/wasptool --eval 'wasp.system.app.debug = True' + +Once debug has been enabled then the watch will automatically log heart +rate data whenever the heart rate application is running (and only +when it is running). Setting the debug flag to False will disable the +logging when the heart rate monitor next exits. + +Finally to download the logs for analysis try: + +.. code-block:: sh + + ./tools/wasptool --pull hrs.data """ import wasp @@ -18,6 +40,10 @@ class HeartApp(): """Heart rate monitor application.""" NAME = 'Heart' + def __init__(self): + self._debug = False + self._hrdata = None + def foreground(self): """Activate the application.""" wasp.watch.hrs.enable() @@ -32,11 +58,13 @@ class HeartApp(): wasp.system.request_tick(1000 // 8) self._hrdata = ppg.PPG(wasp.watch.hrs.read_hrs()) + if self._debug: + self._hrdata.enable_debug() self._x = 0 def background(self): wasp.watch.hrs.disable() - del self._hrdata + self._hrdata = None def _subtick(self, ticks): """Notify the application that its periodic tick is due.""" @@ -87,3 +115,13 @@ class HeartApp(): t.stop() del t + + @property + def debug(self): + return self._debug + + @debug.setter + def debug(self, value): + self._debug = value + if value and self._hrdata: + self._hrdata.enable_debug() diff --git a/wasp/ppg.py b/wasp/ppg.py index 324392d..4fe0ab2 100644 --- a/wasp/ppg.py +++ b/wasp/ppg.py @@ -10,6 +10,7 @@ raw PPG signals into something useful. import array import micropython +import watch @micropython.viper def _compare(d1, d2, count: int, shift: int) -> int: @@ -94,6 +95,7 @@ class PPG(): def __init__(self, spl): self._offset = spl self.data = array.array('b') + self.debug = None self._hpf = Biquad(0.87033078, -1.74066156, 0.87033078, -1.72377617, 0.75754694) @@ -106,6 +108,8 @@ class PPG(): Must be called at 24Hz for accurate heart rate calculations. """ + if self.debug != None: + self.debug.append(spl) spl -= self._offset spl = self._hpf.step(spl) spl = self._agc.step(spl) @@ -167,4 +171,18 @@ class PPG(): # Clear out the accumulated data self.data = array.array('b') + # Dump the debug data + if self.debug: + with open('hrs.data', 'ab') as f: + # Re-sync marker + f.write(b'\xff\xff') + now = watch.rtc.get_localtime() + f.write(array.array('H', now[:6])) + f.write(self.debug) + self.debug = array.array('H') + return hr + + def enable_debug(self): + if self.debug == None: + self.debug = array.array('H')