I've got some basic filter code setup (but not yet tested).
Dependencies: BLE_API Queue mbed nRF51822
Fork of BLE_HeartRate by
noisechk.cpp@62:8e2fbe131b53, 2015-06-28 (annotated)
- Committer:
- roysandberg
- Date:
- Sun Jun 28 03:06:00 2015 +0000
- Revision:
- 62:8e2fbe131b53
Working Beat Detection and Analysis
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
roysandberg | 62:8e2fbe131b53 | 1 | /***************************************************************************** |
roysandberg | 62:8e2fbe131b53 | 2 | FILE: noisechk.cpp |
roysandberg | 62:8e2fbe131b53 | 3 | AUTHOR: Patrick S. Hamilton |
roysandberg | 62:8e2fbe131b53 | 4 | REVISED: 5/13/2002 |
roysandberg | 62:8e2fbe131b53 | 5 | ___________________________________________________________________________ |
roysandberg | 62:8e2fbe131b53 | 6 | |
roysandberg | 62:8e2fbe131b53 | 7 | noisechk.cpp: Noise Check |
roysandberg | 62:8e2fbe131b53 | 8 | Copywrite (C) 2001 Patrick S. Hamilton |
roysandberg | 62:8e2fbe131b53 | 9 | |
roysandberg | 62:8e2fbe131b53 | 10 | This file is free software; you can redistribute it and/or modify it under |
roysandberg | 62:8e2fbe131b53 | 11 | the terms of the GNU Library General Public License as published by the Free |
roysandberg | 62:8e2fbe131b53 | 12 | Software Foundation; either version 2 of the License, or (at your option) any |
roysandberg | 62:8e2fbe131b53 | 13 | later version. |
roysandberg | 62:8e2fbe131b53 | 14 | |
roysandberg | 62:8e2fbe131b53 | 15 | This software is distributed in the hope that it will be useful, but WITHOUT ANY |
roysandberg | 62:8e2fbe131b53 | 16 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
roysandberg | 62:8e2fbe131b53 | 17 | PARTICULAR PURPOSE. See the GNU Library General Public License for more |
roysandberg | 62:8e2fbe131b53 | 18 | details. |
roysandberg | 62:8e2fbe131b53 | 19 | |
roysandberg | 62:8e2fbe131b53 | 20 | You should have received a copy of the GNU Library General Public License along |
roysandberg | 62:8e2fbe131b53 | 21 | with this library; if not, write to the Free Software Foundation, Inc., 59 |
roysandberg | 62:8e2fbe131b53 | 22 | Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
roysandberg | 62:8e2fbe131b53 | 23 | |
roysandberg | 62:8e2fbe131b53 | 24 | You may contact the author by e-mail (pat@eplimited.edu) or postal mail |
roysandberg | 62:8e2fbe131b53 | 25 | (Patrick Hamilton, E.P. Limited, 35 Medford St., Suite 204 Somerville, |
roysandberg | 62:8e2fbe131b53 | 26 | MA 02143 USA). For updates to this software, please visit our website |
roysandberg | 62:8e2fbe131b53 | 27 | (http://www.eplimited.com). |
roysandberg | 62:8e2fbe131b53 | 28 | __________________________________________________________________________ |
roysandberg | 62:8e2fbe131b53 | 29 | |
roysandberg | 62:8e2fbe131b53 | 30 | This file contains functions for evaluating the noise content of a beat. |
roysandberg | 62:8e2fbe131b53 | 31 | |
roysandberg | 62:8e2fbe131b53 | 32 | *****************************************************************************/ |
roysandberg | 62:8e2fbe131b53 | 33 | |
roysandberg | 62:8e2fbe131b53 | 34 | //#include <stdlib.h> |
roysandberg | 62:8e2fbe131b53 | 35 | #include <mbed.h> |
roysandberg | 62:8e2fbe131b53 | 36 | #include "qrsdet.h" |
roysandberg | 62:8e2fbe131b53 | 37 | |
roysandberg | 62:8e2fbe131b53 | 38 | #define NB_LENGTH MS1500 |
roysandberg | 62:8e2fbe131b53 | 39 | #define NS_LENGTH MS50 |
roysandberg | 62:8e2fbe131b53 | 40 | |
roysandberg | 62:8e2fbe131b53 | 41 | int NoiseBuffer[NB_LENGTH], NBPtr = 0 ; |
roysandberg | 62:8e2fbe131b53 | 42 | int NoiseEstimate ; |
roysandberg | 62:8e2fbe131b53 | 43 | |
roysandberg | 62:8e2fbe131b53 | 44 | /************************************************************************ |
roysandberg | 62:8e2fbe131b53 | 45 | GetNoiseEstimate() allows external access the present noise estimate. |
roysandberg | 62:8e2fbe131b53 | 46 | this function is only used for debugging. |
roysandberg | 62:8e2fbe131b53 | 47 | *************************************************************************/ |
roysandberg | 62:8e2fbe131b53 | 48 | |
roysandberg | 62:8e2fbe131b53 | 49 | int GetNoiseEstimate() |
roysandberg | 62:8e2fbe131b53 | 50 | { |
roysandberg | 62:8e2fbe131b53 | 51 | return(NoiseEstimate) ; |
roysandberg | 62:8e2fbe131b53 | 52 | } |
roysandberg | 62:8e2fbe131b53 | 53 | |
roysandberg | 62:8e2fbe131b53 | 54 | /*********************************************************************** |
roysandberg | 62:8e2fbe131b53 | 55 | NoiseCheck() must be called for every sample of data. The data is |
roysandberg | 62:8e2fbe131b53 | 56 | stored in a circular buffer to facilitate noise analysis. When a |
roysandberg | 62:8e2fbe131b53 | 57 | beat is detected NoiseCheck() is passed the sample delay since the |
roysandberg | 62:8e2fbe131b53 | 58 | R-wave of the beat occurred (delay), the RR interval between this |
roysandberg | 62:8e2fbe131b53 | 59 | beat and the next most recent beat, the estimated offset from the |
roysandberg | 62:8e2fbe131b53 | 60 | R-wave to the beginning of the beat (beatBegin), and the estimated |
roysandberg | 62:8e2fbe131b53 | 61 | offset from the R-wave to the end of the beat. |
roysandberg | 62:8e2fbe131b53 | 62 | |
roysandberg | 62:8e2fbe131b53 | 63 | NoiseCheck() estimates the noise in the beat by the maximum and |
roysandberg | 62:8e2fbe131b53 | 64 | minimum signal values in either a window from the end of the |
roysandberg | 62:8e2fbe131b53 | 65 | previous beat to the beginning of the present beat, or a 250 ms |
roysandberg | 62:8e2fbe131b53 | 66 | window preceding the present beat, which ever is shorter. |
roysandberg | 62:8e2fbe131b53 | 67 | |
roysandberg | 62:8e2fbe131b53 | 68 | NoiseCheck() returns ratio of the signal variation in the window |
roysandberg | 62:8e2fbe131b53 | 69 | between beats to the length of the window between the beats. If |
roysandberg | 62:8e2fbe131b53 | 70 | the heart rate is too high and the beat durations are too long, |
roysandberg | 62:8e2fbe131b53 | 71 | NoiseCheck() returns 0. |
roysandberg | 62:8e2fbe131b53 | 72 | |
roysandberg | 62:8e2fbe131b53 | 73 | ***********************************************************************/ |
roysandberg | 62:8e2fbe131b53 | 74 | |
roysandberg | 62:8e2fbe131b53 | 75 | int NoiseCheck(int datum, int delay, int RR, int beatBegin, int beatEnd) |
roysandberg | 62:8e2fbe131b53 | 76 | { |
roysandberg | 62:8e2fbe131b53 | 77 | int ptr, i; |
roysandberg | 62:8e2fbe131b53 | 78 | int ncStart, ncEnd, ncMax, ncMin ; |
roysandberg | 62:8e2fbe131b53 | 79 | double noiseIndex ; |
roysandberg | 62:8e2fbe131b53 | 80 | |
roysandberg | 62:8e2fbe131b53 | 81 | NoiseBuffer[NBPtr] = datum ; |
roysandberg | 62:8e2fbe131b53 | 82 | if(++NBPtr == NB_LENGTH) |
roysandberg | 62:8e2fbe131b53 | 83 | NBPtr = 0 ; |
roysandberg | 62:8e2fbe131b53 | 84 | |
roysandberg | 62:8e2fbe131b53 | 85 | // Check for noise in region that is 300 ms following |
roysandberg | 62:8e2fbe131b53 | 86 | // last R-wave and 250 ms preceding present R-wave. |
roysandberg | 62:8e2fbe131b53 | 87 | |
roysandberg | 62:8e2fbe131b53 | 88 | ncStart = delay+RR-beatEnd ; // Calculate offset to end of previous beat. |
roysandberg | 62:8e2fbe131b53 | 89 | ncEnd = delay+beatBegin ; // Calculate offset to beginning of this beat. |
roysandberg | 62:8e2fbe131b53 | 90 | if(ncStart > ncEnd + MS250) |
roysandberg | 62:8e2fbe131b53 | 91 | ncStart = ncEnd + MS250 ; |
roysandberg | 62:8e2fbe131b53 | 92 | |
roysandberg | 62:8e2fbe131b53 | 93 | |
roysandberg | 62:8e2fbe131b53 | 94 | // Estimate noise if delay indicates a beat has been detected, |
roysandberg | 62:8e2fbe131b53 | 95 | // the delay is not to long for the data buffer, and there is |
roysandberg | 62:8e2fbe131b53 | 96 | // some space between the end of the last beat and the beginning |
roysandberg | 62:8e2fbe131b53 | 97 | // of this beat. |
roysandberg | 62:8e2fbe131b53 | 98 | |
roysandberg | 62:8e2fbe131b53 | 99 | if((delay != 0) && (ncStart < NB_LENGTH) && (ncStart > ncEnd)) |
roysandberg | 62:8e2fbe131b53 | 100 | { |
roysandberg | 62:8e2fbe131b53 | 101 | |
roysandberg | 62:8e2fbe131b53 | 102 | ptr = NBPtr - ncStart ; // Find index to end of last beat in |
roysandberg | 62:8e2fbe131b53 | 103 | if(ptr < 0) // the circular buffer. |
roysandberg | 62:8e2fbe131b53 | 104 | ptr += NB_LENGTH ; |
roysandberg | 62:8e2fbe131b53 | 105 | |
roysandberg | 62:8e2fbe131b53 | 106 | // Find the maximum and minimum values in the |
roysandberg | 62:8e2fbe131b53 | 107 | // isoelectric region between beats. |
roysandberg | 62:8e2fbe131b53 | 108 | |
roysandberg | 62:8e2fbe131b53 | 109 | ncMax = ncMin = NoiseBuffer[ptr] ; |
roysandberg | 62:8e2fbe131b53 | 110 | for(i = 0; i < ncStart-ncEnd; ++i) |
roysandberg | 62:8e2fbe131b53 | 111 | { |
roysandberg | 62:8e2fbe131b53 | 112 | if(NoiseBuffer[ptr] > ncMax) |
roysandberg | 62:8e2fbe131b53 | 113 | ncMax = NoiseBuffer[ptr] ; |
roysandberg | 62:8e2fbe131b53 | 114 | else if(NoiseBuffer[ptr] < ncMin) |
roysandberg | 62:8e2fbe131b53 | 115 | ncMin = NoiseBuffer[ptr] ; |
roysandberg | 62:8e2fbe131b53 | 116 | if(++ptr == NB_LENGTH) |
roysandberg | 62:8e2fbe131b53 | 117 | ptr = 0 ; |
roysandberg | 62:8e2fbe131b53 | 118 | } |
roysandberg | 62:8e2fbe131b53 | 119 | |
roysandberg | 62:8e2fbe131b53 | 120 | // The noise index is the ratio of the signal variation |
roysandberg | 62:8e2fbe131b53 | 121 | // over the isoelectric window length, scaled by 10. |
roysandberg | 62:8e2fbe131b53 | 122 | |
roysandberg | 62:8e2fbe131b53 | 123 | noiseIndex = (ncMax-ncMin) ; |
roysandberg | 62:8e2fbe131b53 | 124 | noiseIndex /= (ncStart-ncEnd) ; |
roysandberg | 62:8e2fbe131b53 | 125 | NoiseEstimate = noiseIndex * 10 ; |
roysandberg | 62:8e2fbe131b53 | 126 | } |
roysandberg | 62:8e2fbe131b53 | 127 | else |
roysandberg | 62:8e2fbe131b53 | 128 | NoiseEstimate = 0 ; |
roysandberg | 62:8e2fbe131b53 | 129 | return(NoiseEstimate) ; |
roysandberg | 62:8e2fbe131b53 | 130 | } |
roysandberg | 62:8e2fbe131b53 | 131 |