0
votes

I have one pushbutton (and a rotary encoder) in a Teensy 3.1 (ARM) project. All is well except I'm having issues with putting it to sleep. Everything is working the first time after a reset, but each time after that, attachInterrupt() appears to not work.

Using this library for the sleep mode call.

Pseudocode:

#include LowPower_Teensy3.h
#include MyButton.h
TEENSY3_LP LP = TEENSY3_LP();
MyButton mySwitch(SWITCH_PIN); // pinMode(SWITCH_PIN, INPUT_PULLUP)

// interrupt handler
void wakeup(void)
{
  digitalWrite(LED, HIGH);
  detachInterrupt(SWITCH_PIN);
}

void setup(){
  // omitted for clarity
}

void loop() {
  switch(menuSelection) {
    // poll switch and encoder to determine menu selection

    // lots of other cases omitted. all work as expected

    case SLEEP_MENU:
      digitalWrite(LED, LOW);
      attachInterrupt(SWITCH_PIN, wakeup, FALLING);
      LP.Sleep();
      break;
  }
}

It seems like SWITCH_PIN is no longer associated with mySwitch after the interrupt.

1

1 Answers

1
votes

Detaching an interrupt handler while executing that interrupt handler is likely a problem. Keep in mind that a library function called your wakeup() and within wakeup() you modified the data the library was operating on. A better pattern is for the handler to leave behind a message that the main loop will then cleanup.

int flagWakeupDone = 0;

void wakeup(void)  {
  ...
  flagWakeupDone = 1;
  return;
}


void loop() {

  if(1 == flagWakeupDone) {
    detachInterrupt(SWITCH_PIN);
    // possibly restablish pin as input with pull up
  }

  ... 

  switch(menuSelection) {

    case SLEEP_MENU:
      ...
      attachInterrupt(SWITCH_PIN, wakeup, FALLING);
      break;
  }

  return;
}