I realised a routine for starting an exposure timer, which has a single start button at INT1 and the same button should be used to store permanently the selected time (set by a rotary encoder on the remaining pin INT0) into the EEPROM for further usage, if found worthwhile.
Depending on the duration time the button is pressed, different actions will start accordingly. During these activities the interrupts are temporarily blocked from being interrupted by other interrupts.
Here is what I did to swap interrupt modes within different but corresponding ISRs. I hope it may help a bit.
Have fun...
InlineSkater
/*------------------------------------------------------------------+
| Question: Can we have an ISR on one pin with different reaction |
| modes set? Answer: Yes, we can... |
| |
| Successfully tested with Arduino Nano in breadboard testbed |
| |
| Author : InlineSkater |
| Date : 23.01.2016 20:30:28 |
| Revision : 1.0 |
| |
| Switch goes low at Pin 3: checked bei ISR, indicated by red LED |
| ISR mode change realised within two corresponging ISRs to detect |
| falling & subsequent rising edge of start pulse. Short & long |
| pulse discriminated and corresponding action started. |
+------------------------------------------------------------------*/
#define DEBUG
#define REDLED 13
#define BUTTON 3
long unsigned int startTime;
long unsigned int stopTime;
int delta_time;
int delta_store = 600;
int delta_start = 50;
void setup() {
#ifdef DEBUG
Serial.begin(9600);
Serial.println(">>> button_test4 >>>");
while(!Serial) {
// wait here for established serial connection
}
#endif
pinMode(BUTTON, INPUT);
digitalWrite(BUTTON, HIGH);
pinMode(REDLED, OUTPUT);
digitalWrite(REDLED, HIGH);
attachInterrupt(INT1, button_low_isr, FALLING);
}
void loop() {
delta_time = stopTime - startTime;
if (delta_time >= delta_store) { // was it a short/long duration?
#ifdef DEBUG
Serial.println("ACTION 1");
#endif
action0_task(); // it was a long duration pulse
} else {
if (delta_time >= delta_start) {
#ifdef DEBUG
Serial.println("ACTION 0");
#endif
action1_task(); // it was a short duration pulse
}
}
}
void action0_task() { // store display time into EEPROM
noInterrupts(); // as a semaphore: no ISR allowed
// action code here: store digits with no interruption
interrupts();
}
void action1_task() { // start display time count down
noInterrupts(); // as a semaphore: no ISR allowed
// action code here: start timer with no interruption
interrupts();
}
void button_low_isr() { // 1st action: button goes low and we see it
digitalWrite(REDLED, LOW);
startTime = millis(); // time shall be noted & mode changed
attachInterrupt(INT1, button_high_isr, RISING);
}
void button_high_isr() { // 2nd action: button goes high and we see it
digitalWrite(REDLED, HIGH);
stopTime = millis(); // time shall be noted & mode changed
attachInterrupt(INT1, button_low_isr, FALLING);
}