Sparkfun MPU6050 accelero and gyro - help needed with interrupt from sensor

Hi fellow Arduino-developers,

I made a circuitry with the MPU6050 sensor, using the libraries from GitHub (i2cdevlib/Arduino/MPU6050 at master · jrowberg/i2cdevlib · GitHub) I could read and process the accelero and gyro values wonderfully.

But I would like to have an instant response from Arduino in case the acceleration values go above a certain level. So far I had no luck, I see no trigger from the INT pin of the MPU6050 board to the D2 INT port of the Arduino nano. Otherwise I tested the interrupt with simple switches to GND, it triggers all right.

Does anyone have a working code with the GitHub library using the interrupt of the MPU6050?

Help is much appreciated!

Cheers: Andras

After much debugging trying every possible way to program the interrupt of the MPU6050 and reading through all materials I could find on the net the sad conclusion:

The MPU6050 can not produce an interrupt signal on its INT pin. It's rather disappointing that they seeming never fixed this (simple to fix) bug...

Does anyone know any other accelerometer breakout board with proven working interrupt?

Protonerd:
After much debugging trying every possible way to program the interrupt of the MPU6050 and reading through all materials I could find on the net the sad conclusion:

The MPU6050 can not produce an interrupt signal on its INT pin. It's rather disappointing that they seeming never fixed this (simple to fix) bug...

Does anyone know any other accelerometer breakout board with proven working interrupt?

Strange - the Rowberg library and code uses theMPU6050 module's interrupt in the "MPU6050_DMP.ino" code.

attachInterrupt(0, dmpDataReady, RISING);

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
    mpuInterrupt = true;
}

Don't believe everything you read.
I've used the "MPU6050_DMP.ino" code, and it works.

Wow, OldSteve, you've put me on the right track. I've tried the above mentioned sketch and it really works. I even tried to remove the connection between D2 of the Arduino Nano and INT of the MPU6050 breakout board, and the interrupts cease to be transmitted. So this works.

After this I went on to program the MPU6050 for motion detection interrupt. For the INT setup I modified the MPU6050_DMP.ino to output the contents of the INT_PIN_CFG and the INT_ENABLE registers to have exactly the same setup, except that I disabled all interrupt sources other than the MOT_INT.

Now it sort of does something. If I move the board with sufficient force/acceleration, I can see from the content of the interrupt register that a motion detection interrupt happened. So the interrupt is generated, half a victory.
I still do not get the INT pin triggering the Arduino though. One bug in my code I already fixed: the D2 (int0) was programmed to have the internal pull-up -> the INT pin cannot compete against that. Still, something is still missing, I concluded so far that:

  • either something is still wrong with how I set up the D2 pin
  • or the MPU6050 really has a bug and while it is able to generate an interrupt signal upon certain interrupt events like data ready, in case of the motion detection it does not.

I will go on to validate above 2 theories as soon as I can zoom in on my breadboard again. But I have to tell, even having to poll the interrupt status register it's much faster than reading out the raw values and doing the maths in the code, so now I have a more instantaneous response to motion than before :smiley:

Protonerd:
Wow, OldSteve, you've put me on the right track. I've tried the above mentioned sketch and it really works. I even tried to remove the connection between D2 of the Arduino Nano and INT of the MPU6050 breakout board, and the interrupts cease to be transmitted. So this works.

After this I went on to program the MPU6050 for motion detection interrupt. For the INT setup I modified the MPU6050_DMP.ino to output the contents of the INT_PIN_CFG and the INT_ENABLE registers to have exactly the same setup, except that I disabled all interrupt sources other than the MOT_INT.

Now it sort of does something. If I move the board with sufficient force/acceleration, I can see from the content of the interrupt register that a motion detection interrupt happened. So the interrupt is generated, half a victory.
I still do not get the INT pin triggering the Arduino though. One bug in my code I already fixed: the D2 (int0) was programmed to have the internal pull-up -> the INT pin cannot compete against that. Still, something is still missing, I concluded so far that:

  • either something is still wrong with how I set up the D2 pin
  • or the MPU6050 really has a bug and while it is able to generate an interrupt signal upon certain interrupt events like data ready, in case of the motion detection it does not.

I will go on to validate above 2 theories as soon as I can zoom in on my breadboard again. But I have to tell, even having to poll the interrupt status register it's much faster than reading out the raw values and doing the maths in the code, so now I have a more instantaneous response to motion than before :smiley:

Good one. I'm pleased that you're seeing some progress. I don't have an MPU6050 set up at the moment, or a free Arduino to do so, or I'd do some more experimenting myself.
During my testing I was only interested in pitch and roll, getting servos to compensate for both, and didn't delve any deeper.
Good luck. :slight_smile:

Bad news.

Related also to: MPU-6050 - interrupt threshold - Sensors - Arduino Forum

Even before I red above thread, I made some modifications to the MPU6050_DMP6 code, becuuse it was somehow conspicious to me. I my code motion detection simply did not work. Then instead of wasting time to debug why, I choose to modify the DMP code example to enable motion detection interrupt in place of the data ready interrupt. I got the same result, namely a steady flow of interrupts even if I did not touch the board. Then I went one step further: I disabled all interrupt sources, red back the INT_ENABLE register to confirm no int source is active. Still the steady flow of interrupts continued.

Rigth now I do not have access to a scope, but if I'm to believe the quoted thread, this is not a real interrupt, more a function of the used library. So it still cannot be confirmed that the MPU6050 can send interrupts at all...it detects interrupts but it fails to relay it to the host processor...

Protonerd:
my code motion detection simply did not work. Then instead of wasting time to debug why, I choose to modify the DMP code example to enable motion detection interrupt in place of the data ready interrupt. I got the same result, namely a steady flow of interrupts even if I did not touch the board.

I found that no matter how well I calibrated the MPU6050, I couldn't get a stable 'yaw' value with the "MPU6050_DMP.ino" example. I had constant yaw drift, and occasionally a 30 degree error right from startup. As such, "motion-detection" would have been impossible. I tried two different (identical) modules, but both exhibited the same behaviour. It didn't matter to me, since I was only concerned with 'pitch' and 'roll', and they were both stable. You really need to use a magnetometer as a reference, to stabilise the yaw values

Then I went one step further: I disabled all interrupt sources, red back the INT_ENABLE register to confirm no int source is active. Still the steady flow of interrupts continued.

This is worrying. I can't connect a module up and test right now, but when I get a chance I will. It won't be useful to you though, because I can't do it for a few weeks.

Rigth now I do not have access to a scope, but if I'm to believe the quoted thread, this is not a real interrupt, more a function of the used library. So it still cannot be confirmed that the MPU6050 can send interrupts at all...it detects interrupts but it fails to relay it to the host processor...

I have an oscilloscope, so will be able to test properly, but have to wait until a couple more Arduinos arrive, in a few weeks as mentioned. The two that I have here right now are tied up in projects, and I don't want to disconnect everything and remove either.

Another point I noticed, from the thread that you linked to. Regarding calibration, it needs to be done often. I found that I had to recalibrate the offsets to different values every time I powered up, even if I hadn't moved the module between tests. (It was held in place with Blu-Tack, so couldn't have moved.)
Even small temperature changes appear to have an effect.

Hi OldSteve,

Thanks for helping me out here.
Actually my sketch uses only a very simple way to deal with the values provided by the sensor, I need only the acceleration values for a sort of hit/clash detection. And that works fine if I just read them back without interrupt. With interrupt the detection would be simply faster, eliminating a lag which can be critical to the application. Therefore I need the INT pin of the MPU6050 to signal the event instead of polling the values.

And that does not seem to work...

Could you share how you configure this to do motion and collision as two different events?

Hi DJWing79,

Currently I keep it rather simple.

I use the command
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
to read out the raw acceleration (and gyro, but these I do not use) values, then I compare them to set thresholds:
if ((abs(ax) > 1000 or abs(ay) > 1000 or (az) > 1000)) { //code for swing}

For collosion, I simply use different thresholds. Now I also experiment with setting up the motion detection interrupt, which can give me a more instantenous response to collosion. I share the code when it's mature enough, but the above method also works quite well.

I made some scope measurements to try to figure out why the motion detect interrupt is not working with the MPU-6050:


Pic#1 and Pic#2: First I used the MPU6050_DMP.ino sketch to see how it works there, because it does seem to work in that code. The above 2 pics show that principally it's possible to have INT pulses, you can even switch between active low and active high.


Pic#3: 2nd thing I wanted to see is how frequently the interrupts come in the DMP sketch. It looks that an INT pulse comes in 15ms intervals.

Pic#4: 3rd thing I tried was to disable all interrupt sources in the same DMP example sketch. I merged this with setting the INT to active high and Latched mode. Level and Latch mode work (longer pulse), but INT cannot be disabled, I still get the same periodic signal. :frowning:

Pic#5: Now that I knew that 1. INT pin can trigger Arduino 2. this periodic signal I cannot disable, I wanted to know whether the MPU reacts on motion. So I used my code to enable only motion detection. And yes! I can still see the periodic signal, but also the intermittend INT pulses due to the motion detection (shaking and hitting the bread board against the table).


Pic#6 and Pic#7: Now that I knew what to expect from a known working code, I switched to my application. Goal was to have an INT triggered from MPU6050 to the D2 pin of the Arduino Nano upon sudden movements (hitting or shaking the board). Well, first of all in my sketch I still saw the periodic signal. As I already mentioned in my previous posts, it cannot be therefore an intentional feature of the DMP sketch, so I have to conclude that the DMP sketch is also not doing what it's meant to. Secondly, with exactly the same connections from MPU6050 INT pin to D2, in my sketch the signal level the INT pin reaches degraded... This is what can be seen on the above 2 pics. No idea why so far, I checked the code and I do not reprogram the D2 anyhow there...but it's settings must be different from that used for the same pin in the DMP sketch.

Pic#8: last but not least I wanted to see how the MPU reacts to the motions. I disconnected the INT pin from the D2 assuming that the pin config loads the INT in a way that it cannot reach near the upper rail. With D2 disconnected I saw a nice signal waveform. I can also see INT pulses launched by the clash and the reaction to it (DFPLayer starts a command as reaction), as well as the unintentional phantom pulses.

So the questions to be found out is:

  1. where these ever present phantom pulses coming from?
  2. how do I (re)program the D2 pin in my sketch in order not to overload the INT from the MPU?

Those 'phantom' pulses are very narrow compared to a genuine INT.
You might be able to filter them out with a simple RC filter, so they don't get high enough to trigger an interrupt on the Arduino.

Just a thought. I'm pretty busy on other stuff right now, and don't have time to dig deeper or set up a circuit myself.

I've got no update up to now from InvenSense (but they keep bombarding me with their marketing emails... >:( ), I'm a bit surprised they keep such a low profile on this forum. Or they know there is a bug but do not want to comment as long as inquires come from small customers.

Anyway, I also tried to contact Jeff Rowberg too, so far no reply, does someone have a good connection to him who might approach him politely on behalf of the community?

Thanks guys in advance!

Hi all,
i was succesfull to make to work a interrupt generation for MPU6050 and ATmega8.
I use library from David Gironi ( Davide Gironi: AVR Atmega MPU6050 gyroscope and accelerometer lib + processing )

and to mpu6050.c add this function:

void mpu6050_DMPinit() {

//MOTION INT ENABLE
mpu6050_writeByte(MPU6050_RA_INT_ENABLE,0x40);

//MOTION DURATION
mpu6050_writeByte(MPU6050_RA_MOT_DUR,1);

//MOTION THR
mpu6050_writeByte(MPU6050_RA_MOT_THR,20);

_delay_ms(1);

//set HPF to HOLD settings
mpu6050_writeBits(MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_ACCEL_HPF_BIT, MPU6050_ACONFIG_ACCEL_HPF_LENGTH, 0b111);

//PIN INT0
mpu6050_writeBits(MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_LEVEL_BIT, 2, 0b10);
}

And this finally work! Then i make some investigations and figured out it also in standby mode (less power consumption). Find that in encosure - Eclipse project.
About power consumption - now the module takes 1,7 mA but through I2C wires goes most of this current (i will try to correct it somehow)

Hope this helps somebody

MotoUnit.zip (64.3 KB)

Zbysekz:
Hi all,
i was succesfull to make to work a interrupt generation for MPU6050 and ATmega8.
I use library from David Gironi ( Davide Gironi blog: AVR Atmega MPU6050 gyroscope and accelerometer lib + processing )

If it works if sure helps a lot of projects out there! Did you check that the periodic interrupts coming from the i2c library are gone? Because as can be seen on the scope shots further up this thread, the MPU can generate interrupts based on motion detection threshold, but it is interpolated on the continouos stream of interrupts from the i2c. Can you advice which is the setting in your code which will tell the MPU not to send the periodic interrupts?

"Why this is so important to me?
I would like to use interrupt from MPU to wake-up arduino on movement - to save battery, when device is not in use.
... Circuit should be awake only when someone is holding/throwing it."

Hi maybe it's too late to answer this... but for record, I solved this problem using the LowPower.h library and the SW420 sensor; not MPU6050.