Arduino BLE sense Pulse sensor

I have been trying this for a while but still couldn't figure it out. I am using the pulse sensor for heart beat which is this one (https://pulsesensor.com/). As I have the Arduino BLE Sense and I am not sure how to use interrupts, I found the code that would calculate the beats per minute with out using the interrupts but not efficient from here (interrupt - pulse sensor + arduino mkr1000 to calculate BPM - Stack Overflow)

#define pulsePin A0

//  VARIABLES
int rate[10];                    
unsigned long sampleCounter = 0; 
unsigned long lastBeatTime = 0;  
unsigned long lastTime = 0, N;
int BPM = 0;
int IBI = 0;
int P = 512;
int T = 512;
int thresh = 512;  
int amp = 100;                   
int Signal;
boolean Pulse = false;
boolean firstBeat = true;          
boolean secondBeat = true;
boolean QS = false;    

void setup() {
  Serial.begin(9600);

}

void loop() {

              if (QS == true) {
                Serial.println("BPM: "+ String(BPM));
                QS = false;
              } else if (millis() >= (lastTime + 20)) {
                readPulse(); 
                lastTime = millis();
//                Serial.print("Last time = ");
//                Serial.println(lastTime);
              }     
}



void readPulse() {

  Signal = analogRead(pulsePin);              
  sampleCounter += 20;                                    // keep track of the time in mS 
  int N = sampleCounter - lastBeatTime;                   // monitor the time since the last beat to avoid noise

  detectSetHighLow();

  if (N > 200) {                                                              // avoid high frequency noise
    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI / 5) * 3) )       
      pulseDetected();
  }

  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;                           
    secondBeat = true;           
  }

}

void detectSetHighLow() {

  if (Signal < thresh && N > (IBI / 5) * 3) {
    if (Signal < T) {                       
      T = Signal;                // keep track of lowest point in pulse wave          
    }
  }

  if (Signal > thresh && Signal > P) {    
    P = Signal;                  // keep track of highest point in pulse wave         
  }                                       

}

void pulseDetected() {
  Pulse = true;                                   // set the Pulse flag when we think there is a pulse
  IBI = sampleCounter - lastBeatTime;             // measure time between beats in mS
  Serial.print("IBI = ");
  Serial.println(IBI);   
  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
    secondBeat = true;
    return;                            
  }
  if (secondBeat) {                                // if it's the secoond time we found a beat, if secondBeat == TRUE
    secondBeat = false;                            // clear SecondBeat flag
    for (int i = 0; i <= 9; i++) {                 
      rate[i] = IBI;
    }
  }

  word 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;                                        // set Quantified Self flag (we detected a beat)
}

but the Interval between beats is not quite correct.

I don't have my finger tip on the sensor and it gives me values, where it should be printing zero.

when i start sensing the value this is the output.

What i want is to be able to detect the interval between two peaks and calculate the beats per minute.

This is the raw output from serial plotter when i sense the pulse.

I tried a lot, like

void loop() {
  
  Input_Voltage = analogRead( A0 ) ;
  sample_counter += 2;
//  Serial.print("sample_counter = ");
//  Serial.println(sample_counter);
//  Serial.print("Input_Voltage = ");
//  Serial.println(Input_Voltage);  
  
  if (Input_Voltage > threshold && Input_Voltage > sampleLast) {
          peak = Input_Voltage;
//          Serial.print("peak = ");
//          Serial.println(peak);  
          ts_1 = sample_counter;
//          delay(2); 
    } 

  
  if( Input_Voltage < sampleLast && Input_Voltage < threshold && (sample_counter - ts_1) > ((IBI / 5) * 3)  ) {
     first_peak = peak_2;
     first_peak_ts = peak_2_ts;

     peak_2 = peak;
     peak_2_ts = ts_1;
     flag = 1;
//     Serial.print("peak_2_ts = ");
//     Serial.println(peak_2_ts);
//     Serial.print("first_peak_ts = ");
//     Serial.println(first_peak_ts);
     IBI = peak_2_ts - first_peak_ts; 
     if (IBI != 0 ){
       Serial.print("IBI = ");
       Serial.println(IBI);
       }
  }
    

when the sample value is greater than threshold and larger than previous value, I note the sensor value, in that case when sample value is lesser than previous value and greater than threshold, i have a peak, I use the same and detect the second peak and calculate the difference, then i replace the second peak as first peak and find new second peak, but it doesn't seem to work.

can someone give me the logic to find the interval between two peaks with quick sampling rate. thank you so much for your help.

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