SparkFun Forums 

Where electronics enthusiasts find answers.

Topics pertaining to the Arduino Core & software used with the Artemis module and Artemis development boards.
#244603
I'm running into a problem with the Artemis Nano where I want it to go into sleep mode when a pushbutton is pressed, then exit it as soon as the button is pressed again. the sleep and wakeup functions are within interrupts and are set to trigger on a falling edge. The problem is that as soon as the the interrupt gets attached, it immediately triggers to go into sleep mode, then hard-faults and starts blinking the LED in the S.O.S. pattern.

The relevant code is below, as is the output on my serial monitor
Code: Select all
#define SLEEP_INTERRUPT   4

setup
{
    pinMode(SLEEP_INTERRUPT, INPUT);
#ifdef DEBUG
  Serial.print("About to attach interrupt");
#endif
  attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT), sleepModeSwitch, FALLING);
#ifdef DEBUG
  Serial.print("Interrupt attached");
#endif
}

void sleepModeSwitch()
{
#ifdef DEBUG
  Serial.print("Interrupt triggered! button status: "); Serial.println(digitalRead(SLEEP_INTERRUPT));
#endif
  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 != 18)
    {
      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;
}
DATARX 055 INITIAL TEST
About to attach interrupt
Interrupt triggered! button status: 1
Going to sleep


++ MbedOS Error Info ++
Error Status: 0x80FF0144 Code: 324 Module: 255
Error Message: Assertion failed: status == osOK
Location: 0x29FED
File: mbed-os/rtos/source/ThisThread.cpp+225
Error Value: 0x0
Current Thread: main Id: 0x10006E2C Entry: 0x2B141 StackSize: 0x1000 StackMem: 0x10005E08 SP: 0x1005FED4
For more info, visit: https://mbed.com/s/error?error=0x80FF01 ... TEMIS_NANO
-- MbedOS Error Info --
Attached to the relevant pin is a basic RC debounce circuit, seen below:
Image

I'm still testing, but I wanted to get some thoughts on what was happening here. According my multimeter and oscilloscope, the signal isn't oscillating so I don't know what could be generating the falling edge that *should* be needed to trigger the interrupt. Any thoughts on what might be happening?
You do not have the required permissions to view the files attached to this post.
#244612
Some further information. It appears that, while the interrupt is being called *very* prematurely as soon as its attached to a pin, it only seems to run once. I added some code to toggle two different LEDs based on whether or not the Artemis is in sleep mode. These LEDs toggle inversely to one another; When the Artemis is asleep, one is on and the other is off. Vice Versa when awake. However, as soon as the LEDs are indicating sleep mode, there's about half a second of illumination before they are both completely dark. Additionally, there's no hardfault message or S.O.S flashing from one of the LEDs, which is strange to me.
#244632
An update based on further testing:

I cut out all the stuff inside the interrupt related to sleeping and waking up just so I could see the interrupt itself in action by toggling two LEDs on and off (one is on when the other is off, vice versa). The interrupt is still being called as soon as its attached, and I've received suggestions to clear the interrupt flag before attaching it. I'm working trying something like that now
#244662
The problem with your code is that you are attaching the interrupt to the pushbutton before you have initialized the sleep mode subsystem. This is causing the interrupt to trigger immediately and put the board into sleep mode before the sleep mode subsystem is ready.

To fix the problem, you need to initialize the sleep mode subsystem before you attach the interrupt. You can do this by calling the initSleepMode() function before you call the attachInterrupt() function.

Here is a revised version of your code that should fix the problem:

C++
#define SLEEP_INTERRUPT 4

void setup() {
// Initialize the sleep mode subsystem.
initSleepMode();

// Set the pushbutton pin to input mode.
pinMode(SLEEP_INTERRUPT, INPUT);

// Attach the interrupt to the pushbutton.
attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT), sleepModeSwitch, FALLING);
}

void sleepModeSwitch() {
// If the board is in sleep mode, wake it up.
if (isSleepMode()) {
wakeUp();
} else {
// Put the board into sleep mode.
goToSleep();
}
}

With this revised code, the interrupt will only trigger when the pushbutton is pressed, and the board will not go into sleep mode until the sleep mode subsystem is ready.
#244664
ReahaTaul wrote: Thu Oct 19, 2023 4:57 am The problem with your code is that you are attaching the interrupt to the pushbutton before you have initialized the sleep mode subsystem. This is causing the interrupt to trigger immediately and put the board into sleep mode before the sleep mode subsystem is ready.

To fix the problem, you need to initialize the sleep mode subsystem before you attach the interrupt. You can do this by calling the initSleepMode() function before you call the attachInterrupt() function.

Here is a revised version of your code that should fix the problem:

C++
#define SLEEP_INTERRUPT 4

void setup() {
// Initialize the sleep mode subsystem.
initSleepMode();

// Set the pushbutton pin to input mode.
pinMode(SLEEP_INTERRUPT, INPUT);

// Attach the interrupt to the pushbutton.
attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT), sleepModeSwitch, FALLING);
}

void sleepModeSwitch() {
// If the board is in sleep mode, wake it up.
if (isSleepMode()) {
wakeUp();
} else {
// Put the board into sleep mode.
goToSleep();
}
}

With this revised code, the interrupt will only trigger when the pushbutton is pressed, and the board will not go into sleep mode until the sleep mode subsystem is ready.
Well, that would hopefully fix the sleep mode stuff, but I actually commented out everything related to putting the Artemis to sleep in the interrupt and replaced it with alternating two LEDs (When in "sleep mode" one turns on, other turns off. When "awake" vice versa). Turns out that as soon as the interrupt is attached to the pin, it triggers without a button press.

From what I understand, me declaring the button pin as an INPUT_PULLUP is creating enough of a falling edge to qualify, and the Artemis is remembering that it happened and triggering the interrupt immediately. Assuming that's the case, I need to clear the "interrupt has occurred" flag before I attach the interrupt, which I still can't figure out how to do. Yet.
#244666
I have just checked some of the code. As you set a attachinterrupt() the first time, it will initialize the complete IRQ system and subsequently clear any interrupt-flag that might be pending, before setting the interrupt. As I have a Nano I tried it as well and I run into the same issue as you. Still trying to find out way, but as soon as the interrupt is being set it triggers.
For now a workaround: debounce structure which is always good to implement with a switch.
Code: Select all
 
#define SLEEP_INTERRUPT  9

bool ledstat = false;       // led start condition
bool prevstat = ledstat;    // remember the previous led condition
unsigned long debounce;     // Stores the last millis()
#define DEBOUNCETIME 1000   // number of milli seconds needed between pushes

void setup() {
  Serial.begin(115200);
  while (!Serial); //Wait for the serial port to come online

  Serial.println(F("check interrupt with led"));
  pinMode(LED_BUILTIN, OUTPUT);
 
  // Set the pushbutton pin to input mode.
  pinMode(SLEEP_INTERRUPT, INPUT);
  
  debounce = millis();
  
  // Attach the interrupt to the pushbutton.
  attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT), sleepModeSwitch, FALLING);
}

void sleepModeSwitch() {
  if (millis() -debounce < DEBOUNCETIME ) return;  // debounce wait 

  ledstat = !ledstat;
  digitalWrite(LED_BUILTIN,ledstat);

  debounce = millis();
}

void loop() {
  if (prevstat != ledstat) {
    if (ledstat) Serial.println("Led is on");
    else Serial.println("Led is off");
    
    prevstat = ledstat;
  }
}
#244667
found it.... and fixed

During the first initialization, the interrupts are enabled, and thus before really setting the interrupt.
copy attached file to: arduino15/packages/SparkFun/hardware/apollo3/2.2.1/cores/arduino/mbed-bridge/core-implement to replace CommonInterrupt.cpp. Recompile your sketch and it should work now.

note: the patch is on my Ubuntu, if you use Windows it is in another place.
You do not have the required permissions to view the files attached to this post.
#244670
paulvha wrote: Thu Oct 19, 2023 7:50 am found it.... and fixed

During the first initialization, the interrupts are enabled, and thus before really setting the interrupt.
copy attached file to: arduino15/packages/SparkFun/hardware/apollo3/2.2.1/cores/arduino/mbed-bridge/core-implement to replace CommonInterrupt.cpp. Recompile your sketch and it should work now.

note: the patch is on my Ubuntu, if you use Windows it is in another place.
This is about as far as it got before things went wonky
C:\Users\Farnaz\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.2.1\cores\arduino\mbed-bridge\core-implement\CommonInterrupt.cpp:177:6: error: no declaration matches 'void arduino::InterruptInParam::_irq_handler(uintptr_t, gpio_irq_event)'
void InterruptInParam::_irq_handler(uintptr_t id, gpio_irq_event event) // {feb 2023}
^~~~~~~~~~~~~~~~
In file included from C:\Users\Farnaz\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.2.1/cores/arduino/mbed-bridge/core-extend/ArduinoAPI.h:9,
from C:\Users\Farnaz\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.2.1/cores/arduino/mbed-bridge/Arduino.h:20,
from C:\Users\Farnaz\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.2.1/cores/arduino/sdk/ArduinoSDK.h:9,
from <command-line>:
C:\Users\Farnaz\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.2.1/cores/arduino/mbed-bridge/core-extend/Common.h:111:17: note: candidate is: 'static void arduino::InterruptInParam::_irq_handler(uint32_t, gpio_irq_event)'
static void _irq_handler(uint32_t id, gpio_irq_event event);
^~~~~~~~~~~~
C:\Users\Farnaz\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.2.1/cores/arduino/mbed-bridge/core-extend/Common.h:64:7: note: 'class arduino::InterruptInParam' defined here
class InterruptInParam : public mbed::InterruptIn {
^~~~~~~~~~~~~~~~
"C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\tools\\arm-none-eabi-gcc\\8-2018-q4-major/bin/arm-none-eabi-g++" -include "C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO/mbed/mbed_config.h" -include "C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino/sdk/ArduinoSDK.h" -iprefix "C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/" "@C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO/mbed/.cxx-flags" -MMD -DARDUINO=10813 -DARDUINO_APOLLO3_SFE_ARTEMIS_NANO -DARDUINO_ARCH_MBED -DARDUINO_ARCH_APOLLO3 -DMBED_NO_GLOBAL_USING_DIRECTIVE -DCORDIO_ZERO_COPY_HCI "@C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO/mbed/.cxx-symbols" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\cores\\arduino" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino/mbed-bridge" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino/mbed-bridge/core-api" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino/mbed-bridge/core-api/api/deprecated" "@C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO/mbed/.includes" "C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\cores\\arduino\\mbed-bridge\\core-implement\\CommonTiming.cpp" -o "C:\\Users\\Farnaz\\AppData\\Local\\Temp\\arduino_build_513726\\core\\mbed-bridge\\core-implement\\CommonTiming.cpp.o"
"C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\tools\\arm-none-eabi-gcc\\8-2018-q4-major/bin/arm-none-eabi-g++" -include "C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO/mbed/mbed_config.h" -include "C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino/sdk/ArduinoSDK.h" -iprefix "C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/" "@C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO/mbed/.cxx-flags" -MMD -DARDUINO=10813 -DARDUINO_APOLLO3_SFE_ARTEMIS_NANO -DARDUINO_ARCH_MBED -DARDUINO_ARCH_APOLLO3 -DMBED_NO_GLOBAL_USING_DIRECTIVE -DCORDIO_ZERO_COPY_HCI "@C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO/mbed/.cxx-symbols" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\cores\\arduino" "-IC:
\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino/mbed-bridge" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino/mbed-bridge/core-api" "-IC:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1/cores/arduino/mbed-bridge/core-api/api/deprecated" "@C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\variants\\SFE_ARTEMIS_NANO/mbed/.includes" "C:\\Users\\Farnaz\\AppData\\Local\\Arduino15\\packages\\SparkFun\\hardware\\apollo3\\2.2.1\\cores\\arduino\\mbed-bridge\\core-implement\\HardwareSerial.cpp" -o "C:\\Users\\Farnaz\\AppData\\Local\\Temp\\arduino_build_513726\\core\\mbed-bridge\\core-implement\\HardwareSerial.cpp.o"
Using library Wire at version 2.0.0 in folder: C:\Users\Farnaz\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.2.1\libraries\Wire
Using library ArduinoBLE at version 1.2.2 in folder: C:\Users\Farnaz\Documents\Arduino\libraries\ArduinoBLE
Using library EEPROM at version 2.0.0 in folder: C:\Users\Farnaz\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.2.1\libraries\EEPROM
Using library Adafruit_Unified_Sensor at version 1.1.2 in folder: C:\Users\Farnaz\Documents\Arduino\libraries\Adafruit_Unified_Sensor
Using library Adafruit_BNO055 at version 1.1.11 in folder: C:\Users\Farnaz\Documents\Arduino\libraries\Adafruit_BNO055
 Topic permissions

You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum