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.
main.cpp
00001 #include "mbed.h" 00002 #include "USBSerial.h" 00003 #include "Adafruit_SSD1306.h" 00004 #include <string> 00005 #include <sstream> 00006 #include <map> 00007 00008 AnalogIn pulseIn(A0); 00009 using namespace std; 00010 USBSerial pc; 00011 I2C i2c(PB_9, PB_8); 00012 Adafruit_SSD1306_I2c oled(i2c,PC_13); 00013 00014 00015 AnalogIn pulsePin(A0); //This is signal input 00016 00017 // these variables are because they are used during the interrupt service routine! 00018 int BPM; // used to hold the pulse rate 00019 int Signal; // holds the incoming raw data 00020 int IBI = 600; // holds the time between beats, the Inter-Beat Interval 00021 bool Pulse = false; // true when pulse wave is high, false when it's low 00022 bool QS = false; // becomes true when Arduoino finds a beat. 00023 00024 void heart_rate_test(void); 00025 int rate[10]; // used to hold last ten IBI values 00026 unsigned long sampleCounter = 0; // used to determine pulse timing 00027 unsigned long lastBeatTime = 0; // used to find the inter beat interval 00028 int P =512; // used to find peak in pulse wave 00029 int T = 512; // used to find trough in pulse wave 00030 int thresh = 512; // used to find instant moment of heart beat 00031 int amp = 100; // used to hold amplitude of pulse waveform 00032 bool firstBeat = true; // used to seed rate array so we startup with reasonable BPM 00033 bool secondBeat = true; // used to seed rate array so we startup with reasonable BPM 00034 00035 Ticker time_up; 00036 // Escreve o texto passado como parâmetro no display 00037 void OLED_writeString(string str, int x, int y) { 00038 oled.clearDisplay(); 00039 oled.setTextCursor(x, y); 00040 oled.fillRect(x, y, 128, 8, 0); 00041 } 00042 00043 00044 void heart_rate_test() 00045 { 00046 Signal = pulsePin.read()*1024; // read the Pulse Sensor 00047 sampleCounter += 2; // keep track of the time in mS with this variable 00048 int N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid nois // find the peak and trough of the pulse wave 00049 if(Signal < thresh && N > (IBI/5)*3) { // avoid dichrotic noise by waiting 3/5 of last IBI 00050 if (Signal < T) { // T is the trough 00051 T = Signal; // keep track of lowest point in pulse wave 00052 } 00053 } 00054 00055 if(Signal > thresh && Signal > P) { // thresh condition helps avoid noise 00056 P = Signal; // P is the peak 00057 } // keep track of highest point in pulse wave 00058 00059 // NOW IT'S TIME TO LOOK FOR THE HEART BEAT 00060 // signal surges up in value every time there is a pulse 00061 if (N > 250) { // avoid high frequency noise 00062 if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ) { 00063 Pulse = true; // set the Pulse flag when we think there is a pulse 00064 //digitalWrite(blinkPin,HIGH); // turn on pin 13 LED 00065 IBI = sampleCounter - lastBeatTime; // measure time between beats in mS 00066 lastBeatTime = sampleCounter; // keep track of time for next pulse 00067 00068 if(firstBeat) { // if it's the first time we found a beat, if firstBeat == TRUE 00069 firstBeat = false; // clear firstBeat flag 00070 return; // IBI value is unreliable so discard it 00071 } 00072 if(secondBeat) { // if this is the second beat, if secondBeat == TRUE 00073 secondBeat = false; // clear secondBeat flag 00074 for(int i=0; i<=9; i++) { // seed the running total to get a realisitic BPM at startup 00075 rate[i] = IBI; 00076 } 00077 } 00078 00079 // keep a running total of the last 10 IBI values 00080 long runningTotal = 0; // clear the runningTotal variable 00081 00082 for(int i=0; i<=8; i++) { // shift data in the rate array 00083 rate[i] = rate[i+1]; // and drop the oldest IBI value 00084 runningTotal += rate[i]; // add up the 9 oldest IBI values 00085 } 00086 00087 rate[9] = IBI; // add the latest IBI to the rate array 00088 runningTotal += rate[9]; // add the latest IBI to runningTotal 00089 runningTotal /= 10; // average the last 10 IBI values 00090 BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM! 00091 QS = true; 00092 string BPM_s= static_cast<ostringstream*>( &(ostringstream() << BPM) )->str(); 00093 OLED_writeString(BPM_s, 1, 1); 00094 // QS FLAG IS NOT CLEARED INSIDE THIS ISR 00095 } 00096 } 00097 00098 if (Signal < thresh && Pulse == true) { // when the values are going down, the beat is over 00099 Pulse = false; // reset the Pulse flag so we can do it again 00100 amp = P - T; // get amplitude of the pulse wave 00101 thresh = amp/2 + T; // set thresh at 50% of the amplitude 00102 P = thresh; // reset these for next time 00103 T = thresh; 00104 } 00105 00106 if (N > 2500) { // if 2.5 seconds go by without a beat 00107 thresh = 512; // set thresh default 00108 P = 512; // set P default 00109 T = 512; // set T default 00110 lastBeatTime = sampleCounter; // bring the lastBeatTime up to date 00111 firstBeat = true; // set these to avoid noise 00112 secondBeat = true; // when we get the heartbeat back 00113 } 00114 00115 00116 } 00117 00118 00119 int main() 00120 { 00121 time_up.attach(&heart_rate_test, 0.002); 00122 oled.clearDisplay(); 00123 OLED_writeString("hello world", 1, 1); 00124 while(true) 00125 { 00126 if (QS == true) 00127 { 00128 00129 QS = false; 00130 pc.printf("%d \n ",BPM); // reset the Quantified Self flag for next time 00131 } 00132 wait_ms(20); 00133 } 00134 } 00135 00136 00137 00138
Generated on Fri Jul 15 2022 19:27:16 by
1.7.2