Projet_BMC / Mbed 2 deprecated PulseSensor2

Dependencies:   mbed USBDevice

Committer:
the_nabil
Date:
Tue Jan 21 16:04:23 2020 +0000
Revision:
1:4800e2f494f1
Parent:
0:030060e88177
pulsesensor

Who changed what in which revision?

UserRevisionLine numberNew contents of line
salvolicitra 0:030060e88177 1 #include "PulseSensor.h"
salvolicitra 0:030060e88177 2
salvolicitra 0:030060e88177 3 PulseSensor::PulseSensor(){}
salvolicitra 0:030060e88177 4
salvolicitra 0:030060e88177 5 PulseSensor::PulseSensor(PinName analogPin, void (*printDataCallback)(char,int), int callbackRateMs)
salvolicitra 0:030060e88177 6 {
salvolicitra 0:030060e88177 7 _started = false;
salvolicitra 0:030060e88177 8
salvolicitra 0:030060e88177 9 _pAin = new AnalogIn(analogPin);
salvolicitra 0:030060e88177 10
salvolicitra 0:030060e88177 11 _callbackRateMs = callbackRateMs;
salvolicitra 0:030060e88177 12
salvolicitra 0:030060e88177 13 _printDataCallback = printDataCallback;
salvolicitra 0:030060e88177 14 }
salvolicitra 0:030060e88177 15
salvolicitra 0:030060e88177 16
salvolicitra 0:030060e88177 17 PulseSensor::~PulseSensor()
salvolicitra 0:030060e88177 18 {
salvolicitra 0:030060e88177 19 delete _pAin;
salvolicitra 0:030060e88177 20 }
salvolicitra 0:030060e88177 21
salvolicitra 0:030060e88177 22
salvolicitra 0:030060e88177 23 void PulseSensor::process_data_ticker_callback(void)
salvolicitra 0:030060e88177 24 {
salvolicitra 0:030060e88177 25 _printDataCallback('S', Signal); // Processing the raw Pulse Sensor data
salvolicitra 0:030060e88177 26 if (QS == true) { // Quantified Self flag is true when a heartbeat is found
salvolicitra 0:030060e88177 27 //fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse
salvolicitra 0:030060e88177 28 _printDataCallback('B',BPM); // send heart rate with a 'B' prefix
salvolicitra 0:030060e88177 29 _printDataCallback('Q',IBI); // send time between beats with a 'Q' prefix
salvolicitra 0:030060e88177 30 QS = false; // reset the Quantified Self flag for next time
salvolicitra 0:030060e88177 31 }
salvolicitra 0:030060e88177 32 }
salvolicitra 0:030060e88177 33
salvolicitra 0:030060e88177 34
salvolicitra 0:030060e88177 35 void PulseSensor::sensor_ticker_callback(void)
salvolicitra 0:030060e88177 36 {
the_nabil 1:4800e2f494f1 37 Signal = 3300 * _pAin->read(); // read the Pulse Sensor
salvolicitra 0:030060e88177 38
salvolicitra 0:030060e88177 39
salvolicitra 0:030060e88177 40 sampleCounter += 4; // keep track of the time in mS with this variable
salvolicitra 0:030060e88177 41 int N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid noise
salvolicitra 0:030060e88177 42
salvolicitra 0:030060e88177 43 // find the peak and trough of the pulse wave
salvolicitra 0:030060e88177 44 if(Signal < thresh && N > (IBI/5)*3) { // avoid dichrotic noise by waiting 3/5 of last IBI
salvolicitra 0:030060e88177 45 if (Signal < T) { // T is the trough
salvolicitra 0:030060e88177 46 T = Signal; // keep track of lowest point in pulse wave
salvolicitra 0:030060e88177 47 }
salvolicitra 0:030060e88177 48 }
salvolicitra 0:030060e88177 49
salvolicitra 0:030060e88177 50 if(Signal > thresh && Signal > P) { // thresh condition helps avoid noise
salvolicitra 0:030060e88177 51 P = Signal; // P is the peak
salvolicitra 0:030060e88177 52 } // keep track of highest point in pulse wave
salvolicitra 0:030060e88177 53
salvolicitra 0:030060e88177 54 // NOW IT'S TIME TO LOOK FOR THE HEART BEAT
salvolicitra 0:030060e88177 55 // signal surges up in value every time there is a pulse
salvolicitra 0:030060e88177 56 if (N > 250) { // avoid high frequency noise
salvolicitra 0:030060e88177 57 if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ) {
salvolicitra 0:030060e88177 58 Pulse = true; // set the Pulse flag when we think there is a pulse
salvolicitra 0:030060e88177 59 //digitalWrite(blinkPin,HIGH); // turn on pin 13 LED
salvolicitra 0:030060e88177 60 IBI = sampleCounter - lastBeatTime; // measure time between beats in mS
salvolicitra 0:030060e88177 61 lastBeatTime = sampleCounter; // keep track of time for next pulse
salvolicitra 0:030060e88177 62
salvolicitra 0:030060e88177 63 if(firstBeat) { // if it's the first time we found a beat, if firstBeat == TRUE
salvolicitra 0:030060e88177 64 firstBeat = false; // clear firstBeat flag
salvolicitra 0:030060e88177 65 return; // IBI value is unreliable so discard it
salvolicitra 0:030060e88177 66 }
salvolicitra 0:030060e88177 67 if(secondBeat) { // if this is the second beat, if secondBeat == TRUE
salvolicitra 0:030060e88177 68 secondBeat = false; // clear secondBeat flag
salvolicitra 0:030060e88177 69 for(int i=0; i<=9; i++) { // seed the running total to get a realisitic BPM at startup
salvolicitra 0:030060e88177 70 rate[i] = IBI;
salvolicitra 0:030060e88177 71 }
salvolicitra 0:030060e88177 72 }
salvolicitra 0:030060e88177 73
salvolicitra 0:030060e88177 74 // keep a running total of the last 10 IBI values
salvolicitra 0:030060e88177 75 long runningTotal = 0; // clear the runningTotal variable
salvolicitra 0:030060e88177 76
salvolicitra 0:030060e88177 77 for(int i=0; i<=8; i++) { // shift data in the rate array
salvolicitra 0:030060e88177 78 rate[i] = rate[i+1]; // and drop the oldest IBI value
salvolicitra 0:030060e88177 79 runningTotal += rate[i]; // add up the 9 oldest IBI values
salvolicitra 0:030060e88177 80 }
salvolicitra 0:030060e88177 81
salvolicitra 0:030060e88177 82 rate[9] = IBI; // add the latest IBI to the rate array
salvolicitra 0:030060e88177 83 runningTotal += rate[9]; // add the latest IBI to runningTotal
salvolicitra 0:030060e88177 84 runningTotal /= 10; // average the last 10 IBI values
salvolicitra 0:030060e88177 85 BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM!
salvolicitra 0:030060e88177 86 QS = true; // set Quantified Self flag
salvolicitra 0:030060e88177 87 // QS FLAG IS NOT CLEARED INSIDE THIS ISR
salvolicitra 0:030060e88177 88 }
salvolicitra 0:030060e88177 89 }
salvolicitra 0:030060e88177 90
salvolicitra 0:030060e88177 91 if (Signal < thresh && Pulse == true) { // when the values are going down, the beat is over
salvolicitra 0:030060e88177 92 Pulse = false; // reset the Pulse flag so we can do it again
salvolicitra 0:030060e88177 93 amp = P - T; // get amplitude of the pulse wave
salvolicitra 0:030060e88177 94 thresh = amp/2 + T; // set thresh at 50% of the amplitude
salvolicitra 0:030060e88177 95 P = thresh; // reset these for next time
salvolicitra 0:030060e88177 96 T = thresh;
salvolicitra 0:030060e88177 97 }
salvolicitra 0:030060e88177 98
salvolicitra 0:030060e88177 99 if (N > 2500) { // if 2.5 seconds go by without a beat
salvolicitra 0:030060e88177 100 thresh = 530; // set thresh default
salvolicitra 0:030060e88177 101 P = 530; // set P default
salvolicitra 0:030060e88177 102 T = 530; // set T default
salvolicitra 0:030060e88177 103 lastBeatTime = sampleCounter; // bring the lastBeatTime up to date
salvolicitra 0:030060e88177 104 firstBeat = true; // set these to avoid noise
salvolicitra 0:030060e88177 105 secondBeat = true; // when we get the heartbeat back
salvolicitra 0:030060e88177 106 }
salvolicitra 0:030060e88177 107 }
salvolicitra 0:030060e88177 108
salvolicitra 0:030060e88177 109
salvolicitra 0:030060e88177 110 bool PulseSensor::start()
salvolicitra 0:030060e88177 111 {
salvolicitra 0:030060e88177 112 if (_started == false)
salvolicitra 0:030060e88177 113 {
salvolicitra 0:030060e88177 114 sampleCounter = 0;
salvolicitra 0:030060e88177 115 lastBeatTime = 0;
salvolicitra 0:030060e88177 116 P =530;
salvolicitra 0:030060e88177 117 T = 530;
salvolicitra 0:030060e88177 118 thresh = 530;
salvolicitra 0:030060e88177 119 amp = 100;
salvolicitra 0:030060e88177 120 firstBeat = true;
salvolicitra 0:030060e88177 121 secondBeat = true;
salvolicitra 0:030060e88177 122
salvolicitra 0:030060e88177 123 BPM=0;
salvolicitra 0:030060e88177 124 Signal=0;
salvolicitra 0:030060e88177 125 IBI = 600;
salvolicitra 0:030060e88177 126 Pulse = false;
salvolicitra 0:030060e88177 127 QS = false;
salvolicitra 0:030060e88177 128
salvolicitra 0:030060e88177 129 _pulseSensorTicker.attach(this, &PulseSensor::sensor_ticker_callback, ((float)_sensorTickRateMs/1000));
salvolicitra 0:030060e88177 130 _processDataTicker.attach(this, &PulseSensor::process_data_ticker_callback, ((float)_callbackRateMs/1000));
salvolicitra 0:030060e88177 131 _started = true;
salvolicitra 0:030060e88177 132 return true;
salvolicitra 0:030060e88177 133 }
salvolicitra 0:030060e88177 134 else
salvolicitra 0:030060e88177 135 {
salvolicitra 0:030060e88177 136 return false;
salvolicitra 0:030060e88177 137 }
salvolicitra 0:030060e88177 138 }
salvolicitra 0:030060e88177 139
salvolicitra 0:030060e88177 140 bool PulseSensor::stop()
salvolicitra 0:030060e88177 141 {
salvolicitra 0:030060e88177 142 if(_started == true)
salvolicitra 0:030060e88177 143 {
salvolicitra 0:030060e88177 144 _pulseSensorTicker.detach();
salvolicitra 0:030060e88177 145 _processDataTicker.detach();
salvolicitra 0:030060e88177 146 _started = false;
salvolicitra 0:030060e88177 147 return true;
salvolicitra 0:030060e88177 148 }
salvolicitra 0:030060e88177 149 else
salvolicitra 0:030060e88177 150 {
salvolicitra 0:030060e88177 151 return false;
salvolicitra 0:030060e88177 152 }
salvolicitra 0:030060e88177 153 }