Hello there,
I am trying to detect a fall with my XIAO nRF52840. It has an onboard IMU (LSM6DS3).
I used this sample code from another forum here which worked fine for double tap detection. However I need a free-fall detection.
So I went through the whole LSM6DS3 documentation and came up with this code here:
#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.accelEnabled = 1;
myIMU.settings.tempEnabled = 1;
myIMU.settings.gyroEnabled = 1; // 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; // 0000 0001 200Hz
dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_2g; // 0000 0000 2g
dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_416Hz;// 0110 0000 516
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); }
}
however now that I (assumed I) configured for free fall I don't get any interrupts anymore.
I guess something is missing / wrong in the setupFreeFallInterrupt()
function but what?
Does anyone have an idea? I admit, I'm not very experienced in these registers. Maybe I missed something?
Thanks for any help!