Arduino BLE with watchdog interrupt deep sleep

Hello

I have a project I’m working on that I want to turn on BLE for a quick second and connect to my phone. If there is no connection after a short time then it should just go back into deep sleep. After this, I wanted watchdog to wake the system back up after 10 seconds and repeat this process. So far, I have used the Arduino BLE library and watchdog deep sleep examples for waking up the system after 10 seconds and that works fine but when I bring in BLE to it, the system constantly goes into deep sleep and immediately wakes up after around half a second instead of 10 seconds. If I comment out the BLE.begin lines, the problem goes away, but obviously BLE is not on anymore.

This was the deep sleep watchdog example I started with:

https://github.com/sparkfun/Arduino_Apo … wPower.ino

Is there a better way to solve this problem other than a watchdog wake up interrupt?

I am very new to this, so I don’t know if I’m missing something simple.

Here is my code so far:

#include "RTC.h"
#include "WDT.h"
#include <ArduinoBLE.h>

BLEService motorService("19B10000-E8F2-537E-4F6C-D104768A1214"); // create service

// create motor characteristic and allow remote device to write
BLEByteCharacteristic motorCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLEWrite);
int flag = 0;

volatile bool alarmFlag = false; // RTC ISR flag
volatile bool watchdogFlag = true; // Watchdog Timer ISR flag
volatile int watchdogInterrupt = 0; // Watchdog interrupt counter

void setup()
{
  Serial.begin(115200);

  Serial.println("Artemis Watchdog Low Power Example");

  // Set the RTC time using UNIX Epoch time
  rtc.setEpoch(1596240000); // Saturday, August 1, 2020 00:00:00

  // Set the RTC's alarm
  //rtc.setAlarm(0, 0, 0, 0, 0, 0); // Set alarm (hund, ss, mm, hh, dd, mm)
  //rtc.setAlarmMode(6); // Set the RTC alarm to trigger every minute
  //rtc.attachInterrupt(); // Attach RTC alarm interrupt

//  Serial.print("Before BLE: ");
//  BLEsetup();
//  Serial.print("After BLE: ");
//  printDateTime();
  
  
  // Configure the watchdog timer
  // See Example2_WDT_Config for more information on how to configure the watchdog
  wdt.configure(WDT_16HZ, 160, 240); // 16 Hz clock, 10-second interrupt period, 15-second reset period

  // Start the watchdog
  wdt.start();
}
/////////////Start Bluetooth and start advertising
void BLEsetup() {
  //Serial.begin(9600);
  //while(!Serial);

  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  
  if (!BLE.begin()) {
    //Serial.println("starting BLE failed!");

    while(1);
  }
  Serial.println("BLE Begun");
  BLE.setLocalName("MotorCallback");
  BLE.setAdvertisedService(motorService);
  motorService.addCharacteristic(motorCharacteristic);
  BLE.addService(motorService);

  //BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  //BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);

  // assign event handlers for characteristic
  //motorCharacteristic.setEventHandler(BLEWritten, motorCharacteristicFunc);
  // set an initial value for the characteristic
  motorCharacteristic.setValue(0);

  // start advertising
  BLE.advertise();

  //Serial.println(("Bluetooth device active, waiting for connections..."));
}

void loop()
{
  // Check for alarm interrupt
//  if (alarmFlag)
//  {
//    Serial.print("Alarm interrupt: ");
//    printDateTime(); // Print RTC's date and time
//    alarmFlag = false;
//
//    wdt.restart(); // "Pet" the dog
//    watchdogInterrupt = 0; // Reset watchdog interrupt counter
//  }

  // Check for watchdog interrupt
  if (watchdogFlag)
  {
    Serial.print("Watchdog interrupt: ");
    printDateTime(); // Print RTC's date and time
    //watchdogFlag = false; // Clear watchdog flag
    

  }
  
  
  Serial.print("Before BLE Setup: ");
  BLEsetup();
  Serial.print("After BLE Setup: ");
  printDateTime();

  BLE.poll();
  delay(1000);

  Serial.println("Need to handle BLE event here!");
  
  BLE.end();

  wdt.restart();
  
  goToSleep(); // Enter deep sleep
}

// Print the RTC's current date and time
void printDateTime()
{
  rtc.getTime();
  Serial.printf("20%02d-%02d-%02d %02d:%02d:%02d.%02d\n",
                rtc.year, rtc.month, rtc.dayOfMonth,
                rtc.hour, rtc.minute, rtc.seconds, rtc.hundredths);
  Serial.println();
}

// Power down gracefully
void goToSleep()
{
  Serial.println("Going to Sleep!");
  printDateTime();
  // Disable UART
  Serial.end();

  // Disable ADC
  powerControlADC(false);
  
  // Force the peripherals off
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_BLEL);
  // Disable all pads (except UART TX/RX)
  for (int x = 0 ; x < 50 ; x++)
    am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);

  //Power down CACHE, flashand SRAM
  am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); // Turn off CACHE and flash
  am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_384K); // Retain all SRAM (0.6 uA)

  // Keep the 32kHz clock running for RTC
  am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
  am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);

  am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); // Sleep forever

  // And we're back!
  wakeUp();
}

// Power up gracefully
void wakeUp()
{
  // Go back to using the main clock
  am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
  am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);

  // 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);

  // Renable power to UART0
  am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_UART0);

  // Enable ADC
  initializeADC();

  // Enable Serial
  Serial.begin(115200);
  Serial.println("Woke Up!");
  printDateTime();
}

// Interrupt handler for the watchdog.
extern "C" void am_watchdog_isr(void)
{
  // Clear the watchdog interrupt
  wdt.clear();

  // Perform system reset after 10 watchdog interrupts (should not occur)
//  if ( watchdogInterrupt < 10 )
//  {
//    //wdt.restart(); // "Pet" the dog
//  }
//  else {
//    while (1); // Wait for reset to occur
//  }

//  watchdogFlag = true; // Set the watchdog flag
//  watchdogInterrupt++; // Increment watchdog interrupt counter
}