Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
PulseSensor.cpp
00001 #include "PulseSensor.h" 00002 00003 00004 PulseSensor::PulseSensor(PinName analogPin, void (*printDataCallback)(int), int callbackRateMs) 00005 { 00006 _started = false; 00007 00008 _pAin = new AnalogIn(analogPin); 00009 00010 _callbackRateMs = callbackRateMs; 00011 00012 _printDataCallback = printDataCallback; 00013 } 00014 00015 00016 PulseSensor::~PulseSensor() 00017 { 00018 delete _pAin; 00019 } 00020 00021 00022 void PulseSensor::process_data_ticker_callback(void) 00023 { 00024 //_printDataCallback('S', Signal); // send Processing the raw Pulse Sensor data 00025 if (QS == true) { // Quantified Self flag is true when a heartbeat is found 00026 //fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse 00027 //_printDataCallback('B',BPM); // send heart rate with a 'B' prefix 00028 _printDataCallback(BPM); 00029 //_printDataCallback('Q',IBI); // send time between beats with a 'Q' prefix 00030 QS = false; // reset the Quantified Self flag for next time 00031 } 00032 } 00033 00034 00035 void PulseSensor::sensor_ticker_callback(void) 00036 { 00037 Signal = 1023 * _pAin->read(); // read the Pulse Sensor 00038 00039 00040 sampleCounter += 2; // keep track of the time in mS with this variable 00041 int N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid noise 00042 00043 // find the peak and trough of the pulse wave 00044 if(Signal < thresh && N > (IBI/5)*3) { // avoid dichrotic noise by waiting 3/5 of last IBI 00045 if (Signal < T) { // T is the trough 00046 T = Signal; // keep track of lowest point in pulse wave 00047 } 00048 } 00049 00050 if(Signal > thresh && Signal > P) { // thresh condition helps avoid noise 00051 P = Signal; // P is the peak 00052 } // keep track of highest point in pulse wave 00053 00054 // NOW IT'S TIME TO LOOK FOR THE HEART BEAT 00055 // signal surges up in value every time there is a pulse 00056 if (N > 250) { // avoid high frequency noise 00057 if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ) { 00058 Pulse = true; // set the Pulse flag when we think there is a pulse 00059 //digitalWrite(blinkPin,HIGH); // turn on pin 13 LED 00060 IBI = sampleCounter - lastBeatTime; // measure time between beats in mS 00061 lastBeatTime = sampleCounter; // keep track of time for next pulse 00062 00063 if(firstBeat) { // if it's the first time we found a beat, if firstBeat == TRUE 00064 firstBeat = false; // clear firstBeat flag 00065 return; // IBI value is unreliable so discard it 00066 } 00067 if(secondBeat) { // if this is the second beat, if secondBeat == TRUE 00068 secondBeat = false; // clear secondBeat flag 00069 for(int i=0; i<=9; i++) { // seed the running total to get a realisitic BPM at startup 00070 rate[i] = IBI; 00071 } 00072 } 00073 00074 // keep a running total of the last 10 IBI values 00075 long runningTotal = 0; // clear the runningTotal variable 00076 00077 for(int i=0; i<=8; i++) { // shift data in the rate array 00078 rate[i] = rate[i+1]; // and drop the oldest IBI value 00079 runningTotal += rate[i]; // add up the 9 oldest IBI values 00080 } 00081 00082 rate[9] = IBI; // add the latest IBI to the rate array 00083 runningTotal += rate[9]; // add the latest IBI to runningTotal 00084 runningTotal /= 10; // average the last 10 IBI values 00085 BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM! 00086 QS = true; // set Quantified Self flag 00087 // QS FLAG IS NOT CLEARED INSIDE THIS ISR 00088 } 00089 } 00090 00091 if (Signal < thresh && Pulse == true) { // when the values are going down, the beat is over 00092 Pulse = false; // reset the Pulse flag so we can do it again 00093 amp = P - T; // get amplitude of the pulse wave 00094 thresh = amp/2 + T; // set thresh at 50% of the amplitude 00095 P = thresh; // reset these for next time 00096 T = thresh; 00097 } 00098 00099 if (N > 2500) { // if 2.5 seconds go by without a beat 00100 thresh = 512; // set thresh default 00101 P = 512; // set P default 00102 T = 512; // set T default 00103 lastBeatTime = sampleCounter; // bring the lastBeatTime up to date 00104 firstBeat = true; // set these to avoid noise 00105 secondBeat = true; // when we get the heartbeat back 00106 } 00107 } 00108 00109 00110 bool PulseSensor::start() 00111 { 00112 if (_started == false) 00113 { 00114 sampleCounter = 0; 00115 lastBeatTime = 0; 00116 P =512; 00117 T = 512; 00118 thresh = 512; 00119 amp = 100; 00120 firstBeat = true; 00121 secondBeat = true; 00122 00123 BPM=0; 00124 Signal=0; 00125 IBI = 600; 00126 Pulse = false; 00127 QS = false; 00128 00129 _pulseSensorTicker.attach(this, &PulseSensor::sensor_ticker_callback, ((float)_sensorTickRateMs/1000)); 00130 _processDataTicker.attach(this, &PulseSensor::process_data_ticker_callback, ((float)_callbackRateMs/1000)); 00131 _started = true; 00132 return true; 00133 } 00134 else 00135 { 00136 return false; 00137 } 00138 } 00139 00140 bool PulseSensor::stop() 00141 { 00142 if(_started == true) 00143 { 00144 _pulseSensorTicker.detach(); 00145 _processDataTicker.detach(); 00146 _started = false; 00147 return true; 00148 } 00149 else 00150 { 00151 return false; 00152 } 00153 } 00154 00155 uint8_t PulseSensor::get_bpm(){ 00156 return BPM; 00157 }
Generated on Mon Sep 26 2022 15:47:46 by
1.7.2