wollewald / MPU9250_WE

An Arduino library for the 9-axis accelerometer, gyroscope and magnetometer MPU9250 and MPU6500. It contains many example sketches make it easy to use.
https://wolles-elektronikkiste.de/en/mpu9250-9-axis-sensor-module-part-1
MIT License
61 stars 26 forks source link

wake-on-motion interrupt not working as intended #19

Closed purohitprachi72 closed 6 months ago

purohitprachi72 commented 6 months ago

Hello, I tried running the wom interrupt example code but i'm not getting the expected output. The loop is printing the readings correctly but whenever there is a motion the "Interrupt type: motion" is not detected for some reason. The if loop is not being executed, i think.

if(motion){
    byte source = myMPU9250.readAndClearInterrupts();
    Serial.println("Interrupt!");
    if(myMPU9250.checkInterrupt(source, MPU9250_WOM_INT)){
      Serial.println("Interrupt Type: Motion");
      delay(1000);
    }
    motion = false;
    // if additional interrupts have occured in the meantime:
    myMPU9250.readAndClearInterrupts(); 
  }

Also, I'm trying the low-pwr accel mode which will start taking readings when an interrupt is generated...board used is xiao nrf52840 by seeed studio

#include <MPU9250_WE.h>
#include <Wire.h>

#define MPU9250_ADDR 0x68

const int intPin = 2;
volatile bool motion = false;

MPU9250_WE myMPU9250 = MPU9250_WE(MPU9250_ADDR);

void setup() {
  Serial.begin(115200);

  while(!Serial) delay(10);
  Wire.begin();

  if (!myMPU9250.init()) {
    Serial.println("MPU9250 does not respond");
  } else {
    Serial.println("MPU9250 is connected");
  }

  Serial.println("Position your MPU9250 flat and don't move it - calibrating...");
  delay(1000);
  myMPU9250.autoOffsets();
  Serial.println("Done!");

  myMPU9250.setSampleRateDivider(5);

  // Configure accelerometer range
  myMPU9250.setAccRange(MPU9250_ACC_RANGE_2G);

  myMPU9250.enableAccDLPF(true);
  // *   DLPF     Bandwidth [Hz]      Delay [ms]    Output rate [kHz]
  // *     6             5              66.96           1
  myMPU9250.setAccDLPF(MPU9250_DLPF_6);

  // Set low power accelerometer data rate
  myMPU9250.setLowPowerAccDataRate(MPU9250_LP_ACC_ODR_0_98);

  // Enable motion detection interrupt
  myMPU9250.setIntPinPolarity(MPU9250_ACT_HIGH); // Set interrupt pin to active high

  myMPU9250.enableIntLatch(true);   

  myMPU9250.enableClearIntByAnyRead(false); 

  // Enable Wake-on-Motion (WoM) interrupt
  myMPU9250.enableInterrupt(MPU9250_WOM_INT);

  myMPU9250.setWakeOnMotionThreshold(128); // Set motion detection threshold

  /*  Enable/disable wake on motion (WOM) and  WOM mode:
   *  MPU9250_WOM_DISABLE
   *  MPU9250_WOM_ENABLE
   *  ***
   *  MPU9250_WOM_COMP_DISABLE   // reference is the starting value
   *  MPU9250_WOM_COMP_ENABLE    // reference is the last value
   */
  myMPU9250.enableWakeOnMotion(MPU9250_WOM_ENABLE, MPU9250_WOM_COMP_DISABLE);

  // Put MPU9250 to sleep
  // myMPU9250.sleep(true);
  // Serial.println("MPU9250 is in sleep mode. Waiting for motion to wake it up...");

  attachInterrupt(digitalPinToInterrupt(intPin), motionISR, RISING);
  Serial.println("Turn your MPU9250 and see what happens...");
}

void loop() {
  xyzFloat gValue, accRaw;

  if(motion){
    motion = false;
    // myMPU9250.sleep(false);

    // Read accelerometer data
    xyzFloat accRaw = myMPU9250.getAccRawValues();
    xyzFloat gValue = myMPU9250.getGValues();
    float resultantG = myMPU9250.getResultantG(gValue);

    // Print the accelerometer data
    Serial.println("Motion detected!");
    Serial.print("Raw acceleration values (x,y,z): ");
    Serial.print(accRaw.x);
    Serial.print(", ");
    Serial.print(accRaw.y);
    Serial.print(", ");
    Serial.println(accRaw.z);

    Serial.print("g values (x,y,z): ");
    Serial.print(gValue.x);
    Serial.print(", ");
    Serial.print(gValue.y);
    Serial.print(", ");
    Serial.println(gValue.z);

    Serial.print("Resultant g: ");
    Serial.println(resultantG);

    // delay(1000);

    // Clear any additional interrupts that may have occurred
    myMPU9250.readAndClearInterrupts();
    // myMPU9250.sleep(true);
  }
delay(10);
}

void motionISR() {
  motion = true;
  // myMPU9250.sleep(false);
}

o/p: MPU9250 does not respond Position your MPU9250 flat and don't move it - calibrating... Done! Turn your MPU9250 and see what happens...

wollewald commented 6 months ago

Just for my interest: could you solve the issue?

purohitprachi72 commented 6 months ago

Hello! The problem was with the MPU9250 module itself, which was not working correctly. Once I replaced it with a new one, the wake-on-motion interrupt started working fine.

Regarding the "MPU9250 does not respond" message, it still appears initially, but the readings are correctly obtained afterward. I'm not entirely sure why this happens, but it doesn't seem to affect the functionality once the initial message is bypassed.

Thanks for following up!

wollewald commented 6 months ago

Hi, if you get "MPU9250 does not respond" although you get measured values it is an indication that you have an MPU6500 instead of a MPU9250. The init procedure checks whether the value of the "Who am I" register matches the value for an MPU9250. If you have an MPU6500 the missing magnetometer is the only difference. You can check what you have with the "Who am I" sketch. All the best for your project!

purohitprachi72 commented 6 months ago

Hi, the sensor has the labeling of MPU9250/6500, so that must be the case. However, I'm still able to get magnetometer readings with this sensor. Thank you so much for the wishes. Kind regards!