Problem with two interrupt

Hello evreyone,

I have an issue with two interrupt.

An interrupt isttriggered each 5 second to wakeup my board.

LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, triggeredAlarm, CHANGE);

The second is triggered when a drop falls into the rain gaude, and wakeup my board.

LowPower.attachInterruptWakeup(pin_arrosage, triggeredDropArrosage, RISING);

Over all, it's works fine, excepted that some time my code stop working. The loop stops.

I observedand I guess because I am not sure, the problem appear when the two intterrupt are triggeredat the same time.
Or, at a very close same time.

I haerd that two interrupt can not occur at the same time. The second is waiting until the first occur.
I also heard that an ISR must be short as possible.
I finaly heard the no Serial.print must occured in a interrupt

Now, I red that an ISR must complete its job within 6ms, or the second interrupt must occurs 6ms after the first.

So what is Ture, what is False??

Any Idea?

I am aware, that my ISR are too long, in any case because I add a Serial for debuging and I would like to have a led flashing when a interrupt occure.

Here is my bad code:

// Need to flash a LED and increment a value
void triggeredDropArrosage()
{
   vcountDrops=vcountDrops+1;
    //led_state = !led_state;
 
  sw.digitalWrite(wakeup_led,HIGH);
  delayMicroseconds(50000);
  sw.digitalWrite(wakeup_led,LOW);
  delayMicroseconds(50000);
  sw.digitalWrite(wakeup_led,HIGH);

}

// Only need to flash a LED
void triggeredAlarm(){
  sw.digitalWrite(wakeup_led,HIGH);
  delayMicroseconds(50000);
  sw.digitalWrite(wakeup_led,LOW);
  delayMicroseconds(50000);
  sw.digitalWrite(wakeup_led,HIGH);
   delayMicroseconds(50000);
  sw.digitalWrite(wakeup_led,LOW);
  delayMicroseconds(50000);
  sw.digitalWrite(wakeup_led,HIGH);
  Si.sprintln(F("Alarm Wakeup now!"),1);
}

So, depending of what is False or True, how can I improve my two ISR to have a LED flashing and a Serial.print for debuging

Impoartant, as well, is there a way to make sure that triggeredDropArrosage() DO NOT occur , some ms before and after triggeredAlarm() is called?

How fast (in ms) an ISR must be completed?

many thank

Move the LED flashing and printing out of the ISR. Instead set a flag in the ISR and use the flag to trigger actions in loop(). Do not use delay() or delayMicroseconds() anywhere in the code. Use millis() for timing instead and keep loop() running as fast as possible.

My first change is the following

void triggeredAlarm(){
  sw.digitalWrite(wakeup_led,HIGH);
}

But for the second, I would like to have the led flashing twice

Not good Idea?

void triggeredDropArrosage()
{
    vcountDrops=vcountDrops+1;
   
  sw.digitalWrite(wakeup_led,HIGH);
  delayMicroseconds(50000);
  sw.digitalWrite(wakeup_led,LOW);
  delayMicroseconds(50000);
  sw.digitalWrite(wakeup_led,HIGH);
}

UKHeliBob:
Move the LED flashing and printing out of the ISR. Instead set a flag in the ISR and use the flag to trigger actions in loop(). Do not use delay() or delayMicroseconds() anywhere in the code. Use millis() for timing instead and keep loop() running as fast as possible.

Ok I have not seen you answr before I post my last message

Show the complete sketch.
Use CTRL T to format your code.
Attach your sketch between code tags
[code]Paste your sketch here[/code]

ISRs should be short executing code.
Set a flag and get out.
ISR variables should be made ‘volatile’.
When you detect the flag is set in loop then call a function to handle it.

Learn to use BlinkWithoutDelay techniques, example in examples in the IDE.
also see Robin2’s discussion on doing several things at once.

But for the second, I would like to have the led flashing twice

Not good Idea?

Flash it as many times as you want but don't do it in the ISR and don't use delay() or delayMicroseconds()

Hello all
Thank a lot for your reply.

I modified my code as the following and it look to work fine now. (I have to test it more)
My recent test, was to move the bunket of my rain gauge as fast as pssoible until the next mesure.
When I was doing it my code stop running. Now it does not happe :slight_smile:

First to make you understanding, here is how work my board

  • is sleeping for 5 seconde (timeSleep)
  • wakeup, flash the led wakeup_led
  • and reapt it for 1 minute

When the bunket move, it wakeup my board, inrement a variable, and my board goes to sleep.

As it take about 15second to measure the value of my sensor, I deduct about 15 sec from one minute in order to make sure that the measure happen each minute, and not each minute + 15 seconde :slight_smile: .
This not important and not my issue. it work

 for (int i=0; i<int((TX_INTERVAL-((timeToSend/1000)+(timeSleep/1000)))/(timeSleep/1000)); i++) {
          Si.sprintln(F("DEBUG:sleep "),2);
          #if defined(OLED)
            display.print(". ");
            display.display();
          #endif
          sw.digitalWrite(wakeup_led,LOW);
          LowPower.sleep(timeSleep);
          sw.digitalWrite(wakeup_led,HIGH);

          if(flagAlarm == true){
            flagAlarm = false; // This part is not really usefull as the alarm_led is manager just before and after LowPower.sleep()
          }
          if(flagDrop == true)
          {
// If the bncket has moved, flash another led twice
            flagDrop = false;
            sw.digitalWrite(led_flag_drop, HIGH);
            delay(100);
            sw.digitalWrite(led_flag_drop, LOW);
            delay(100);
            sw.digitalWrite(led_flag_drop, HIGH);
            delay(100);
            sw.digitalWrite(led_flag_drop, LOW);
            Si.sprint(F("DEBUG Drop:"),2);
            Si.sprintln(vcountDrops,2);
            
          }
        }

In other word, when it goes sleep it turn off the led 'wakeup_led' and turn it on when the board wakeup.
I do not need a led in the ISR triggeredAlarm

First my ISR triggeredAlarm.
I remove the led. As I remove it, This is not really useful as you can see. I also can remove the flag..

void triggeredAlarm(){
  flagAlarm = true;
}

(I declared flagAlarm as volatile and bool)

Now triggeredDropArrosage() is a bit more tricky

void triggeredDropArrosage()
{
  vcountDrops=vcountDrops+1;
  delayMicroseconds(100000); // 100ms
  flagDrop = true;
}

First, I have to keep

vcountDrops=vcountDrops+1;

because this ISR can be called when my boad sleep or when my board is sending the measure.
the vcountDrops variable must increment at any time and I can not manage it within a flag, because I would have to control the flag after each measures....

Important, I observed, when my buncket move from a side to another, it count 1,3,4,6,8. It's not incrementing may be because of bouncing..... The ISR triggeredDropArrosage is caled 1 or 1 time.

I observed adding a small delay with

delayMicroseconds(10000); // 10ms

it solves my issue, but I know that ISR must be as fast as possible, si it should not be a good idea.

I have not tried to reduce that delay to

delayMicroseconds(5000); // 5ms

or even less, but for now it's the only solution to have my variable 'vcountDrops' incrementing correctly.

What do you things?
(I hope, you understand my code)