pulse sensor and ISR stops the rest of my code

Hello,
i have been working on Pulse Sensor with arduino mega
and this code is the only one i can get right readings from

int pulsePin = A1;          
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 = true; 

void setup(){

  TCCR2A = 0x02;  
  TCCR2B = 0x06; 
  OCR2A = 0x7C;  
  TIMSK2 = 0x02;  
  sei();
  Serial.begin(9600);
}
void loop(){
}
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(blinkPin,HIGH);  
    delay(200); //    
    IBI = sampleCounter - lastBeatTime;
    lastBeatTime = sampleCounter;       
   if(firstBeat){                     
      firstBeat = false;             
      return;                          
    }   
    if(secondBeat){              
      secondBeat = false;     
      for(int i=0; i<=9; i++){   
        rate[i] = IBI;                      
      }
    }   
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;
   Serial.print("Your Beat ");
   Serial.println(BPM);                  
    }             
}      
  if (Signal < thresh && Pulse == true){  
    digitalWrite(13,LOW);
    delay(200); //    
    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 = true;           
    lastBeatTime = sampleCounter;
  }
      
}

But the Interrupt Service Routines is triggered every 2 ms to get accurate readings
so other sensors stops giving reading
can any one give me guides on how to take readings of all sensors

P.S there is DHT11 Thermistor and weight sensor in the circuit i want to take there readings beside heart rate
i tried push button with pulse sensor and DHT to control when to get DHT inside loop and stop ISR but is there any other solution ?

Your ISR stops because it tries to print. NEVER print from within an interrupt, because printing depends on interrupts and those are turned off in an ISR.

ISRs should be as short as possible. Yours is way, way too long. Take almost everything out of the ISR and put it in the main loop.

The ISR should collect and store the absolute minimum data necessary, set a global flag (declared "volatile") that the data need to be processed, and exit.

jremington:
Your ISR stops because it tries to print. NEVER print from within an interrupt, because printing depends on interrupts and those are turned off in an ISR.

The code isnt written by me it written by [developer](https://pulsesensor.com/pages/pulse-sensor-amped-arduino-v1dot1) of sensor so how to print data processed out of ISR . should i do this after calling ISR in void loop()`?

The ISR should collect and store the absolute minimum data necessary, set a global flag (declared "volatile") that the data need to be processed, and exit.

Can you clear your point more ?

If you don't know how to use a global flag, modify your sketch like this:

bool flag = false;
void loop(){
  if (flag) {
    flag = false;
    T2SR();
  }
}
ISR(TIMER2_COMPA_vect){
  flag = true; }
void T2SR() {

Leave everything before and after this part as is.

When you know more about the timer registers and their coding, you can drop the ISR and check the T2 overflow flag in loop(). I'm too lazy now to figure out which is the COMPA flag and how to clear it.

Something like this:

volatile unsigned int signal;
volatile bool haveSignal;

ISR(TIMER2_COMPA_vect){
  reading = analogRead(pulsePin);
  haveSignal = true;
}

void loop() {
  if (haveSignal) { // Yoo hoo! Got a new signal!
    haveSignal = false; // Record that we handled the new signal.
    noInterrupts();
    unsigned int signal = reading; // So to prevent the value from changing while we work onit.
    interrrupts();
    processSignal(signal);
  }
  // Whatever else loop() has to do.
}

void processSignal(unsigned int signal) {
  // Do something useful with your newly acquired data.
  // But don't take too long here or you will still miss events!
}

I second DrDietrich's proposal of reply #3, except that "flag" should be declared volatile.

Everything that is now in the Timer2 ISR should be moved into the function T2SR(). Sadly, the developer of the pulse sensor does not understand very well how to program an Arduino.

volatile bool flag = false;
void loop(){
  if (flag) {
    flag = false;
    T2SR();
  }
}
ISR(TIMER2_COMPA_vect){
  flag = true; }
void T2SR() {

Bytes (bool) have atomic access, no need for volatile here. I didn't want to overload the OP with local copies and exclusive access to volatile multi-byte variables.

Nevertheless, for a beginner, it is important to stress the need for "volatile".

Volatile by itself does not help much. The whole story requires exclusive access as well.

Interrupts are not that easy to handle, there are many pitfalls. Especially when there's a lot of work to be done every 2 ms it will require careful planning. If timing is critical, even more so.

Then OP talks about adding the DHT11, which by itself also requires delicate timing for its communication. An interrupt triggering every 2 ms is bound to mess up the communication with that sensor so halting the timer interrupt is very likely required to make it work - unless the interrupt can be changed to finish really fast so as not to mess up that timing, and the work on the heartbeat readings can wait for some time (so there has to be a way to store and handle a backlog of readings).

Also worrying is that analogRead() call in the ISR, that takes quite long. It makes me think how that can be sped up - a possible solution may be to set the ADC in free running mode, so the ISR can simply read the latest value from the register without having to wait for a conversion to complete.

The whole story requires exclusive access as well.

Gibberish. Instead of trying to argue with me, and making no sense at all to a beginner, I suggest that you post a clear beginner level tutorial on how to do this properly.

Bye now.

jremington:
a clear beginner level tutorial on how to do this properly.

That's a pretty tall order considering the subject matter at hand!

Bytes (bool) have atomic access, no need for volatile here.

The volatile is absolutely needed there and it has little to do with atomic access. Volatile tells the compiler that the variable may be modified out of normal program flow and so its value must be loaded from RAM each time it is accessed, rather than relying on a cached copy in a register.

I wrote that here no volatile is needed, because in this code the flag is read only once. There is nothing wrong with this pattern.

If somebody thinks that volatile should be mentioned, he should also mention atomic access, IMO.

tried solution in reply #3 and #4 it still printing a non-accurate readings for heart sensor
for more searches that have been recommended i am still searching but i could use a hint to get accurate value from heart sensor

My crystal ball is in repair, please show your code.

DrDiettrich:
If you don't know how to use a global flag, modify your sketch like this:

bool flag = false;

void loop(){
  if (flag) {
    flag = false;
    T2SR();
  }
}
ISR(TIMER2_COMPA_vect){
  flag = true; }
void T2SR() {

can you clear more why using flag ?

DrDiettrich:
My crystal ball is in repair, please show your code.

the same one you have posted with adding flag to ISR function
if you want the complete code
i will put in attachment as its a big one !

BodyTemp.ino (239 Bytes)

DHT_sensor.ino (761 Bytes)

ISR.ino (1.92 KB)

weight_sensor.ino (1.18 KB)

Project.ino (2.21 KB)

The five pieces of code (why five?) fit nicely in the 9,000 character limit.

Why don't you start with writing a smallest possible example that shows the problem? In your case a sketch that just reads the heart beat sensor. That's anyway what you already should have done to even have a chance of tracking down the problem (and in the process verifying it's not the sensor that's at fault).

Please reformat your code, to fix the indentation.
It's not obvious to me what your code does, too many if's and obscure variables.