Issue with two "attachInterrupt"

This code worked normally initially but then stopped working, now the only thing that shows me it's not hardware problem is when I comment out the line with the second interrupt declaration. ( attachInterrupt digitalPinToInterrupt(LightOffPin), buttonpressed, FALLING) .
And no, I tested the button and it is not stuck.
Any ideas?

#include <Wire.h>
#include <TimeLib.h>
#include <DS3232RTC.h>
#define LightLevelPin 9
#define LightOffPin 3
#define AlarmPin 2
#define IndicatorLED 13
double LightLevel = 0;
double Base = 0.0039215;
byte AlarmH = 18;
byte AlarmM = 10;     // Set 30 minutes before wake time
volatile boolean WakeBoss = false;

void wakeshining();

void setup() {

  pinMode(LightLevelPin, OUTPUT);
  pinMode(IndicatorLED, OUTPUT);
  pinMode(AlarmPin, INPUT_PULLUP);
  pinMode(LightOffPin, INPUT_PULLUP);
  //  Serial.begin(9600);
  //  while (!Serial) ;                    // wait for serial
  //delay(200);
  RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
  RTC.alarm(ALARM_2);
  RTC.alarmInterrupt(ALARM_1, false);
  RTC.alarmInterrupt(ALARM_2, false);
  RTC.squareWave(SQWAVE_NONE);
  RTC.setAlarm(ALM2_MATCH_HOURS, 0, AlarmM, AlarmH, 0);
  RTC.alarm(ALARM_2);
  RTC.squareWave(SQWAVE_NONE);
  RTC.alarmInterrupt(ALARM_2, true);
  attachInterrupt(digitalPinToInterrupt(AlarmPin), waketheboss, FALLING);
//  attachInterrupt(digitalPinToInterrupt(LightOffPin), buttonpressed, FALLING);
  setPwmFrequency(LightLevelPin, 1);
}


void loop() {

  if (WakeBoss == true) {
    digitalWrite(IndicatorLED, HIGH);
    wakeshining();
  }

}

void waketheboss() {
  WakeBoss = true;
}

void wakeshining() { // I know that this ISR takes half an hour LOL, should be no longer than microseconds.

  while (LightLevel < 255) {                  // 1020 increments up to 255, 1,764 secondsX1020 = 30 mins.
    for (float f = 0; f < 83000; f++) {}       // About 1 sec of delay per line
    for (float f = 0; f < 63470; f++) {}       // About 0,764 sec of delay per line
    analogWrite(LightLevelPin, LightLevel);
    LightLevel = pow(Base, 4) + 1 ;            //y=x^4...
    //    Serial.println(LightLevel);
    Base = Base + 0.0039215;
  }
  WakeBoss = false;
  digitalWrite(IndicatorLED, LOW);
}

void buttonpressed() {

  digitalWrite(LightLevelPin, LOW);
  digitalWrite(IndicatorLED, LOW);
  RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
  RTC.alarm(ALARM_1);
  RTC.alarm(ALARM_2);
  RTC.alarmInterrupt(ALARM_1, false);
  RTC.alarmInterrupt(ALARM_2, false);
  RTC.setAlarm(ALM2_MATCH_HOURS, 0, AlarmM, AlarmH, 0);
  digitalWrite(IndicatorLED, LOW);

}


void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if (pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch (divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if (pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if (pin == 3 || pin == 11) {
    switch (divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x07; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

The problem with the two interrupts declared is that none of them works.

What is connected to the AlarmPin D2?

buttonpressed () is not a good ISR.

It is calling i2c commands which rely on interrupts which are disabled in the ISR.

cattledog:
It is calling i2c commands which rely on interrupts which are disabled in the ISR.

That will hang a sketch won't it.

What is connected to the AlarmPin D2?

A pin from the RTC that changes to low when alarm time is achieved. I've checked it, and it's changing normally.

buttonpressed () is not a good ISR

I know, but the problem isn't even there so far...

caiopoit:
I know, but the problem isn't even there so far...

How would you know? If it was hanging in that ISR it would look just as you describe. Put a serial print at the top of loop so you can tell when it runs and see if it is hanging up.

I2C in the ISR blows up every other sketch. Don't see why yours would be special.

caiopoit:
This code worked normally initially but then stopped working,

Exactly what do you mean by that?

Was it working properly every time you used it over the course of two or three weeks and now, when you try it there is a problem?

Or do you mean that it only works properly for the first 3 seconds and then stops working?

The debugging process will be very different for the two cases.

...R

Exactly what do you mean by that?

I reuploaded the code sometimes because I had changed two variables that set the alarm time, ( AlarmH and AlarmM ), and at some point it stopped working. Doesn’t show compiling errors. The only relationship I can find now is that before I had reached this final working code (that no longer works) the compiler showed some errors at that commented out attachInterrupt line, but it stopped, started working and now stopped, but no errors are shown when compiling.

caiopoit:
I reuploaded the code sometimes ...

You have managed NOT to answer the questions I asked in Reply #5.

It sounds as if you had a program that worked and then you changed the program and the changed version does not work. if so, post the working version so we can see what changes you have made.

...R

I did not change the program, just those two variables, and it didn’t stop working right after the change.

caiopoit:
I did not change the program, just those two variables, and it didn’t stop working right after the change.

So post the working version of the program before you changed the variables.

...R

That's the problem, the code worked initially and now it does not, it's the same code. Why does it work without 2 interrupts but doesn't with the 2 enabled?

Maybe you never pressed the button with the "working" code?

Maybe you never pressed the button with the "working" code?

Yes I did, I said the code was working... Now it only works if i compile it without the button part. With the button part the arduino will simply freeze up. Even without pressing it. This is my problem: Issue with two "attachInterrupt"

As explained, the call of the i2c function in the interrupt will hang the sketch. If you are seeing the sketch fail, without pressing the button, there may be a pre exisiting interrupt flag, or the attachInterrupt() set a flag itself.

LightOffPin is digital3 or INT1 with the AT328.

Try you code with clearing the INT1 Flag. Set up the interrupt this way

cli(); //disable interrupts when attaching
attachInterrupt(digitalPinToInterrupt(LightOffPin), buttonpressed, FALLING);//INT1 pin 3
EIFR |= (1<<INTF1); //clear interrupt flag by writing bit
sei();//reenable interrupts

The code should now fail when pressing the button.

THANK YOU.

If you are seeing the sketch fail, without pressing the button, there may be a pre exisiting interrupt flag, or the attachInterrupt() set a flag itself.

So, wouldn't that be a bug with the arduino compiler? Now that it's solved I want to understand what happened exactly.
Just for reference, this is the fixed code:

#include <Wire.h>
#include <TimeLib.h>
#include <DS3232RTC.h>
#define LightLevelPin 9
#define LightOffPin 3
#define AlarmPin 2
#define IndicatorLED 13
double LightLevel = 0;
double Base = 0.0039215;
byte AlarmH = 20;
byte AlarmM = 20;     // Set 30 minutes before wake time
volatile boolean WakeBoss = false;

void wakeshining();

void setup() {

  pinMode(LightLevelPin, OUTPUT);
  pinMode(IndicatorLED, OUTPUT);
  pinMode(AlarmPin, INPUT_PULLUP);
  pinMode(LightOffPin, INPUT_PULLUP);
  //  Serial.begin(9600);
  //  while (!Serial) ;                    // wait for serial
  //delay(200);
  RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
  RTC.alarm(ALARM_2);
  RTC.alarmInterrupt(ALARM_1, false);
  RTC.alarmInterrupt(ALARM_2, false);
  RTC.squareWave(SQWAVE_NONE);
  RTC.setAlarm(ALM2_MATCH_HOURS, 0, AlarmM, AlarmH, 0);
  RTC.alarm(ALARM_2);
  RTC.squareWave(SQWAVE_NONE);
  RTC.alarmInterrupt(ALARM_2, true);
  attachInterrupt(digitalPinToInterrupt(AlarmPin), waketheboss, FALLING);
  cli(); //disable interrupts when attaching
  attachInterrupt(digitalPinToInterrupt(LightOffPin), buttonpressed, FALLING);//INT1 pin 3
  EIFR |= (1 << INTF1); //clear interrupt flag by writing bit
  sei();//reenable interrupts
  //  attachInterrupt(digitalPinToInterrupt(LightOffPin), buttonpressed, FALLING);
  setPwmFrequency(LightLevelPin, 1);
}


void loop() {

  if (WakeBoss == true) {
    digitalWrite(IndicatorLED, HIGH);
    wakeshining();
  }

}

void waketheboss() {
  WakeBoss = true;
}

void wakeshining() {

  while (LightLevel < 255) {                  // 1020 increments up to 255, 1,764 secondsX1020 = 30 mins.
    for (float f = 0; f < 83000; f++) {}       // About 1 sec of delay per line
    for (float f = 0; f < 63470; f++) {}       // About 0,764 sec of delay per line
    analogWrite(LightLevelPin, LightLevel);
    LightLevel = pow(Base, 4) + 1 ;            //y=x^4...
    //    Serial.println(LightLevel);
    Base = Base + 0.0039215;
  }
  WakeBoss = false;
  digitalWrite(IndicatorLED, LOW);
}

void buttonpressed() {

  digitalWrite(LightLevelPin, LOW);
  digitalWrite(IndicatorLED, LOW);
  RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
  RTC.alarm(ALARM_1);
  RTC.alarm(ALARM_2);
  RTC.alarmInterrupt(ALARM_1, false);
  RTC.alarmInterrupt(ALARM_2, false);
  RTC.setAlarm(ALM2_MATCH_HOURS, 0, AlarmM, AlarmH, 0);
  digitalWrite(IndicatorLED, LOW);

}


void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if (pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch (divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if (pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if (pin == 3 || pin == 11) {
    switch (divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x07; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

No that's not a bug. It is documented. It's there so you can service an interrupt that happens while you have them temporarily disabled like in a critical section. If you don't want that behavior then you just have to clear the flag when you set the interrupt.

Just for reference, this is the fixed code:

Are you saying that this ISR actually executes when the button is pressed?

void buttonpressed() {

  digitalWrite(LightLevelPin, LOW);
  digitalWrite(IndicatorLED, LOW);
  RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
  RTC.alarm(ALARM_1);
  RTC.alarm(ALARM_2);
  RTC.alarmInterrupt(ALARM_1, false);
  RTC.alarmInterrupt(ALARM_2, false);
  RTC.setAlarm(ALM2_MATCH_HOURS, 0, AlarmM, AlarmH, 0);
  digitalWrite(IndicatorLED, LOW);

}

Yes, it executes. But I changed it anyway, now I set a flag and it runs on loop. But it was working, it’s just because I will modify the code in the future.