I've got some basic filter code setup (but not yet tested).

Dependencies:   BLE_API Queue mbed nRF51822

Fork of BLE_HeartRate by Bluetooth Low Energy

Revision:
62:8e2fbe131b53
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postclas.cpp	Sun Jun 28 03:06:00 2015 +0000
@@ -0,0 +1,234 @@
+/*****************************************************************************
+FILE:  postclas.cpp
+AUTHOR: Patrick S. Hamilton
+REVISED:    5/13/2002
+  ___________________________________________________________________________
+
+postclas.cpp: Post classifier
+Copywrite (C) 2002 Patrick S. Hamilton
+
+This file is free software; you can redistribute it and/or modify it under
+the terms of the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option) any
+later version.
+
+This software is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.  See the GNU Library General Public License for more
+details.
+
+You should have received a copy of the GNU Library General Public License along
+with this library; if not, write to the Free Software Foundation, Inc., 59
+Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+You may contact the author by e-mail (pat@eplimited.edu) or postal mail
+(Patrick Hamilton, E.P. Limited, 35 Medford St., Suite 204 Somerville,
+MA 02143 USA).  For updates to this software, please visit our website
+(http://www.eplimited.com).
+  __________________________________________________________________________
+
+This file contains functions for classifying beats based after the
+following beat is detected.
+
+    ResetPostClassify() -- Resets static variables used by
+        PostClassify()
+    PostClassify() -- classifies each beat based on six preceding
+        beats and the following beat.
+    CheckPostClass() --  classifys beat type based on the last
+        eight post classifications of that beat.
+    CheckPCRhythm() -- returns the classification of the RR interval
+        for this type of beat based its previous eight RR intervals.
+
+****************************************************************/
+
+#include <mbed.h>
+#include "bdac.h"
+#include "ecgcodes.h"
+
+// External Prototypes.
+
+double DomCompare(int newType, int domType) ;
+int GetBeatTypeCount(int type) ;
+
+// Records of post classifications.
+
+int PostClass[MAXTYPES][8], PCInitCount = 0 ;
+int PCRhythm[MAXTYPES][8] ;
+
+/**********************************************************************
+ Resets post classifications for beats.
+**********************************************************************/
+
+void ResetPostClassify()
+    {
+    int i, j ;
+    for(i = 0; i < MAXTYPES; ++i)
+        for(j = 0; j < 8; ++j)
+            {
+            PostClass[i][j] = 0 ;
+            PCRhythm[i][j] = 0 ;
+            }
+    PCInitCount = 0 ;
+    }
+
+/***********************************************************************
+    Classify the previous beat type and rhythm type based on this beat
+    and the preceding beat.  This classifier is more sensitive
+    to detecting premature beats followed by compensitory pauses.
+************************************************************************/
+
+void PostClassify(int *recentTypes, int domType, int *recentRRs, int width, double mi2,
+    int rhythmClass)
+    {
+    static int lastRC, lastWidth ;
+    static double lastMI2 ;
+    int i, regCount, pvcCount, normRR ;
+    double mi3 ;
+
+    // If the preceeding and following beats are the same type,
+    // they are generally regular, and reasonably close in shape
+    // to the dominant type, consider them to be dominant.
+
+    if((recentTypes[0] == recentTypes[2]) && (recentTypes[0] != domType)
+        && (recentTypes[0] != recentTypes[1]))
+        {
+        mi3 = DomCompare(recentTypes[0],domType) ;
+        for(i = regCount = 0; i < 8; ++i)
+            if(PCRhythm[recentTypes[0]][i] == NORMAL)
+                ++regCount ;
+        if((mi3 < 2.0) && (regCount > 6))
+            domType = recentTypes[0] ;
+        }
+
+    // Don't do anything until four beats have gone by.
+
+    if(PCInitCount < 3)
+        {
+        ++PCInitCount ;
+        lastWidth = width ;
+        lastMI2 = 0 ;
+        lastRC = 0 ;
+        return ;
+        }
+
+    if(recentTypes[1] < MAXTYPES)
+        {
+
+        // Find first NN interval.
+        for(i = 2; (i < 7) && (recentTypes[i] != recentTypes[i+1]); ++i) ;
+        if(i == 7) normRR = 0 ;
+        else normRR = recentRRs[i] ;
+
+        // Shift the previous beat classifications to make room for the
+        // new classification.
+        for(i = pvcCount = 0; i < 8; ++i)
+            if(PostClass[recentTypes[1]][i] == PVC)
+                ++pvcCount ;
+
+        for(i = 7; i > 0; --i)
+            {
+            PostClass[recentTypes[1]][i] = PostClass[recentTypes[1]][i-1] ;
+            PCRhythm[recentTypes[1]][i] = PCRhythm[recentTypes[1]][i-1] ;
+            }
+
+        // If the beat is premature followed by a compensitory pause and the
+        // previous and following beats are normal, post classify as
+        // a PVC.
+
+        if(((normRR-(normRR>>3)) >= recentRRs[1]) && ((recentRRs[0]-(recentRRs[0]>>3)) >= normRR)// && (lastMI2 > 3)
+            && (recentTypes[0] == domType) && (recentTypes[2] == domType)
+                && (recentTypes[1] != domType))
+            PostClass[recentTypes[1]][0] = PVC ;
+
+        // If previous two were classified as PVCs, and this is at least slightly
+        // premature, classify as a PVC.
+
+        else if(((normRR-(normRR>>4)) > recentRRs[1]) && ((normRR+(normRR>>4)) < recentRRs[0]) &&
+            (((PostClass[recentTypes[1]][1] == PVC) && (PostClass[recentTypes[1]][2] == PVC)) ||
+                (pvcCount >= 6) ) &&
+            (recentTypes[0] == domType) && (recentTypes[2] == domType) && (recentTypes[1] != domType))
+            PostClass[recentTypes[1]][0] = PVC ;
+
+        // If the previous and following beats are the dominant beat type,
+        // and this beat is significantly different from the dominant,
+        // call it a PVC.
+
+        else if((recentTypes[0] == domType) && (recentTypes[2] == domType) && (lastMI2 > 2.5))
+            PostClass[recentTypes[1]][0] = PVC ;
+
+        // Otherwise post classify this beat as UNKNOWN.
+
+        else PostClass[recentTypes[1]][0] = UNKNOWN ;
+
+        // If the beat is premature followed by a compensitory pause, post
+        // classify the rhythm as PVC.
+
+        if(((normRR-(normRR>>3)) > recentRRs[1]) && ((recentRRs[0]-(recentRRs[0]>>3)) > normRR))
+            PCRhythm[recentTypes[1]][0] = PVC ;
+
+        // Otherwise, post classify the rhythm as the same as the
+        // regular rhythm classification.
+
+        else PCRhythm[recentTypes[1]][0] = lastRC ;
+        }
+
+    lastWidth = width ;
+    lastMI2 = mi2 ;
+    lastRC = rhythmClass ;
+    }
+
+
+/*************************************************************************
+    CheckPostClass checks to see if three of the last four or six of the
+    last eight of a given beat type have been post classified as PVC.
+*************************************************************************/
+
+int CheckPostClass(int type)
+    {
+    int i, pvcs4 = 0, pvcs8 ;
+
+    if(type == MAXTYPES)
+        return(UNKNOWN) ;
+
+    for(i = 0; i < 4; ++i)
+        if(PostClass[type][i] == PVC)
+            ++pvcs4 ;
+    for(pvcs8=pvcs4; i < 8; ++i)
+        if(PostClass[type][i] == PVC)
+            ++pvcs8 ;
+
+    if((pvcs4 >= 3) || (pvcs8 >= 6))
+        return(PVC) ;
+    else return(UNKNOWN) ;
+    }
+
+/****************************************************************************
+    Check classification of previous beats' rhythms based on post beat
+    classification.  If 7 of 8 previous beats were classified as NORMAL
+    (regular) classify the beat type as NORMAL (regular).
+    Call it a PVC if 2 of the last 8 were regular.
+****************************************************************************/
+
+int CheckPCRhythm(int type)
+    {
+    int i, normCount, n ;
+
+
+    if(type == MAXTYPES)
+        return(UNKNOWN) ;
+
+    if(GetBeatTypeCount(type) < 9)
+        n = GetBeatTypeCount(type)-1 ;
+    else n = 8 ;
+
+    for(i = normCount = 0; i < n; ++i)
+        if(PCRhythm[type][i] == NORMAL)
+            ++normCount;
+    if(normCount >= 7)
+        return(NORMAL) ;
+    if(((normCount == 0) && (n < 4)) ||
+        ((normCount <= 1) && (n >= 4) && (n < 7)) ||
+        ((normCount <= 2) && (n >= 7)))
+        return(PVC) ;
+    return(UNKNOWN) ;
+    }
\ No newline at end of file