I'm trying to implement a button-operated sleep mode toggle on a Sparkfun Artemis module. Button press one puts the Artemis to sleep, button press two wakes it up. I'm coding it in the Arduino IDE and I've been running into this one problem. Basically, as soon as I reach then line in setup that attaches the interrupt routine to the pin/button, the interrupt IMMEDIATELY triggers and sends it into sleep mode.
The interrupt is configured to trigger on a Falling Edge, and is pulled high both internally and externally by a 10k resistor, seen below:
Below is also the relevant code for the interrupt, sleeping and waking up. According to the debug outputs on the serial monitor, as soon as the attachInterrupt() line runs, the interrupt triggers and the device goes to sleep.
void setup(void) { int cnt = 0; pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected pinMode(BATTERY_LED, OUTPUT); pinMode(SLEEP_INTERRUPT, INPUT_PULLUP); digitalWrite(SLEEP_INTERRUPT, HIGH); delay(50); #ifdef DEBUG Serial.begin(115200); #endif ledTimer = millis() ; #ifdef DEBUG Serial.print("About to attach interrupt. button status: "); Serial.println(digitalRead(SLEEP_INTERRUPT)); #endif attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT), sleepModeSwitch, FALLING); #ifdef DEBUG Serial.print("Interrupt attached"); #endif deepSleepTimer = millis() ; } void sleepModeSwitch() { if(sleep_mode_status == false) { goToSleep(); } else { wakeUp(); } } void goToSleep() { sleep_mode_status = true; #ifdef DEBUG Serial.println("Going to sleep"); delay(50); //Wait for serial to finish Serial.end(); //Power down UART(s) #endif // turn off the led. digitalWrite(LED_BUILTIN, LOW); // Stop the BLE advertising. BLE.stopAdvertise() ; powerControlADC(false); for(int x = 0; x < 50; x++) { if(x != SLEEP_INTERRUPT) { am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE); } } //Power down Flash, SRAM, cache am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); //Turn off CACHE am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); //Turn off everything but lower 512k am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); //Turn off everything but lower 64k //am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover) // // Enable interrupts to the core. am_hal_interrupt_master_enable(); // //Enable the timer interrupt in the NVIC. // NVIC_EnableIRQ(STIMER_CMPR6_IRQn); //Go to Deep Sleep. am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); } void wakeUp() { am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX); // Renable UART0 pins am_hal_gpio_pinconfig(48, g_AM_BSP_GPIO_COM_UART_TX); am_hal_gpio_pinconfig(49, g_AM_BSP_GPIO_COM_UART_RX); am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_UART0); initializeADC(); #ifdef DEBUG Serial.begin(115200); Serial.println("Waking up! Hello world!"); #endif deepSleepTimer = millis() ; sleep_mode_status = false; } Also, if DEBUG is defined, it'll crash after printing "going to sleep...", which I believe is being caused by a call to the UART after it's already been disabled for sleep. Unfortunately, that also makes it hard for me to see what's going on after the interrupt is triggered since I don't have my debug prints to tell me that. I did some reading around and while I did (and still might) suspect EMI causing these false-positives, this is all being powered by a 3.7V lipo battery and I couldn't see visible oscillations on my oscilloscope with the smallest interval of time available on it, nor was there enough of a peak and valley on the voltage to be visible that I could see either.
Does anyone have any clue what might be happening?
update: I added an extra line that would turn an LED on or off based on whether it was asleep (LED off) or awake (LED on) and also ran them in reverse for good measure (asleep LED on, awake LED off). The only time I saw the LED turn on was when it was asleep, and it was only for about half a second before it turned off again. So, it seems the interrupt is only being triggered the one time since it doesn't seem to go to sleep and then wake up (wash, rinse, repeat).
update 2: Ran another test with the oscilloscope to recheck for voltage variance. Oscilloscope was set to 500mV and 5 nanoseconds per division, and it was basically just a straight line all the way through, even when the interrupt triggered. No button press, no debounce, nothing.
update 3: thanks to jms' suggestions, I've found that once all the sleep-mode-specific code is removed from the interrupt and I'm just toggling some LEDs on and off, the button operation works fine. No debounce that I've observed, but I'm still seeing that same problem of the interrupt firing once as soon as it's attached to the pin, as evidenced by the following serial output.
About to attach interrupt. button status: 1 Going to sleep... Interrupt attached
After that, I can press the button all I want and only get one response per button press.
I'm looking into seeing if manually clearing the interrupt flag before attaching it (per jms' suggestion) will fix it.

SLEEP_INTERRUPTshould have a!in the name to indicate that this is active-low. \$\endgroup\$