unable to wake from lowpower.sleep using external interrupt

I built a voltage logger that takes a user defined voltage threshold and compares it to a measured voltage(using an INA260 configured for HIGH side measuring). The device uses two tilt switches to monitor device movement, every time the device moves it restarts a 5 minute timer, if the device does NOT move for 5 minutes the processor will enter a lowpower.sleep. It will stay here until a pin status CHANGE occurs on any of the interrupt pins(2 & 3), once a status change occurs the processor should wake up and begin monitoring again. If the processor measures a voltage of which is outside the user defined upper OR lower limit, it will save this data(voltage and current) to the onboard SPI FLASH and continue to monitor.

The components I'm using are:
Adafruit ItsyBitsy M0 Express(STSAMD21G18 32-bit cortx M0)
Adafruit INA20 HIGH/LOW side voltage, current power sensor
Self built Li-Ion battery management using MCP73831.

The device works as it should except for the tilt interrupts, I want it to respond to a CHANGE in their status, but once the processor goes to lowpower.sleep, the tilt interrupts do NOT work to wake it, nor do they work to restart 5 minute time(though if I change the mode to LOW for Xtilt and Ytilt, it will restart the timer but still will NOT wake the board). Below is my code and my circuit, any help is much appreciated, thank you!

sketch_dec05b.ino (7.52 KB)

Sorry, code didn’t post.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_INA260.h>
#include <SdFat.h>
#include <Adafruit_SPIFlash.h>
#include "ArduinoLowPower.h"

// On-board external flash (QSPI or SPI) macros should already
// defined in your board variant if supported
Adafruit_FlashTransport_QSPI flashTransport;

Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);

#error No QSPI/SPI flash are defined on your board variant.h !

Adafruit_SPIFlash flash(&flashTransport);

// file system object from SdFat
FatFileSystem fatfs;

// Configuration for the datalogging file:
#define FILE_NAME      "data.csv"

Adafruit_INA260 ina260 = Adafruit_INA260();

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET  7 // Reset pin # (or -1 if sharing Arduino reset pin)

//Pins definitions
#define enterPin 9
#define upPin 10
#define downPin 11
#define XtiltPin 2
#define YtiltPin 3

//Declare variables
uint8_t sequence = 0; //sequence of main program
float upVolt = 25.0; //up voltage limit
float loVolt = 10.0; //down voltage limit
float voltage; //measure voltage sensor
float current; //measure current sensor
volatile bool Xtilt; //measure x tilt sensor
volatile bool Ytilt; //measure y tilt sensor
bool up, down, enter; //measure the state of the buttons
uint16_t timer;  //take the 100ms time
uint16_t timeTilt;  //take the 5 minutes tilt time
uint16_t timeSave; //time when the voltage measure is out of range

void setup() {
  //pins as input
  pinMode(enterPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(XtiltPin, INPUT_PULLUP);
  pinMode(YtiltPin, INPUT_PULLUP);

  Serial.begin(9600); //initialize the serial transmition at 9600 bauds

  //=======Oled Initialize===================
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(WHITE);        // Draw white text
  //=====INA260 Initialize=====================
  if (!ina260.begin()) {
    Serial.println("Couldn't find INA260 chip");
    // while (1);
  //=====Initialize flash library=============
  if (!flash.begin()) {
    Serial.println("Error, failed to initialize flash chip!");

  // First call begin to mount the filesystem.  Check that it returns true
  // to make sure the filesystem was mounted.
  if (!fatfs.begin(&flash)) {
    Serial.println("Error, failed to mount newly formatted filesystem!");
    Serial.println("Was the flash chip formatted with the fatfs_format example?");

void loop() {
  if (sequence == 0) { //configuring the Voltage upper limit
    display.setCursor(5, 0);
    display.print(F("Voltage upper limit"));
    display.setCursor(45, 15);
    display.print(F(" V"));

    if (up == LOW && upVolt < 33.0) {
      display.fillRect(0, 0, 128, 32, BLACK);
      upVolt += 0.01;
    else if (down == LOW && upVolt > 0.0) {
      display.fillRect(0, 0, 128, 32, BLACK);
      upVolt -= 0.01;
    else if (enter == LOW) {
      display.fillRect(0, 0, 128, 32, BLACK);
      sequence = 1;
  else if (sequence == 1) { //configuring the Voltage lower limit
    display.setCursor(5, 0);
    display.print(F("Voltage lower limit"));
    display.setCursor(45, 15);
    display.print(F(" V"));

    if (up == LOW && loVolt < upVolt - 1.0) {
      display.fillRect(0, 0, 128, 32, BLACK);
      loVolt += 0.01;
    else if (down == LOW && loVolt > 0.0) {
      display.fillRect(0, 0, 128, 32, BLACK);
      loVolt -= 0.01;
    else if (enter == LOW) {
      display.fillRect(0, 0, 128, 32, BLACK);
      sequence = 2;
      timeTilt = millis();
  else if (sequence == 2) { //reading the voltage sensor each 100ms
    if (millis() - timer > 100) {
      voltage = ina260.readBusVoltage() * 1000.0;
      Serial.print("Voltage="); Serial.println(voltage);

      if (voltage < loVolt || voltage > upVolt) { //if the measure voltage is out of range
        current = ina260.readCurrent() * 1000.0; //reading the current
      timeSave += 100;
      timer = millis();


void readButtons() {
  enter = digitalRead(enterPin);
  up = digitalRead(upPin);
  down = digitalRead(downPin);

void readTilt() {
  Xtilt = digitalRead(XtiltPin);
  Ytilt = digitalRead(YtiltPin);

  if (Xtilt == CHANGE || Ytilt == CHANGE) {
    Serial.println("Tilt activated");
    timeTilt = millis();

  if (millis() - timeTilt > 300000 ) { //5min * 60 sec = 300 sec = 300000 ms --> go to sleep
    Serial.println("Go to sleep...zzzz");
    // Attach a wakeup interrupt on pin XtiltPin and YtiltPin, calling repetitionsIncrease when the device is woken up
    LowPower.attachInterruptWakeup(XtiltPin, wakeUpBoard, CHANGE);
    LowPower.attachInterruptWakeup(YtiltPin, wakeUpBoard, CHANGE);
    // Triggers an infinite sleep (the device will be woken up only by the registered wakeup sources)
    // The power consumption of the chip will drop consistently

void wakeUpBoard() {
  Serial.println("Wake up!");
  sequence = 2;


void saveFlash() {
  // Open the datalogging file for writing.  The FILE_WRITE mode will open
  // the file for appending, i.e. it will add new data to the end of the file.
  File dataFile = fatfs.open(FILE_NAME, FILE_WRITE);
  // Check that the file opened successfully and write a line to it.
  if (dataFile) {
    // Write a line to the file.  You can use all the same print functions
    // as if you're writing to the serial monitor.  For example to write
    // two CSV (commas separated) values:
    dataFile.print(voltage, DEC);
    dataFile.print(current, DEC);
    dataFile.print(timeSave, DEC);
    // Finally close the file when done writing.  This is smart to do to make
    // sure all the data is written to the file.
    Serial.println("Wrote new measurement to data file!");
  else {
    Serial.println("Failed to open data file for writing!");