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.
Dependencies: 4DGL-uLCD-SE mbed
Fork of uLCD144G2_demo by
main.cpp
- Committer:
- maryannionascu
- Date:
- 2015-10-28
- Revision:
- 10:ad2548407023
- Parent:
- 9:b2a894f94cb7
File content as of revision 10:ad2548407023:
#include "mbed.h"
#include "uLCD_4DGL.h"
//Calculates the BPM using a photoresistor as input and outputs the BPM to an LCD screen.
uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;
AnalogIn photoresistor(p15);
Timer t; //running timer
Ticker interrupt; //recurring 2 ms interrupt
volatile float beat; //raw analog signal data from photoresistor
volatile int BPM = 60; //beats per minute
volatile int beatCount = 0; //number of beats found
volatile float currIBI = 0; // current InterBeat Interval: the time since the last beat
volatile float lastIBI = 1; //last InterBeat Interval: the time between beats
volatile float pastIBI[10]; //past ten IBI values
volatile float sumIBI = 0; ///sum of past ten IBI values
volatile unsigned long lastBeatTime = 0; //time of last beat
volatile float peak = 25; //peak of heartbeat wave; initilized to 20 to avoid noise at startup
volatile float trough = 15; //trough of heartbeat wave
volatile float lowerThresh = 10; // used to reduce noice; change these values based on amount of light in room
volatile float upperThresh = 30; // used to reduce noice; change these values based on amount of light in room
volatile float amp = 5; // amplitude of heartbeat wave
volatile bool firstBeat = true; //keeps track of first beat found
volatile bool beatFound = false; //true when a beat is found, false in between beats
volatile bool BPMfound = false; //true when BPM is found, false otherwise.
void findBPM(){
__disable_irq(); // disable interrupts
beat = photoresistor * 100; // read the analog data from the photoresistor and multiply by 100 (amplifies small values)
currIBI = t.read() - lastBeatTime;
// avoid noise by waiting 3/5 of last IBI
if((beat < lowerThresh) && (currIBI > (lastIBI*3)/5)){
if (beat < trough){
trough = beat;
}
}
if((beat > upperThresh) && (beat > peak)){
peak = beat;
}
// photoresistor signal surges when there is a heartbeat
if ((currIBI > 0.25) && (beat > upperThresh) && (beatFound == false)){
beatFound = true;
beatCount++;
lowerThresh = beat - 0.7; //adjust threshold to account for any change in lighting and avoid noise
lastIBI = t.read() - lastBeatTime;
lastBeatTime = t.read();
//if this is the first beat found, fill pastIBI values with this value until more beats are found
if(firstBeat){
firstBeat = false;
for(int i=0; i< 10; i++){
pastIBI[i] = lastIBI;
}
}
sumIBI = lastIBI;
//shift data over one value in pastIBI array to make room for next IBI value and discard oldest value
for(int i=0; i< 9; i++){
pastIBI[i] = pastIBI[i+1];
sumIBI += pastIBI[i];
}
pastIBI[9] = lastIBI; //add most recent IBI value to array
sumIBI = sumIBI/10; //average the last 10 IBI values
BPM = 60/sumIBI; //BPM = 1 minute / average IBI
if(beatCount == 5){ //Only report BPM after at least 5 beats are found
BPMfound = true;
beatCount = 0;
}
}
//when the signal is less than the threshold, the beat is over
if (((beat < lowerThresh) && beatFound) || (currIBI > 2)){
beatFound = false; // reset the beatFound flag to find the next beat
amp = peak - trough; // calculate amplitude of heartbeat wave
upperThresh = amp/2 + trough; // set upper threshold to 50% of the amplitude
peak = upperThresh;
trough = lowerThresh;
}
__enable_irq(); //enable interrupts
}
int main()
{
uLCD.color(RED);
uLCD.printf("\nHeart Beat Monitor\n");
wait(1);
uLCD.cls();
t.start();
interrupt.attach(&findBPM, 0.002); //throws interrupt every 2ms to read sensor data and calculate BPM
while(1){
if(t.read() > 10){ //wait 10 seconds to get an accurate average
if(BPMfound){
BPMfound = false; //start calculating next BPM
uLCD.locate(1,2);
uLCD.printf("\nYour BPM is:\n");
uLCD.printf("%2D", BPM);
wait(3);
uLCD.cls();
lastBeatTime = 0;
beatCount = 0;
t.start(); //restart timer
}
//No heartbeat detected wtihin 10 seconds
else{
uLCD.printf("\nNo heartbeat detected!");
wait(3);
uLCD.cls();
lastBeatTime = 0;
beatCount = 0;
t.start(); //restart timer
}
}
else{
uLCD.locate(1,2);
uLCD.printf("\nCalculating...\n");
wait(.1);
uLCD.cls();
}
}
}
