Any example of using IMU with XiaoBle using Wake-Up Interrupt

Here you go…

3 drops/Falls and a SLEEP…

Double-Tap (on the can) to Wake up! :stuck_out_tongue:

Enjoy

HTH
GL :slight_smile: PJ :v:

Code for video…

/*****************************************************************************/
// Code for 3 Falls and a SLEEP! video
// IMU Interrupt Example for XIAO BLE Sense
// This example shows how to configure LMSD6S3TR-C on XIAO BLE SENSE to interrupt
// on INT1 after a Free Fall event after 3 Free Falls it sleeps and "Double Tap" INT2 wakes it up again.
// tested with 2.9.0 - 2.9.3 
//poatched and toasted by pjg
/*******************************************************************************/

#include "LSM6DS3.h"
#include "Wire.h"
#include <U8x8lib.h>
LSM6DS3 myIMU(I2C_MODE, 0x6A); // IMU 
//#define int2Pin PIN_LSM6DS3TR_C_INT1
#define int2Pin P0_11 // <--- GPIO pin number 
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* clock=*/ PIN_WIRE_SCL, /* data=*/ PIN_WIRE_SDA, /* reset=*/ U8X8_PIN_NONE);
 // OLEDs without Reset of the Display

const int buttonPin = 1;     // the number of the pushbutton pin
int buttonState = 0;         // variable for reading the pushbutton status
int BuzzerPin = A3;
uint8_t interruptCount = 0; // Amount of received interrupts
uint8_t prevInterruptCount = 0; // Interrupt Counter from last loop
uint16_t detectCount = 0;

void setup() {
    Serial.begin(9600);
	  delay(1000); //relax...
	  Serial.println("Processor came out of reset.\n");
    u8x8.begin();
    u8x8.setFlipMode(1);   // set number from 1 to 3, the screen word will rotary 180
    
    pinMode(LED_BUILTIN, OUTPUT);// initialize the LED pin as an output:
    pinMode(buttonPin, INPUT_PULLUP);// initialize the pushbutton pin as an input:
    pinMode(BuzzerPin, OUTPUT);
    pinMode(LEDR, OUTPUT);
    pinMode(LEDG, OUTPUT);
    pinMode(LEDB, OUTPUT);
    setLedRGB(false, false, true); // set blue led

    myIMU.settings.gyroEnabled = 0; // Gyro currently not used, disabled to save power 
    if (myIMU.begin() != 0) {
        Serial.println("IMU error");
    } else {
        Serial.println("IMU OK!");
    }
    Serial.println("\nLSM6D3 'FREE FALL DEMO' compiled on "__DATE__ " at " __TIME__);
    //setupDoubleTapInterrupt();
    setupFreeFallInterrupt();
    pinMode(int2Pin, INPUT);
    attachInterrupt(digitalPinToInterrupt(int2Pin), int1ISR, RISING);
    u8x8.setFont(u8x8_font_8x13B_1x2_r);
    u8x8.clearDisplay();
    u8x8.setCursor(0, 0);
    u8x8.print("Free Fall Demo");
   Serial.print("\Iterrupt Counter: ");
   Serial.println(interruptCount);
}

void loop() {
    setLedRGB(false, false, true); // reset led to blue only
    u8x8.setCursor(0, 3);
    u8x8.print(interruptCount);
    //Serial.print("\Iterrupt Counter: ");
    //Serial.println(interruptCount);
uint8_t readDataByte = 0;
    //Read the wake-up source register
    myIMU.readRegister(&readDataByte, LSM6DS3_ACC_GYRO_WAKE_UP_SRC);
    //Mask off the FF_IA bit for free-fall detection
    readDataByte &= 0x20;
    if (readDataByte) {
        detectCount ++;
        Serial.print("Free fall detected!  ");
        Serial.println(detectCount);
    }
    delay(10);
    // if interrupt was received in this cycle
    if (interruptCount > prevInterruptCount) {
      Serial.println("\Interrupt received!");
      setLedRGB(false, true, false); // set green only
    }
    
    prevInterruptCount = interruptCount;
    
    if (interruptCount >= 3) {
      // Trigger System OFF after 5 interrupts
      goToPowerOff();
    }
    
    delay(500);
}


// -------------------- System ------------------------- //

void goToPowerOff() {
  setLedRGB(false, false, false);
  Serial.println("Going to System OFF");
  u8x8.clearDisplay();
  u8x8.setCursor(0, 3);
  u8x8.print("SLEEP");
  setupDoubleTapInterrupt(); // not needed here, if already applied..
  delay(1000); // delay seems important to apply settings, before going to System OFF
  //Ensure interrupt pin from IMU is set to wake up device
  nrf_gpio_cfg_sense_input(digitalPinToInterrupt(int2Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
  delay(2000); // Required delay
  // Trigger System OFF
  NRF_POWER->SYSTEMOFF = 1;
}

// -------------------- Interrupts ------------------------- //

void setupFreeFallInterrupt() {
  uint8_t errorAccumulator = 0;
  uint8_t dataToWrite = 0;  //Temporary variable

  //Setup the accelerometer******************************
  dataToWrite = 0; //Start Fresh!
  dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_200Hz;
  dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_2g;
  dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_416Hz;

   // //Now, write the patched together data
   errorAccumulator += myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x60 );
   //errorAccumulator += myIMU.readRegister(&dataToWrite, LSM6DS3_ACC_GYRO_CTRL4_C);
   //errorAccumulator += myIMU.writeRegister( LSM6DS3_ACC_GYRO_CTRL4_C, 0x10 );
   // Write 00h into WAKE_UP_DUR 
	 errorAccumulator += myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_DUR, 0x00 );
    // Set FF threshold (FF_THS[2:0] = 011b)
    // Set six samples event duration (FF_DUR[5:0] = 000110b)
    // Write 33h into FREE_FALL 
   errorAccumulator += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x33);
    // FF interrupt driven to INT1 pin
    // Write 10h into MD1_CFG
	 errorAccumulator += myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x10 );
    // Also route to INT2 pin
    // Write 10h into MD1_CFG
	 errorAccumulator += myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD2_CFG, 0x10 );
	  // Latch interrupt
    // Write 01h into TAP_CFG 
   errorAccumulator += myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x81);
	
	if( errorAccumulator )
  {
	  Serial.println("Problem configuring the device.");
  }
  else
  {
	  Serial.println("Device O.K.");
  }	
}


void setupDoubleTapInterrupt() {
  uint8_t error = 0;
  uint8_t dataToWrite = 0;

  // Double Tap Config
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x60); //* Acc = 416Hz (High-Performance mode)// Turn on the accelerometer
  // ODR_XL = 416 Hz, FS_XL = 2g
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x8E);// INTERRUPTS_ENABLE, SLOPE_FDS// Enable interrupts and tap detection on X, Y, Z-axis
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_THS_6D, 0x85);// Set tap threshold 8C
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_INT_DUR2, 0x7F);// Set Duration, Quiet and Shock time windows 7F
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_THS, 0x80);// Single & double-tap enabled (SINGLE_DOUBLE_TAP = 1)
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x08);// Double-tap interrupt driven to INT1 pin
}

void int1ISR()
{
  interruptCount++;
 ;
  
}

// -------------------- Utilities ------------------------- //

void setLedRGB(bool red, bool green, bool blue) {
  if (!blue) { digitalWrite(LEDB, HIGH); } else { digitalWrite(LEDB, LOW); }
  if (!green) { digitalWrite(LEDG, HIGH); } else { digitalWrite(LEDG, LOW); }
  if (!red) { digitalWrite(LEDR, HIGH); } else { digitalWrite(LEDR, LOW); }
}

Serial output…one cycle

IMU OK!

LSM6D3 'FREE FALL DEMO' compiled on Mar  2 2025 at 16:14:27
Device O.K.
Iterrupt Counter: 0
Free fall detected!  1
Interrupt received!
Free fall detected!  2
Interrupt received!
Free fall detected!  3
Interrupt received!
Going to System OFF
Processor came out of reset.

IMU OK!

LSM6D3 'FREE FALL DEMO' compiled on Mar  2 2025 at 16:14:27
Device O.K.
Iterrupt Counter: 0