maxrefdes117

Committer:
zinnetyazicii53
Date:
Tue Aug 06 12:19:46 2019 +0000
Revision:
0:78a2573ad768
commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zinnetyazicii53 0:78a2573ad768 1 #include "heartRate.h"
zinnetyazicii53 0:78a2573ad768 2 int16_t IR_AC_Max = 20;
zinnetyazicii53 0:78a2573ad768 3 int16_t IR_AC_Min = -20;
zinnetyazicii53 0:78a2573ad768 4
zinnetyazicii53 0:78a2573ad768 5 int16_t IR_AC_Signal_Current = 0;
zinnetyazicii53 0:78a2573ad768 6 int16_t IR_AC_Signal_Previous;
zinnetyazicii53 0:78a2573ad768 7 int16_t IR_AC_Signal_min = 0;
zinnetyazicii53 0:78a2573ad768 8 int16_t IR_AC_Signal_max = 0;
zinnetyazicii53 0:78a2573ad768 9 int16_t IR_Average_Estimated;
zinnetyazicii53 0:78a2573ad768 10
zinnetyazicii53 0:78a2573ad768 11 int16_t positiveEdge = 0;
zinnetyazicii53 0:78a2573ad768 12 int16_t negativeEdge = 0;
zinnetyazicii53 0:78a2573ad768 13 int32_t ir_avg_reg = 0;
zinnetyazicii53 0:78a2573ad768 14
zinnetyazicii53 0:78a2573ad768 15 int16_t cbuf[32];
zinnetyazicii53 0:78a2573ad768 16 uint8_t offset = 0;
zinnetyazicii53 0:78a2573ad768 17 static const uint16_t FIRCoeffs[12] = {172, 321, 579, 927, 1360, 1858, 2390, 2916, 3391, 3768, 4012, 4096};
zinnetyazicii53 0:78a2573ad768 18
zinnetyazicii53 0:78a2573ad768 19 bool heartRate::checkForBeat(int32_t sample)
zinnetyazicii53 0:78a2573ad768 20 {
zinnetyazicii53 0:78a2573ad768 21 bool beatDetected = false;
zinnetyazicii53 0:78a2573ad768 22
zinnetyazicii53 0:78a2573ad768 23 // Save current state
zinnetyazicii53 0:78a2573ad768 24 IR_AC_Signal_Previous = IR_AC_Signal_Current;
zinnetyazicii53 0:78a2573ad768 25
zinnetyazicii53 0:78a2573ad768 26 //This is good to view for debugging
zinnetyazicii53 0:78a2573ad768 27 //Serial.print("Signal_Current: ");
zinnetyazicii53 0:78a2573ad768 28 //Serial.println(IR_AC_Signal_Current);
zinnetyazicii53 0:78a2573ad768 29
zinnetyazicii53 0:78a2573ad768 30 // Process next data sample
zinnetyazicii53 0:78a2573ad768 31 IR_Average_Estimated = averageDCEstimator(&ir_avg_reg, sample);
zinnetyazicii53 0:78a2573ad768 32 IR_AC_Signal_Current = lowPassFIRFilter(sample - IR_Average_Estimated);
zinnetyazicii53 0:78a2573ad768 33
zinnetyazicii53 0:78a2573ad768 34 // Detect positive zero crossing (rising edge)
zinnetyazicii53 0:78a2573ad768 35 if ((IR_AC_Signal_Previous < 0) & (IR_AC_Signal_Current >= 0))
zinnetyazicii53 0:78a2573ad768 36 {
zinnetyazicii53 0:78a2573ad768 37
zinnetyazicii53 0:78a2573ad768 38 IR_AC_Max = IR_AC_Signal_max; //Adjust our AC max and min
zinnetyazicii53 0:78a2573ad768 39 IR_AC_Min = IR_AC_Signal_min;
zinnetyazicii53 0:78a2573ad768 40
zinnetyazicii53 0:78a2573ad768 41 positiveEdge = 1;
zinnetyazicii53 0:78a2573ad768 42 negativeEdge = 0;
zinnetyazicii53 0:78a2573ad768 43 IR_AC_Signal_max = 0;
zinnetyazicii53 0:78a2573ad768 44
zinnetyazicii53 0:78a2573ad768 45 //if ((IR_AC_Max - IR_AC_Min) > 100 & (IR_AC_Max - IR_AC_Min) < 1000)
zinnetyazicii53 0:78a2573ad768 46 if ((IR_AC_Max - IR_AC_Min) > 20 & (IR_AC_Max - IR_AC_Min) < 1000)
zinnetyazicii53 0:78a2573ad768 47 {
zinnetyazicii53 0:78a2573ad768 48 //Heart beat!!!
zinnetyazicii53 0:78a2573ad768 49 beatDetected = true;
zinnetyazicii53 0:78a2573ad768 50 }
zinnetyazicii53 0:78a2573ad768 51 }
zinnetyazicii53 0:78a2573ad768 52
zinnetyazicii53 0:78a2573ad768 53 // Detect negative zero crossing (falling edge)
zinnetyazicii53 0:78a2573ad768 54 if ((IR_AC_Signal_Previous > 0) & (IR_AC_Signal_Current <= 0))
zinnetyazicii53 0:78a2573ad768 55 {
zinnetyazicii53 0:78a2573ad768 56 positiveEdge = 0;
zinnetyazicii53 0:78a2573ad768 57 negativeEdge = 1;
zinnetyazicii53 0:78a2573ad768 58 IR_AC_Signal_min = 0;
zinnetyazicii53 0:78a2573ad768 59 }
zinnetyazicii53 0:78a2573ad768 60
zinnetyazicii53 0:78a2573ad768 61 // Find Maximum value in positive cycle
zinnetyazicii53 0:78a2573ad768 62 if (positiveEdge & (IR_AC_Signal_Current > IR_AC_Signal_Previous))
zinnetyazicii53 0:78a2573ad768 63 {
zinnetyazicii53 0:78a2573ad768 64 IR_AC_Signal_max = IR_AC_Signal_Current;
zinnetyazicii53 0:78a2573ad768 65 }
zinnetyazicii53 0:78a2573ad768 66
zinnetyazicii53 0:78a2573ad768 67 // Find Minimum value in negative cycle
zinnetyazicii53 0:78a2573ad768 68 if (negativeEdge & (IR_AC_Signal_Current < IR_AC_Signal_Previous))
zinnetyazicii53 0:78a2573ad768 69 {
zinnetyazicii53 0:78a2573ad768 70 IR_AC_Signal_min = IR_AC_Signal_Current;
zinnetyazicii53 0:78a2573ad768 71 }
zinnetyazicii53 0:78a2573ad768 72
zinnetyazicii53 0:78a2573ad768 73 return(beatDetected);
zinnetyazicii53 0:78a2573ad768 74 }
zinnetyazicii53 0:78a2573ad768 75
zinnetyazicii53 0:78a2573ad768 76 // Average DC Estimator
zinnetyazicii53 0:78a2573ad768 77 int16_t heartRate::averageDCEstimator(int32_t *p, uint16_t x)
zinnetyazicii53 0:78a2573ad768 78 {
zinnetyazicii53 0:78a2573ad768 79 *p += ((((long) x << 15) - *p) >> 4);
zinnetyazicii53 0:78a2573ad768 80 return (*p >> 15);
zinnetyazicii53 0:78a2573ad768 81 }
zinnetyazicii53 0:78a2573ad768 82
zinnetyazicii53 0:78a2573ad768 83 // Low Pass FIR Filter
zinnetyazicii53 0:78a2573ad768 84 int16_t heartRate::lowPassFIRFilter(int16_t din)
zinnetyazicii53 0:78a2573ad768 85 {
zinnetyazicii53 0:78a2573ad768 86 cbuf[offset] = din;
zinnetyazicii53 0:78a2573ad768 87
zinnetyazicii53 0:78a2573ad768 88 int32_t z = mul16(FIRCoeffs[11], cbuf[(offset - 11) & 0x1F]);
zinnetyazicii53 0:78a2573ad768 89
zinnetyazicii53 0:78a2573ad768 90 for (uint8_t i = 0 ; i < 11 ; i++)
zinnetyazicii53 0:78a2573ad768 91 {
zinnetyazicii53 0:78a2573ad768 92 z += mul16(FIRCoeffs[i], cbuf[(offset - i) & 0x1F] + cbuf[(offset - 22 + i) & 0x1F]);
zinnetyazicii53 0:78a2573ad768 93 }
zinnetyazicii53 0:78a2573ad768 94
zinnetyazicii53 0:78a2573ad768 95 offset++;
zinnetyazicii53 0:78a2573ad768 96 offset %= 32; //Wrap condition
zinnetyazicii53 0:78a2573ad768 97
zinnetyazicii53 0:78a2573ad768 98 return(z >> 15);
zinnetyazicii53 0:78a2573ad768 99 }
zinnetyazicii53 0:78a2573ad768 100
zinnetyazicii53 0:78a2573ad768 101 // Integer multiplier
zinnetyazicii53 0:78a2573ad768 102 int32_t heartRate::mul16(int16_t x, int16_t y)
zinnetyazicii53 0:78a2573ad768 103 {
zinnetyazicii53 0:78a2573ad768 104 return((long)x * (long)y);
zinnetyazicii53 0:78a2573ad768 105 }