Can anyone explain the algorithm on this code? Heart Rate

This code is what I found on the Internet and I want to understand how it works.
The main thing I want to understand is how he calculates bpm.
#include <Adafruit_SSD1306.h>

#define OLED_Address 0x3C
Adafruit_SSD1306 oled(1);

int x=0;
int lastx=0;
int lasty=0;
int LastTime=0;
bool BPMTiming=false;
bool BeatComplete=false;
int BPM=0;

#define UpperThreshold 550
#define LowerThreshold 500

void setup() {
oled.begin(SSD1306_SWITCHCAPVCC, OLED_Address);
oled.clearDisplay();
oled.setTextSize(2);
}

void loop()
{
if(x>127)
{
oled.clearDisplay();
x=0;
lastx=x;
}

int value=analogRead(0);
oled.setTextColor(WHITE);
int y=60-(value/16);
oled.writeLine(lastx,lasty,x,y,WHITE);
lasty=y;
lastx=x;
// calc bpm

if(value>UpperThreshold)
{
if(BeatComplete)
{
BPM=millis()-LastTime;
BPM=int(60/(float(BPM)/1000));
BPMTiming=false;
BeatComplete=false;
}
if(BPMTiming==false)
{
LastTime=millis();
BPMTiming=true;
}
}
if((value<LowerThreshold)&(BPMTiming))
BeatComplete=true;
// display bpm
oled.writeFillRect(0,50,128,16,BLACK);
oled.setCursor(0,50);
oled.print(BPM);
oled.print(" BPM");
oled.display();
x++;
}

Have you tried to work out how the algorithm works? It's pretty simple. What parts are giving difficulty?

It might help if you Auto-Format the code. That will make understanding the structure a little easier.

I try to write some comments.
did I have some misunderstanding?

if(a>127)                // Clear EEG
{
display.clearDisplay();
a=0;
lasta=a;
}

ThisTime=millis(); //Get the time 
int value=analogRead(0); //read anlog
display.setTextColor(WHITE);
int b=60-(value/16);why

display.writeLine(lasta,lastb,a,b,WHITE); //write a Line (EEG)
lastb=b;
lasta=a;
if(value>UpperThreshold)     // Heart beat leading edge detected.
{
if(BeatComplete) //calculate the bpm 
{
BPM=ThisTime-LastTime;
BPM=int(1/float(BPM)*1000*60);   //Divide by 60x1000 to change from millisecond to minute.
BPMTiming=false;
BeatComplete=false;

}
if(BPMTiming==false) //  Reset BPMTiming
LastTime=millis();
BPMTiming=true; // this switches BPMTiming as set in if (BeatComplete) from false to true
}
}
if((value<LowerThreshold)&(BPMTiming))  // Heart beat trailing edge detected.
BeatComplete=true;                                        // edge detected,beat is complete
display.writeFillRect(0,50,128,16,BLACK);
display.setCursor(0,50);
display.print("BPM:");
display.print(BPM);
display.display();

a++;

   }







































Here, you are multiplying by 60x1000, not dividing.

Otherwise your comments are correct.

I think "why" here was meant to be a comment. It is not valid C code. What this line is doing is calculating a vertical pixel position on the oled from the analog input value.

  // If the value is high...
  if (value > UpperThreshold)
  {
    // and it's the first time it was high since the last time it was low...
    if (BeatComplete)
    {
      // This is the start of a beat.

      // Record the number of milliseconds since the start of 
      // the previous beat
      unsigned long millisecondsPerBeat = millis() - LastTime;

      // divide the number of milliseconds into the number of
      // milliseconds in a minute (60000) to get beats per minute
      BPM = 60000.0 / millisecondsPerBeat;
      BPMTiming = false;
      BeatComplete = false;
    }
    if (BPMTiming == false)
    {
      LastTime = millis();
      BPMTiming = true;
    }
  }
  if ((value < LowerThreshold) & (BPMTiming))
    BeatComplete = true;

[/quote]

1 Like

You can always add a few serial monitor prints, and maybe delays to help you work out program flow and the value of certain variables.
You can comment out sections too to help

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.