XIAO nRF52840 free-fall detection not working

Hello there,

I was trying the free-fall detect sample from the library but I don’t get anything. I see the start logs in the serial monitor but after that it gets quiet.
I was wondering if everything is correct there. In the loop the wakeup register is checked but always 0.

uint8_t readDataByte = 0;
lsm6ds3.readRegister(&readDataByte, LSM6DS3_ACC_GYRO_WAKE_UP_SRC);
readDataByte &= 0x20;

Could it be there was no wake-up? Did it even go to sleep in the first place? I can’t find anything like this in the sample code.

I was expecting a call for

attachInterrupt

somewhere. Any ideas?

This is the complete sample code from the library:

#include "LSM6DS3.h"
#include "Wire.h"

#define CLEAR_STEP      true
#define NOT_CLEAR_STEP  false

//Create a instance of class LSM6DS3
LSM6DS3 lsm6ds3(I2C_MODE, 0x6A);    //I2C device address 0x6A
uint16_t detectCount = 0;

void setup() {
    Serial.begin(9600);
    while (!Serial);
    if (lsm6ds3.begin() != 0) {
        Serial.println("Device error");
    } else {
        Serial.println("Device OK!");
    }

    if (0 != config_free_fall_detect()) {
        Serial.println("Fail to configure!");
    } else {
        Serial.println("Success to Configure!");
    }
}

void loop() {
    uint8_t readDataByte = 0;
    //Read the wake-up source register
    lsm6ds3.readRegister(&readDataByte, LSM6DS3_ACC_GYRO_WAKE_UP_SRC);
  
    //Mask off the FF_IA bit for free-fall detection
    readDataByte &= 0x20;

    Serial.print("ReadDataByte:");
    Serial.println(readDataByte);
    
    if (readDataByte) {
        detectCount ++;
        Serial.print("Free fall detected!  ");
        Serial.println(detectCount);
    }
    delay(10);
}

int config_free_fall_detect(void) {
    uint8_t error = 0;
    uint8_t dataToWrite = 0;

    dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_200Hz;
    dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_2g;
    dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_416Hz;

    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, dataToWrite);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_DUR, 0x00);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x33);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x10);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_MD2_CFG, 0x10);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x01);

    return error;
}

I made some progress with the code for double tap interrupts that was posted here

However, when adapting the configuration to free fall I still don’t receive anything. My current configuration code looks like this:

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

  dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_200Hz;
  dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_2g;
  dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_416Hz;

  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, dataToWrite);

  // p.61
  // enable linear acceleration sensor
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL9_XL, 0x38);

  // Wakeup source (p.62)
  // 00100000 x20
  // 00101111 x2f
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_SRC, 0x2f);

  // TAP_CFG (58h) Register (page 77)
  // Latch interrupt - Write 01h into TAP_CFG 
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x01); // LATCHED
  
  //MD1_CFG (5Eh) Functions routing on INT1 register (page 80)
  // Free fall
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x10);   // 00010000

  //p.79 -> default values
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_DUR, 0x00); 

  // p.80 -> 
  // 00110 :
  // 011 : 312mg threshold
  //error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x33); // 00110 011
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x30); // 00110 000   156mg
  //error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x00); // 00000 000 156mg
  //error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x07); // 00000 111 500mg
  
  if (error) {
	  Serial.println("Problem configuring the device.");
  } else {
	  Serial.println("Device O.K.");
  }	
}

with everything as it was before (working with the double tap).

So the whole project looks like that:

/*****************************************************************************/
// 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 "Double Tap" was recognized.
// Additionally, the device goes into System OFF state, after 5 interrupts were
// received. Another "Double Tap" will wake up the device again.
// 
// by chuck
/*******************************************************************************/

#include "LSM6DS3.h"
#include "Wire.h"

LSM6DS3 myIMU(I2C_MODE, 0x6A);
#define int1Pin PIN_LSM6DS3TR_C_INT1

uint8_t interruptCount = 0; // Amount of received interrupts
uint8_t prevInterruptCount = 0; // Interrupt Counter from last loop

void setup() {
    Serial.begin(9600);
    
    while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
    }

    Serial.println("--- START ---");


    pinMode(LED_RED, OUTPUT);
    pinMode(LED_GREEN, OUTPUT);
    pinMode(LED_BLUE, 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!");
    }
    
    setupFreeFallInterrupt();
    
    pinMode(int1Pin, INPUT);
    attachInterrupt(digitalPinToInterrupt(int1Pin), int1ISR, RISING);
}

void loop() {
    setLedRGB(false, false, true); // reset led to blue only

    Serial.print("\Iterrupt Counter: ");
    Serial.println(interruptCount);

    // 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 >= 5) {
      // Trigger System OFF after 5 interrupts
      goToPowerOff();
    }
    
    delay(500);
}


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

void goToPowerOff() {
  setLedRGB(false, false, false);
  Serial.println("Going to System OFF");
  setupFreeFallInterrupt(); // not needed here, if already applied..
  delay(100); // 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(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
  // Trigger System OFF
  NRF_POWER->SYSTEMOFF = 1;
}

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

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

  dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_200Hz;
  dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_2g;
  dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_416Hz;

  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, dataToWrite);

  // p.61
  // enable linear acceleration sensor
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL9_XL, 0x38);

  // Wakeup source (p.62)
  // 00100000 x20
  // 00101111 x2f
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_SRC, 0x2f);

  // TAP_CFG (58h) Register (page 77)
  // Latch interrupt - Write 01h into TAP_CFG 
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x01); // LATCHED
  
  //MD1_CFG (5Eh) Functions routing on INT1 register (page 80)
  // Free fall
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x10);   // 00010000

  //p.79 -> default values
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_DUR, 0x00); 

  // p.80 -> 
  // 00110 :
  // 011 : 312mg threshold
  //error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x33); // 00110 011
  error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x30); // 00110 000   156mg
  //error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x00); // 00000 000 156mg
  //error += myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x07); // 00000 111 500mg
  
  if (error) {
	  Serial.println("Problem configuring the device.");
  } else {
	  Serial.println("Device O.K.");
  }	
}

void int1ISR()
{
  interruptCount++;
}

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

void setLedRGB(bool red, bool green, bool blue) {
  if (!blue) { digitalWrite(LED_BLUE, HIGH); } else { digitalWrite(LED_BLUE, LOW); }
  if (!green) { digitalWrite(LED_GREEN, HIGH); } else { digitalWrite(LED_GREEN, LOW); }
  if (!red) { digitalWrite(LED_RED, HIGH); } else { digitalWrite(LED_RED, LOW); }
}

Any idea what I’m doing wrong? No interrupts occurring.

I had to go back to 2.9.0 To get it to work as b4.
HTH
GL :slight_smile:

//poatched and toasted by pjg
/*******************************************************************************/

#include "LSM6DS3.h"
#include "Wire.h"
#include <U8x8lib.h>
LSM6DS3 myIMU(I2C_MODE, 0x6A); // IMU 
#define int1Pin PIN_LSM6DS3TR_C_INT1

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


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 'High Level Example' compiled on "__DATE__ " at " __TIME__);
    setupDoubleTapInterrupt();
    
    pinMode(int1Pin, INPUT);
    attachInterrupt(digitalPinToInterrupt(int1Pin), int1ISR, RISING);
    u8x8.setFont(u8x8_font_8x13B_1x2_r);
    u8x8.clearDisplay();
    u8x8.setCursor(0, 0);
    u8x8.print("Tap Demo");
  
}

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

    // 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(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
  delay(2000); // Required delay
  // Trigger System OFF
  NRF_POWER->SYSTEMOFF = 1;
}

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

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

Output:

Processor came out of reset.

IMU OK!

LSM6D3 'High Level Example' compiled on Aug 29 2023 at 13:54:10
Iterrupt Counter: 0
Iterrupt Counter: 0
Iterrupt Counter: 0
Iterrupt Counter: 0
Iterrupt Counter: 0
Iterrupt Counter: 0
Iterrupt Counter: 1
Interrupt received!
Iterrupt Counter: 1
Iterrupt Counter: 1
Iterrupt Counter: 1
Iterrupt Counter: 1
Iterrupt Counter: 1
Iterrupt Counter: 1
Iterrupt Counter: 1
Iterrupt Counter: 1
Iterrupt Counter: 1
Iterrupt Counter: 2
Interrupt received!
Iterrupt Counter: 2
Iterrupt Counter: 2
Iterrupt Counter: 2
Iterrupt Counter: 2
Iterrupt Counter: 2
Iterrupt Counter: 2
Iterrupt Counter: 2
Iterrupt Counter: 2
Iterrupt Counter: 3
Interrupt received!
Going to System OFF

with any other board files it act unpredictable. IMO.
this configuration works for my application
HTH
GL :slight_smile:

1 Like

Thank you for your help.
But still, this is the sample for double tap gestures.
What I want is the same for free fall but this doesn’t seem to work.

Ah’ OK I see that now. So are you getting interrupts ?
are you able to reproduce the video "impact detection with the polling of the Threshold and Time?
LMK,
GL :slight_smile:

You want ;

Pseudo-code

To summarize, here is the pseudo-code required to initialize free-fall detection

  • Set event duration (FF_DUR5 bit) - Write 00h into WAKE_UP_DUR
  • Set FF threshold (FF_THS[2:0] = 011b) and set six samples event duration (FF_DUR[5:0] = 000110b) - Write 33h into FREE_FALL
  • Drive free-fall interrupt to INT1 pin - Write 10h into MD1_CFG
  • Latch interrupt - Write 01h into TAP_CFG

To check if a free-fall event has occurred, read register WAKE_UP_SRC and check if bit 5 (FF_IA) is set

from this link https://community.element14.com/challenges-projects/design-challenges/design-for-a-cause-2021/b/blog/posts/ace—blog-8—offloading-computation-to-lsm6ds3

main points are the Freefall has Interrupt has to be latched and you still poll for the interrupt to have occurred. (or attach it to another pin or flag in your interrupt routine.)
yours looks like the sparkfun example btw
HTH
GL :slight_smile:

1 Like

Hey there, thanks for your help. As stated I copied the code from someone in this forum who wanted the double tap interrupt. And for that purpose everything works perfectly fine! Hence my thought it shouldn’t be too hard to switch to free-fall.

Regarding your suggestions, I thought I have almost all of these settings, haven’t I?
I was not sure about the FF_DUR to be honest. The documentation states

Free-fall duration event. Default: 0

But what values can I enter there? I mean is this something like “millis” or “check cycles” or “processor ticks”? But then again, these are some flags only. So I’m confused.

However I have this in my code already:

myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_DUR, 0x00); 
myIMU.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x33);
myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x10);
myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x01);

Isn’t this basically what you suggested?
What am I missing?

Hi there,
Well It looks like it’s not complete, and the thing about the Interrupt and a Pin needing attached . When I get some free time I’ll look closer but you are close but I think your not getting the interrupt from the FF the duration is 153ms min. afaik
The address and the register bit as well as the Rising or Falling edge of the Interrupt all need to be compatible logic.
HTH
GL :slight_smile:

1 Like

Hello there,
thanks for all the feedback. I tried to fix things but had no success.
The blog post that explains a little more was nice and gave some insights but I still can’t make it work.
I bought another nRF52840 but have the same issue - so the chip is not broken or so.

I even tried to fix the sample code from the library but it’s not working either.

#include "LSM6DS3.h"
#include "Wire.h"

#define CLEAR_STEP      true
#define NOT_CLEAR_STEP  false

//Create a instance of class LSM6DS3
LSM6DS3 lsm6ds3(I2C_MODE, 0x6A);    //I2C device address 0x6A
uint16_t detectCount = 0;

void setup() {
    Serial.begin(9600);
    while (!Serial);
    if (lsm6ds3.begin() != 0) {
        Serial.println("Device error");
    } else {
        Serial.println("Device OK!");
    }

    if (0 != config_free_fall_detect()) {
        Serial.println("Fail to configure!");
    } else {
        Serial.println("Success to Configure!");
    }
}

void loop() {
    uint8_t readDataByte = 0;
    //Read the wake-up source register
    lsm6ds3.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);
}

int config_free_fall_detect(void) {
    uint8_t error = 0;
    uint8_t dataToWrite = 0;

    dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_200Hz;
    dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_2g;
    dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_416Hz;

    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, dataToWrite);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_DUR, 0x00);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_FREE_FALL, 0x33);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x10);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_MD2_CFG, 0x10);
    error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x01);

    return error;
}

Any other ideas?

So Hi there,
I see you have been asking over on Arduino. That volatile discussion is important but NOT pertinent to this Code. BTW. You missed ONE major detail.
Here is the output and a small clip of it in action.

Device OK!
Success to Configure!
Free fall detected!  1
Free fall detected!  2
Free fall detected!  3
Free fall detected!  4
Free fall detected!  5
Free fall detected!  6
Free fall detected!  7
Free fall detected!  8
Free fall detected!  9
Free fall detected!  10

HTH
GL :slight_smile: PJ

https://www.st.com/en/mems-and-sensors/lsm6ds3tr-c.html#
https://www.st.com/resource/en/application_note/an5130-lsm6ds3trc-alwayson-3d-accelerometer-and-3d-gyroscope-stmicroelectronics.pdf

Section Interrupt generation and Section 5.2 more specifically. About the Zone, the free fall zone consist of the time duration and threshold, you asked what do you write there, well based on the scales you choose you can adjust the levels and duration of ““Zero G”” closest to Zero on all axis = Free Fall
You didn’t notice in my Double tap code I , enable the interrupt for the 2 Tap writing an 0x81
Section 5.2 in the fine print :smiley:

 The basic interrupts (6D/4D, free-fall, wake-up, tap, inactivity) have to be enabled by setting the
INTERRUPTS_ENABLE bit in the TAP_CFG register.

Changing your 0x01 to 0x81 and Wha-la… Interrupt generation.

:stuck_out_tongue_winking_eye: :point_up_2:
error += lsm6ds3.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x81);

1. Write 60h to CTRL1_XL // Turn on the accelerometer
// ODR_XL = 416 Hz, FS_XL = ±2 g
2. Write 81h to TAP_CFG // Enable interrupts and latch interrupt
3. Write 00h to WAKE_UP_DUR // Set event duration (FF_DUR5 bit)
4. Write 33h to FREE_FALL // Set FF threshold (FF_THS[2:0] = 011b)
// Set six samples event duration (FF_DUR[5:0] = 000110b)
5. Write 10h to MD1_CFG // FF interrupt driven to INT1 pin
The sample code exploits a threshold set to 312 mg for free-fall recognition and the event is notified by hardware
through the INT1 pin. The FF_DUR[5:0] field of the FREE_FALL / WAKE_UP_DUR registers is configured like this
to ignore events that are shorter than 6/ODR_XL = 6/412 Hz ~= 15 msec in order to avoid false detections.

1 Like

Oh that looks awesome.
So I understand I forgot to set the highest bit (the one for the timestamp)?
But why is that important for the interrupt?
I mean it looks like this fixes things but I really have no clue on how I should have known that. To be honest, the documentation was a bit too short for my taste.
The document you found looks better actually. Gonna read through it so I hope I don’t have to ask more noob questions in the future.

In any case thank you very much for your help. I will need some time to understand all this but I guess that will help a lot!

Sure, no problem . You didn’t enable the Interrupt is all. the 01 sets it to latch and the 80 enables them. add them together “81” and it works as it should. read the AppNote you’ll get it all in there. I’ll post another demo with it all together with the DEV Expansion board.
HTH
GL :slight_smile: PJ

But why is that flag “enable them”?
The documentation reads:

TIMER_EN : Timestamp count enable, output data are collected in TIMESTAMP0_REG (40h),
TIMESTAMP1_REG (41h), TIMESTAMP2_REG (42h) register. Default: 0
(0: timestamp count disabled; 1: timestamp count enabled)

So I understood it is something like “I know the exact tick when it happened”. Where did you see this enables / disables them globally? I guess I still don’t understand some things perfectly. Even though, the document you provided helped a lot. Took me some hours but I finally understand some things. Thanks a lot!

And there is still something I don’t understand.
Since you are helping me so much, perhaps you might tell me more.
In my interrupt code I receive the interrupt exactly once. So I assume I have to (re)set things again after the interrupt was fired.
Where can I get that information from? Which values have to be set again and which persist?

LOL, did you read the whole thing? tiny print too… :wink:

OK Anyway Depending on several things, How you program the PIN_MODE for the interrupt pin is one.
Then how you program the chip to act with the Interrupt pin internally.
the above uses the Latching" feature of the pin. ie. interrupt is asserted until you READ the WAKE_UP_SRC register. You can change that mode to only interrupt on a Free_Fall and release Interrupt after it’s within threshold.
this is less desirable for my application btw .
READ the app_note
Look over the Code in the New thread…here.XIAO nRF52840 Sense Free-Falls , Sleep & Double Tap Wake Up Demo

HTH
GL :slight_smile:

1 Like

Hey there,
no, I did not read EVERYTHING. There were some chapters I didn’t want to go into depth since this would lead to even more questions.
But these interrupts and free-fall/tap/movement detection chapters etc. were pretty interesting.

So do I understand you right, the interrupt is “blocked” until I read from the register?

I guess I understand now. So once I’m done with my logic, I have to call

myIMU.readRegister(&readDataByte, LSM6DS3_ACC_GYRO_WAKE_UP_SRC);

This then “resets” everything and I can receive another one.
Nice! Again I have no idea where that was written but I’m happy you pointed me to what I was missing.

Sorry for all these beginner questions. I’m still studying this. I hope in a few semesters I might get a better understanding of all this - and help others like you did.

Again, thanks a lot!

1 Like