Meerpohl
Meerpohl

Reputation: 471

MPU 6050 gyroscope/accelerometer and shake detection

I am using a mpu 6050 chip for my project and it works good so far. I read the quaternion and send it's data via bluetooth to my pc. What I now need is shake detection. In the datasheet of the mpu 6050 it says this is supported but I can't find any further information about shake detection in the rest of the document.

I use Jeff Rowbergs arduino library for the chip with a teensy 3.0 board. https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

For some reason my chips interrupt pin is never triggered although I tried to use it. That's why I keep polling to read the data which is ok because it works.

Here's my mpu init and update function so far. If anybody knows a good way to detect shake please help on this one. I can't find a way. (maybe not using the chips built-in functionality but calculate it from the available data)

void mpuInit()
{
  Wire.begin();
  TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
  mpu.initialize();

  boolean testConnection = mpu.testConnection();

  #ifdef DEBUG
    if(testConnection) Serial.println("MPU6050 connection successful");
    else Serial.println("MPU6050 connection failed");
  #endif

  devStatus = mpu.dmpInitialize();

  mpu.setXGyroOffset(220);
  mpu.setYGyroOffset(76);
  mpu.setZGyroOffset(-85);
  mpu.setZAccelOffset(1788);

  // make sure it worked (returns 0 if so)
  if (devStatus == 0) {
    mpu.setDMPEnabled(true);
    mpuIntStatus = mpu.getIntStatus();

    // set our DMP Ready flag so the main loop() function knows it's okay to use it
    dmpReady = true;

    // get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    #ifdef DEBUG
      Serial.print("DMP Initialization failed (code ");
      Serial.print(devStatus);
      Serial.println(")");
    #endif
  }
}

void mpuUpdate()
{
  // if programming failed, don't try to do anything
  if (!dmpReady) return;

  //get INT_STATUS byte
  mpuIntStatus = mpu.getIntStatus();

  // get current FIFO count
  fifoCount = mpu.getFIFOCount();

  // wait for MPU interrupt or extra packet(s) available
  if ((fifoCount < packetSize)) return;

  if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
      // reset so we can continue cleanly
      mpu.resetFIFO();
      #ifdef DEBUG
        Serial.println("Reset FIFO.");
      #endif

  // otherwise, check for DMP data ready interrupt (this should happen frequently)
  } else if (mpuIntStatus & 0x02) {
      // wait for correct available data length, should be a VERY short wait
      while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

      // read a packet from FIFO
      mpu.getFIFOBytes(fifoBuffer, packetSize);

      // track FIFO count here in case there is > 1 packet available
      // (this lets us immediately read more without waiting for an interrupt)
      fifoCount -= packetSize;

      #ifdef OUTPUT_READABLE_QUATERNION
          // display quaternion values in easy matrix form: w x y z
          mpu.dmpGetQuaternion(&q, fifoBuffer);

          #ifdef DEBUG
            Serial.print("quat\t");
            Serial.print(q.w);
            Serial.print("\t");
            Serial.print(q.x);
            Serial.print("\t");
            Serial.print(q.y);
            Serial.print("\t");
            Serial.println(q.z);
          #endif

          uint8_t *w = (uint8_t *) &q.w;
          state[0] = w[0];
          state[1] = w[1];
          state[2] = w[2];
          state[3] = w[3];

          uint8_t *x = (uint8_t *) &q.x;
          state[4] = x[0];
          state[5] = x[1];
          state[6] = x[2];
          state[7] = x[3];

          uint8_t *y = (uint8_t *) &q.y;
          state[8] = y[0];
          state[9] = y[1];
          state[10] = y[2];
          state[11] = y[3];

          uint8_t *z = (uint8_t *) &q.z;
          state[12] = z[0];
          state[13] = z[1];
          state[14] = z[2];
          state[15] = z[3];
      #endif
  }

Upvotes: 0

Views: 8975

Answers (2)

SteveH
SteveH

Reputation: 1

Same problem..

I had an mpu6050 working on arduino uno using Jeff's code.

I ported it to Teensy 3.1.. Didn't work

I had to put in a line of code making the pin being used as an interrupt and input pin. I used pin 15.

pinMode(15, INPUT);
attachInterrupt(15, dmpDataReady, RISING);

Then it all worked.

Checkout this link: Does shaking mean detecting changes in acceleration?

http://www.raspberrypi.org/forums/viewtopic.php?t=66402&p=489229

Upvotes: 0

user1363642
user1363642

Reputation: 1

Your problem is the MPU6050 code declares interrupt pins for the UNO. With the UNO there are a few interrupt pins, and the first is called "0." However this corresponds with pin 2.

With the teensy 3.x interrupt pin declaration is similar, except that you declare any particular pin an interrupt (most of them if not all are interrupt capable.)

This is a similar answer to SteveH, i believe I have just made it more explicit.

I believe there exists a MPU6050 DMP code fork by Paul, the creator of Teensy. I would assume this part of the code is fixed.

Upvotes: 0

Related Questions