Pulse sensor readings to pulse rate

Hi!
I am trying to get my arduino Uno board to give me a BPM pulse rate from the readings of a “Pulse Sensor (www.pulsesensor.com)”

This is my attempt:

#include <LiquidCrystal.h>
#include <Keypad.h>

//Sources: http://sunraysme.wordpress.com/2012/04/10/a-keypad-for-thearduino/
// http://pulsesensor.myshopify.com/pages/pulse-sensor-amped-arduino-v1dot1

//Basics
int sysinit = 0;
int agedigit1;
int agedigit2;
int maxpuls;
int pulsePin = 0;          
int blinkPin = 13;         
int fadePin = 5;           
int fadeRate = 0;  
volatile int BPM;                  
volatile int Signal;                
volatile int IBI = 600;             
volatile boolean Pulse = false; 
volatile boolean QS = false;  
volatile int rate[10];                  
volatile unsigned long sampleCounter = 0;   
volatile unsigned long lastBeatTime = 0;      
volatile int P =512;                
volatile int T = 512;               
volatile int thresh = 512;       
volatile int amp = 100;          
volatile boolean firstBeat = true;       
volatile boolean secondBeat = false;

const byte rows = 4; //four rows
const byte cols = 3; //three columns
char keys[rows][cols] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

byte rowPins[rows] = {5, 4, 3, 2};
byte colPins[cols] = {8, 7, 6};
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );

LCD definitions
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void interruptSetup(){ 
  TCCR2A = 0x02;  
  TCCR2B = 0x06; 
  OCR2A = 0x7C;  
  TIMSK2 = 0x02;  
  sei();
}
ISR(TIMER2_COMPA_vect){ 
  Signal = analogRead(pulsePin); 
  sampleCounter += 2;               
  int N = sampleCounter - lastBeatTime;
  if(Signal < thresh && N > (IBI/5)*3){
    if (Signal < T){ 
      T = Signal;    
    }
  }
  if(Signal > thresh && Signal > P){  
    P = Signal;                     
  }
  if (N > 250){

  if ( (Signal > thresh) && (Pulse == false) && (N > ((IBI/5)*3) ))  {  
    Pulse = true;                      
    digitalWrite(pulsePin,HIGH);            
    IBI = sampleCounter - lastBeatTime;
    lastBeatTime = sampleCounter;
    if(secondBeat)  {              
      secondBeat = false;     
      for(int i=0; i<=9; i++)  {   
        rate[i] = IBI;                      
      }
    }                       

    if(firstBeat)  {                     
      firstBeat = false; 
      secondBeat = true;
      sei();            
      return;                          
    }
    word  runningTotal = 0;
      for(int i=0; i<=8; i++)  {
        rate[i] = rate[i+1]; 
        runningTotal += rate[i];      
      }
      rate[9] = IBI;                   
      runningTotal += rate[9];             
      runningTotal /= 10;             
      BPM = 60000/runningTotal;
      QS = true; 
  }
  }
  if (Signal < thresh && Pulse == true)  {  
    digitalWrite(13,LOW);         
    Pulse = false;                      
    amp = P - T;                        
    thresh = amp/2 + T;            
    P = thresh;                         
    T = thresh;
  }
  if (N > 2500)  {    
    thresh = 512; 
    P = 512; 
    T = 512; 
    firstBeat = true;                 
    secondBeat = false;           
    lastBeatTime = sampleCounter;
  }
}

void setup()
{
  lcd.begin(16,2);
  pinMode(13,OUTPUT); //Ledpin
  pinMode(10,OUTPUT);
  pinMode(8, INPUT_PULLUP); //Kolumn 1
  pinMode(7, INPUT_PULLUP); //Kolumn 2
  pinMode(6, INPUT_PULLUP); //Kolumn 3
  lcd.setCursor(0,0);
  lcd.print("Input age and press '#' on the keypad");
  lcd.print(" Age: ");
  lcd.setCursor(0,5);
  interruptSetup();
}

void loop()
{
  char key = kpd.getKey();

  switch (sysinit) {
  case 0:  {
    int digit = key - '0';
    if(digit >= 0) {
      if(digit <= 9) {
        agedigit1 = digit;
        lcd.print(key);
        sysinit = sysinit++;
      }
    }
  }
    break;
  case 1:  {
    int digit2 = key - '0';
    if(digit2 >= 0)  {
      if(digit2 <=9)  {
        agedigit2 = digit2;
        lcd.print(key);
        sysinit = sysinit++;
      }
    }
  }
    break;
    
  case 2:  {
    if(key == '#')  {
      maxpuls = 220 - (10*agedigit1 + agedigit2);
      lcd.setCursor(0,1);
      lcd.print(" Maxpuls: ");
      lcd.print(maxpuls);
      Serial.println();
      sysinit = sysinit++;
    }
  }
    break;
  case 3:  {
    sendDataToProcessing('S', Signal); 
    if (QS == true){                                     
      sendDataToProcessing('B',BPM); 
      sendDataToProcessing('Q',IBI);
      QS = false;                        
    }
   ledFadeToBeat();
   delay(20);                          
   }
  break; 
  }
}
void sendDataToProcessing(char symbol, int data )  {
  Serial.print(symbol);    
  Serial.println(data);     
}
void ledFadeToBeat(){
  fadeRate-= 15;                         
  fadeRate= constrain(fadeRate,0,255);
  analogWrite(fadePin, fadeRate);            
}

I should mention that this is my first attempt to Arduino and therefore apologize for any structural or obvious “mess ups” in my code.
Any help with figuring out how to convert the sensor values to BPM is greatly appreciated! :slight_smile:

A quick look,

your ISR seems to me much too big, you must keep it as small as possible and do all the math ion the main loop.
Otherwise you get an reentry problem -> see wikipedia

Let the ISR just count the pulses (and do optionally some debounce detection) and move all that math.