Hello,
I am coding on a Seeed Xiao NRF52840 Sense, with the LSM6DS3 6-axis chip. I was wanting to write some code on possibly putting the chip into power off mode, but then when a significant motion is detected by the LSM6DS3, if that would be able to wake it up into the power on mode?
Currently I am using the Arduino IDE, with the appropriate libraries and I am coding on a MAC.
I have seen this ticket which wakes up from a double tap, but i was wondering if there was a way to make it wakeup from any "significant Motion found in the high level example for the LSM6DS3, the code snippets I am referencing will be located below.
Any help would be appreciated.
This is the Double tap to wakeup from an interrupt.
/*****************************************************************************/ // 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); 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!"); } setupDoubleTapInterrupt(); 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"); setupDoubleTapInterrupt(); // 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 setupDoubleTapInterrupt() { uint8_t error = 0; uint8_t dataToWrite = 0; // Double Tap Config myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x60); myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x8E);// INTERRUPTS_ENABLE, SLOPE_FDS myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_THS_6D, 0x8C); myIMU.writeRegister(LSM6DS3_ACC_GYRO_INT_DUR2, 0x7F); myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_THS, 0x80); myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x08); } 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); } }
This is the high level example with significant motion.
#include <LSM6DS3.h> #include <Wire.h> //Create a instance of class LSM6DS3 LSM6DS3 myIMU(I2C_MODE, 0x6A); //I2C device address 0x6A float aX, aY, aZ, gX, gY, gZ; const float accelerationThreshold = 2.5; // threshold of significant in G's const int numSamples = 119; int samplesRead = numSamples; void setup() { // put your setup code here, to run once: Serial.begin(9600); while (!Serial); //Call .begin() to configure the IMUs if (myIMU.begin() != 0) { Serial.println("Device error"); } else { Serial.println("aX,aY,aZ,gX,gY,gZ"); } } void loop() { // wait for significant motion while (samplesRead == numSamples) { // read the acceleration data aX = myIMU.readFloatAccelX(); aY = myIMU.readFloatAccelY(); aZ = myIMU.readFloatAccelZ(); // sum up the absolutes float aSum = fabs(aX) + fabs(aY) + fabs(aZ); // check if it's above the threshold if (aSum >= accelerationThreshold) { // reset the sample read count samplesRead = 0; break; } } // check if the all the required samples have been read since // the last time the significant motion was detected while (samplesRead < numSamples) { // check if both new acceleration and gyroscope data is // available // read the acceleration and gyroscope data samplesRead++; // print the data in CSV format Serial.print(myIMU.readFloatAccelX(), 3); Serial.print(','); Serial.print(myIMU.readFloatAccelY(), 3); Serial.print(','); Serial.print(myIMU.readFloatAccelZ(), 3); Serial.print(','); Serial.print(myIMU.readFloatGyroX(), 3); Serial.print(','); Serial.print(myIMU.readFloatGyroY(), 3); Serial.print(','); Serial.print(myIMU.readFloatGyroZ(), 3); Serial.println(); if (samplesRead == numSamples) { // add an empty line if it's the last sample Serial.println(); } } }