Aruino mkr nb1500 external interrupt

Hardware: mkr nb1500 + mkr imu shield

According to the imu shield datasheet the interrupt pin is connected to pin 0 on the nb1500.

I am trying to put the nb1500 to sleep and wake it up from an external interrupt from the imu.
Once i am moving the imu, the interrupt pin should trigger, but i am not sure it actually does. Is there a way i can check this? The variable imuTrigger in my code does detect any/no motion.

I am using the ArduinoLowPower library Arduino Low Power - Arduino Reference.

#include <Adafruit_BNO055.h>
#include "ArduinoLowPower.h"

#define BNO055_ADDRESS          0x28
#define BNO055_INT_STA          0x37
#define BNO055_PWR_MODE         0x3E
#define BNO055_OPR_MODE         0x3D
#define BNO055_ACC_NM_SET       0x16
#define BNO055_PAGE_ID          0x07

Adafruit_BNO055 bno = Adafruit_BNO055();
imu::Vector<3> acc;

const int pin = 0;

void setup() {
  initializeIMU();
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(pin, INPUT_PULLUP);  
  LowPower.attachInterruptWakeup(pin, dummy, CHANGE);
}

void loop() {
  // flash LED to indicate the board is on
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);
  delay(100);
  
  // interrupt pin from imu: 64 = any motion detected, 128 = no motion detected
  uint8_t imuTrigger = readByte(BNO055_ADDRESS, BNO055_INT_STA);

  if (imuTrigger == 128) {
    LowPower.sleep();
  }
  
}


void dummy() {
  // This function will be called once on device wakeup
  // You can do some little operations here (like changing variables which will be used in the loop)
  // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context
  
}

/* ---------------------------------------------------------------------------------------------------------------------------*/
void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
  Wire.beginTransmission(address);  // Initialize the Tx buffer
  Wire.write(subAddress);           // Put slave register address in Tx buffer
  Wire.write(data);                 // Put data in Tx buffer
  Wire.endTransmission();           // Send the Tx buffer
}

uint8_t readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data; // `data` will store the register data
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (size_t) 1);   // Read one byte from slave register address
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}

void initializeIMU()
{
  bno.begin();
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_OPR_MODE, 0x00); // Put IMU in operation mode; 0x00 = config, 0x08 is IMU fusion mode
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PWR_MODE, 0x01); // Put IMU in low power mode
  Serial.println("IMU low power mode selected");
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PAGE_ID, 0x01);    // SELECT PAGE 1 TO CONFIGRE SETTINGS of page 1
  delay(20);
  //  writeByte(BNO055_ADDRESS, BNO055_ACC_NM_SET, 0x7E); // 336s (~5.5 min), max duration
  writeByte(BNO055_ADDRESS, BNO055_ACC_NM_SET, 0x09); // 5s usefull for testing
  Serial.println("no motion to low power duration: 5s");
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PAGE_ID, 0x00);    // SELECT PAGE 0 TO CONFIGRE SETTINGS of page 0
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_OPR_MODE, 0x08); // Operation mode: IMU fusion mode
  Serial.println("IMU fusion mode selected");
  delay(100);
}

My code does not work. It goes to sleep, but never wakes up when moving the imu. Anyone notice what i am doing wrong?

for example connect oscilloscope probe to pin 0 and GND

Unfortunately i don't have acces to such fancy equipment :frowning:
Is it possible to do this by code?

I'm not sure if the code will help here.
Since your controller is sleeping and not waking up - what code will monitor this pin?

What if i won't put the controller to sleep, that way it should be possible to measure the interrupt pin right? Because, the interrupt pin should be triggered once the imu is not moving for 5 s. See code below:

#include <Adafruit_BNO055.h>
#include "ArduinoLowPower.h"

#define BNO055_ADDRESS          0x28
#define BNO055_INT_STA          0x37
#define BNO055_PWR_MODE         0x3E
#define BNO055_OPR_MODE         0x3D
#define BNO055_ACC_NM_SET       0x16
#define BNO055_PAGE_ID          0x07

Adafruit_BNO055 bno = Adafruit_BNO055();
imu::Vector<3> acc;

const int pin = 0;

void setup() {
  Serial.begin(9600);
  while(!Serial);
  
  initializeIMU();
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(pin, INPUT_PULLUP);  
}

void loop() {
  // interrupt pin from imu: 64 = any motion detected, 128 = no motion detected
  uint8_t imuTrigger = readByte(BNO055_ADDRESS, BNO055_INT_STA);
  Serial.print("imu trigger: "); Serial.println(imuTrigger);
  Serial.print("interrupt pin: ");Serial.println(pin);
  delay(100);
}


/* ---------------------------------------------------------------------------------------------------------------------------*/
void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
  Wire.beginTransmission(address);  // Initialize the Tx buffer
  Wire.write(subAddress);           // Put slave register address in Tx buffer
  Wire.write(data);                 // Put data in Tx buffer
  Wire.endTransmission();           // Send the Tx buffer
}

uint8_t readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data; // `data` will store the register data
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (size_t) 1);   // Read one byte from slave register address
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}

void initializeIMU()
{
  bno.begin();
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_OPR_MODE, 0x00); // Put IMU in operation mode; 0x00 = config, 0x08 is IMU fusion mode
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PWR_MODE, 0x01); // Put IMU in low power mode
  Serial.println("IMU low power mode selected");
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PAGE_ID, 0x01);    // SELECT PAGE 1 TO CONFIGRE SETTINGS of page 1
  delay(20);
  //  writeByte(BNO055_ADDRESS, BNO055_ACC_NM_SET, 0x7E); // 336s (~5.5 min), max duration
  writeByte(BNO055_ADDRESS, BNO055_ACC_NM_SET, 0x09); // 5s usefull for testing
  Serial.println("no motion to low power duration: 5s");
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PAGE_ID, 0x00);    // SELECT PAGE 0 TO CONFIGRE SETTINGS of page 0
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_OPR_MODE, 0x08); // Operation mode: IMU fusion mode
  Serial.println("IMU fusion mode selected");
  delay(100);
}

Not sure if this is the correct way to measure the interrupt pin, but i dont detect any change of that value, it stays 0. While the variable imu trigger does detect the no motion.

image

I would write a simple sketch to attach and ISR to Pin 0 and set a flag when it triggers. In loop(), report the condition of the flag every second or two. If it ever turns on, the interrupt worked.

Thanks for the tip! Here is the simple sketch for anyone interested. Seems like my IMU does not fire a interrupt. Back to the imu datasheet to figure out the problem :smiley:

#include <Adafruit_BNO055.h>
#include "ArduinoLowPower.h"

#define BNO055_ADDRESS          0x28
#define BNO055_INT_STA          0x37
#define BNO055_PWR_MODE         0x3E
#define BNO055_OPR_MODE         0x3D
#define BNO055_ACC_NM_SET       0x16
#define BNO055_PAGE_ID          0x07

Adafruit_BNO055 bno = Adafruit_BNO055();
imu::Vector<3> acc;

const int pin = 0;
volatile byte state = HIGH;
const byte ledPin = LED_BUILTIN;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  initializeIMU();
  pinMode(ledPin, OUTPUT);
  pinMode(pin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(pin), ISR, CHANGE);
}

void loop() {
  // interrupt pin from imu: 64 = any motion detected, 128 = no motion detected
  digitalWrite(ledPin, state);
  delay(100);
}

void ISR() {
  state = !state;
  Serial.println("INTERRUPT DETECTED!");
}
/* ---------------------------------------------------------------------------------------------------------------------------*/
void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
  Wire.beginTransmission(address);  // Initialize the Tx buffer
  Wire.write(subAddress);           // Put slave register address in Tx buffer
  Wire.write(data);                 // Put data in Tx buffer
  Wire.endTransmission();           // Send the Tx buffer
}

uint8_t readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data; // `data` will store the register data
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (size_t) 1);   // Read one byte from slave register address
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}

void initializeIMU()
{
  bno.begin();
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_OPR_MODE, 0x00); // Put IMU in operation mode; 0x00 = config, 0x08 is IMU fusion mode
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PWR_MODE, 0x01); // Put IMU in low power mode
  Serial.println("IMU low power mode selected");
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PAGE_ID, 0x01);    // SELECT PAGE 1 TO CONFIGRE SETTINGS of page 1
  delay(20);
  //  writeByte(BNO055_ADDRESS, BNO055_ACC_NM_SET, 0x7E); // 336s (~5.5 min), max duration
  writeByte(BNO055_ADDRESS, BNO055_ACC_NM_SET, 0x09); // 5s usefull for testing
  Serial.println("no motion to low power duration: 5s");
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_PAGE_ID, 0x00);    // SELECT PAGE 0 TO CONFIGRE SETTINGS of page 0
  delay(20);
  writeByte(BNO055_ADDRESS, BNO055_OPR_MODE, 0x08); // Operation mode: IMU fusion mode
  Serial.println("IMU fusion mode selected");
  delay(100);
}