0

My question is quite simple. I am using one external interrupt on the Mega2560 to wake it up with an alarm from the rtc DS3231 and record data from sensors for about 30 seconds and I would like also to use the other external interrupt to wake it up in case of shock detection to measure the signal.

The thing is that I know external interrupts have priority on internal interrupt but is it possible to put, in my case, the shock detection prior to the alarm ? In case the shock occurs during the alarm recording I would prefer to record the shock signal.

Thank you for your help !

  • Is it really important to catch the case, that both interrupts fire at the same time? That's seems to be a rather rare case. Maybe it would be sufficient to check the shock interrupt flag at the start of the alarm ISR. – chrisl Sep 6 '19 at 9:02
  • Hi ! Ok so it is not possible to have priorities between external interrupts ? I agree that it would be bad luck if the shock occurs at that moment but I wanted a rather robust system. Your idea of checking the flag at the moment of the alarm will just tell me if a shock occured but I wouldn't get the intensity of it... I guess I will have to make a compromise. Thank you ! – JamesONeil Sep 6 '19 at 9:21
2

Interrupts are not the right place to handle priorities. The interrupt handlers should be as short as possible. Then the likeliness of two of them happening at the same time is very low. And even if it happens, the lowest-priority interrupt will only be delayed by a handful of microseconds, which should not be a big deal.

In this case, the sensible approach is to have the interrupt handlers set a global flag and do nothing else. Then the main program will check the flags and do the real work, handling the priorities as needed.

Conceptually, the code could be something along these rough lines:

// Global flags.
volatile bool alarmDetected;
volatile bool shockDetected;

// Interrupt handlers.
void onAlarmInterrupt() { alarmDetected = true; }
void onShockInterrupt() { shockDetected = true; }

void loop() {
    if (shockDetected) {  // check this first!
        measureShockData();
        if (gotEnoughShockData()) {
            shockDetected = false;
            alarmDetected = false;  // ignore the alarm
            goToSleep();
        }
    } else if (alarmDetected) {
        recordSensorData();
        if (gotEnoughSensorData()) {
            alarmDetected = false;
            goToSleep();
        }
    }
}

Note that you can remove the line that ignores the alarm in case of shock. If you do so, the alarm will be handled after all relevant shock data has been recorded.

| improve this answer | |
  • Hi ! Thank you for your solution I think I will go with it ! – JamesONeil Sep 6 '19 at 9:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.