user27561: I have a problem with these two modules. I am trying to create a pulse sensor but also want to use a remote for some further functionality (menu system).
I have the code separated into two files, one for the main menu and the other for the pulse sensor. They work as expected individually but when i combine the code it only displays the pulse readings and doesnt allow me to use the main menu functionality.
ISR(TIMER2_COMPA_vect) {                        // triggered when Timer2 counts to 124
  cli();                                      // disable interrupts while we do this
  Signal = analogRead(pulsePin);              // read the Pulse Sensor
  sampleCounter += 2;                         // keep track of the time in mS with this variable
  int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise

  //  find the peak and trough of the pulse wave
  if (Signal < thresh && N > (IBI / 5) * 3) { // avoid dichrotic noise by waiting 3/5 of last IBI
    if (Signal < T) {                       // T is the trough
      T = Signal;                         // keep track of lowest point in pulse wave
    }
  }

  if (Signal > thresh && Signal > P) {        // thresh condition helps avoid noise
    P = Signal;                             // P is the peak
  }                                        // keep track of highest point in pulse wave

  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  // signal surges up in value every time there is a pulse
  if (N > 250) {                                  // avoid high frequency noise
    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI / 5) * 3) ) {
      Pulse = true;                               // set the Pulse flag when we think there is a pulse
      IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
      lastBeatTime = sampleCounter;               // keep track of time for next pulse

      if (secondBeat) {                      // if this is the second beat, if secondBeat == TRUE
        secondBeat = false;                  // clear secondBeat flag
        for (int i = 0; i <= 9; i++) {       // seed the running total to get a realisitic BPM at startup
          rate[i] = IBI;
        }
      }

      if (firstBeat) {                       // if it's the first time we found a beat, if firstBeat == TRUE
        firstBeat = false;                   // clear firstBeat flag
        secondBeat = true;                   // set the second beat flag
        sei();                               // enable interrupts again
        return;                              // IBI value is unreliable so discard it
      }


      // keep a running total of the last 10 IBI values
      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
  // QS FLAG IS NOT CLEARED INSIDE THIS ISR
    }
  }

  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;                      // set these to avoid noise
    secondBeat = false;                    // when we get the heartbeat back
  }
  Temp = Thermistor(analogRead(tempPin));
  Sweat = analogRead(moisture);

  sei();                                   // enable interrupts when youre done!
}

I think the problem is with the actual header file. When the IRemote is initialised, it calls sei() which then turns on the global interrupts.
Is there a way to solve this issue? I was thinking about something along the lines of each interrupt should be unique and shouldnt be dependent on the other, and is there a way to tell the compiler about a hierarchy of interrupts.
Thanks in advance. 

user23841: 
ISR should be as short as possible. Set flag and let the main program to handle it.
Global interrupt flag is handled automatically (on AVR platform), so you don't have to call cli().
Enabling interrupts in ISR handler might cause more problem than you can even imagine. Usual one is stack overflow caused by going deeper and deeper by another ISRs (or the same one, if it's longer than ISR period).


27561: <p>I have a problem with these two modules. I am trying to create a pulse sensor but also want to use a remote for some further functionality (menu system).
I have the code separated into two files, one for the main menu and the other for the pulse sensor. They work as expected individually but when i combine the code it only displays the pulse readings and doesnt allow me to use the main menu functionality.</p>

<pre><code>ISR(TIMER2_COMPA_vect) {                        // triggered when Timer2 counts to 124
  cli();                                      // disable interrupts while we do this
  Signal = analogRead(pulsePin);              // read the Pulse Sensor
  sampleCounter += 2;                         // keep track of the time in mS with this variable
  int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise

  //  find the peak and trough of the pulse wave
  if (Signal &lt; thresh &amp;&amp; N &gt; (IBI / 5) * 3) { // avoid dichrotic noise by waiting 3/5 of last IBI
    if (Signal &lt; T) {                       // T is the trough
      T = Signal;                         // keep track of lowest point in pulse wave
    }
  }

  if (Signal &gt; thresh &amp;&amp; Signal &gt; P) {        // thresh condition helps avoid noise
    P = Signal;                             // P is the peak
  }                                        // keep track of highest point in pulse wave

  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  // signal surges up in value every time there is a pulse
  if (N &gt; 250) {                                  // avoid high frequency noise
    if ( (Signal &gt; thresh) &amp;&amp; (Pulse == false) &amp;&amp; (N &gt; (IBI / 5) * 3) ) {
      Pulse = true;                               // set the Pulse flag when we think there is a pulse
      IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
      lastBeatTime = sampleCounter;               // keep track of time for next pulse

      if (secondBeat) {                      // if this is the second beat, if secondBeat == TRUE
        secondBeat = false;                  // clear secondBeat flag
        for (int i = 0; i &lt;= 9; i++) {       // seed the running total to get a realisitic BPM at startup
          rate[i] = IBI;
        }
      }

      if (firstBeat) {                       // if it's the first time we found a beat, if firstBeat == TRUE
        firstBeat = false;                   // clear firstBeat flag
        secondBeat = true;                   // set the second beat flag
        sei();                               // enable interrupts again
        return;                              // IBI value is unreliable so discard it
      }


      // keep a running total of the last 10 IBI values
      word runningTotal = 0;                  // clear the runningTotal variable

      for (int i = 0; i &lt;= 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
  // QS FLAG IS NOT CLEARED INSIDE THIS ISR
    }
  }

  if (Signal &lt; thresh &amp;&amp; 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 &gt; 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;                      // set these to avoid noise
    secondBeat = false;                    // when we get the heartbeat back
  }
  Temp = Thermistor(analogRead(tempPin));
  Sweat = analogRead(moisture);

  sei();                                   // enable interrupts when youre done!
}
</code></pre>

<p>I think the problem is with the actual header file. When the IRemote is initialised, it calls sei() which then turns on the global interrupts.</p>

<p>Is there a way to solve this issue? I was thinking about something along the lines of each interrupt should be unique and shouldnt be dependent on the other, and is there a way to tell the compiler about a hierarchy of interrupts.</p>

<p>Thanks in advance. </p>
 23841: <ol>
<li>ISR should be as short as possible. Set flag and let the main program to handle it.</li>
<li>Global interrupt flag is handled automatically (on AVR platform), so you don't have to call <code>cli()</code>.</li>
<li>Enabling interrupts in ISR handler might cause more problem than you can even imagine. Usual one is stack overflow caused by going deeper and deeper by another ISRs (or the same one, if it's longer than ISR period).</li>
</ol>
