heart rate mesuarement

Dependencies:   mbed USBDevice

main.cpp

Committer:
zmoutaou
Date:
2020-01-24
Revision:
2:515e6791dfe2
Parent:
0:a78b08608d76

File content as of revision 2:515e6791dfe2:

#include "mbed.h"
#include "USBSerial.h" 
#include "Adafruit_SSD1306.h"
#include <string>
#include <sstream>
#include <map>

AnalogIn pulseIn(A0);
using namespace std;
USBSerial pc;
I2C i2c(PB_9, PB_8);
Adafruit_SSD1306_I2c oled(i2c,PC_13); 


AnalogIn pulsePin(A0);  //This is signal input

// these variables are because they are used during the interrupt service routine!
int BPM;                   // used to hold the pulse rate
int Signal;                // holds the incoming raw data
int IBI = 600;             // holds the time between beats, the Inter-Beat Interval
bool Pulse = false;     // true when pulse wave is high, false when it's low
bool QS = false;        // becomes true when Arduoino finds a beat.

void heart_rate_test(void);
int rate[10];                    // used to hold last ten IBI values
unsigned long sampleCounter = 0;          // used to determine pulse timing
unsigned long lastBeatTime = 0;           // used to find the inter beat interval
int P =512;                      // used to find peak in pulse wave
int T = 512;                     // used to find trough in pulse wave
int thresh = 512;                // used to find instant moment of heart beat
int amp = 100;                   // used to hold amplitude of pulse waveform
bool firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
bool secondBeat = true;       // used to seed rate array so we startup with reasonable BPM

Ticker time_up;
// Escreve o texto passado como parâmetro no display
void OLED_writeString(string str, int x, int y) {
oled.clearDisplay();
oled.setTextCursor(x, y);
oled.fillRect(x, y, 128, 8, 0);
 } 
 

void heart_rate_test() 
{
    Signal = pulsePin.read()*1024;               // read the Pulse Sensor
    sampleCounter += 2;                         // keep track of the time in mS with this variable
    int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid nois //  find the peak and trough of the pulse wave
    if(Signal < thresh && N > (IBI/5)*3) {      // avoid dichrotic noise by waiting 3/5 of last IBI
        if (Signal < T) {                       // T is the trough
            T = Signal;                         // keep track of lowest point in pulse wave
        }
    }
 
    if(Signal > thresh && Signal > P) {         // thresh condition helps avoid noise
        P = Signal;                             // P is the peak
    }                                        // keep track of highest point in pulse wave
 
    //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
    // signal surges up in value every time there is a pulse
    if (N > 250) {                                  // avoid high frequency noise
        if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ) {
            Pulse = true;                               // set the Pulse flag when we think there is a pulse
            //digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
            IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
            lastBeatTime = sampleCounter;               // keep track of time for next pulse
 
            if(firstBeat) {                        // if it's the first time we found a beat, if firstBeat == TRUE
                firstBeat = false;                 // clear firstBeat flag
                return;                            // IBI value is unreliable so discard it
            }
            if(secondBeat) {                       // if this is the second beat, if secondBeat == TRUE
                secondBeat = false;                 // clear secondBeat flag
                for(int i=0; i<=9; i++) {        // seed the running total to get a realisitic BPM at startup
                    rate[i] = IBI;
                }
            }
 
            // keep a running total of the last 10 IBI values
            long runningTotal = 0;                   // clear the runningTotal variable
 
            for(int i=0; i<=8; i++) {               // shift data in the rate array
                rate[i] = rate[i+1];              // and drop the oldest IBI value
                runningTotal += rate[i];          // add up the 9 oldest IBI values
            }
 
            rate[9] = IBI;                          // add the latest IBI to the rate array
            runningTotal += rate[9];                // add the latest IBI to runningTotal
            runningTotal /= 10;                     // average the last 10 IBI values
            BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
            QS = true; 
            string BPM_s= static_cast<ostringstream*>( &(ostringstream() << BPM) )->str();
            OLED_writeString(BPM_s, 1, 1);  
            // QS FLAG IS NOT CLEARED INSIDE THIS ISR
        }
    }
 
    if (Signal < thresh && Pulse == true) {    // when the values are going down, the beat is over
        Pulse = false;                         // reset the Pulse flag so we can do it again
        amp = P - T;                           // get amplitude of the pulse wave
        thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
        P = thresh;                            // reset these for next time
        T = thresh;
    }
 
    if (N > 2500) {                            // if 2.5 seconds go by without a beat
        thresh = 512;                          // set thresh default
        P = 512;                               // set P default
        T = 512;                               // set T default
        lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
        firstBeat = true;                      // set these to avoid noise
        secondBeat = true;                     // when we get the heartbeat back
    }

 
}


int main()
{
    time_up.attach(&heart_rate_test, 0.002);
    oled.clearDisplay();
    OLED_writeString("hello world", 1, 1);
    while(true) 
    {
        if (QS == true)
        {                      

        QS = false;  
        //pc.printf("%d \n ",BPM);                   // reset the Quantified Self flag for next time    
     }
     wait_ms(20);
    }
}