MPU6050 accelerometer and gyro readings in parallel on a code

Hi,

I'm trying to work on a code that reads the YPR from an MPU6050, using the DM6 code from J. Rowberg and simultaneously process the dynamic accelerometer readings to detect impact on the system.

I would like to ask you guys if something like this would be even possible:
Starting with the basic example, I want to light up a LED when the gyro readings in X, Y or Z exceeds 90 degrees. In parallel, the accelerometer from the same MPU, should be ready to detect impacts above 2g and light up the LED even if the angles are below 90 degrees.

Blink the LED with the angles is quite simple, but I cannot figure how to add the impact thing.

This question might have been answered on the "Demonstration code for several things at the same time", but it's still not clear to me. I've been also researching and trying for a while, but no positive result.

Thank you in advance and best regards
Fernando

Post you code. Without that we cannot know what you are talking about. And please use the code button </> so your code looks like this and is easy to copy to a text editor.

Maybe the demo Several Things at a Time will give you some ideas.

...R

actually I didn't upload my code on the first time because it's not working.
The problem is that Arduino reads only the second sub loop (ledIMPACT) and ignores the ledANGLE (probably because it reads the first and goes to next):

#define SENSOR_LED 6 

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

MPU6050 mpu; //defines a name for the MPU

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high

void setup() 
{
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    Serial.begin(115200);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately

    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();

    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

    mpu.setXGyroOffset(17); //original 220
    mpu.setYGyroOffset(35); //original 76
    mpu.setZGyroOffset(-24); //original -85
    mpu.setXAccelOffset(-888);
    mpu.setYAccelOffset(1744);
    mpu.setZAccelOffset(1589); // 1688 factory default for my test chip original 1788
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }
    //init LEDs
    pinMode(SENSOR_LED, OUTPUT);
}

void ledANGLE (int gx, int gy, int gz) //defines locking values for angle sensibility (tiltlock)
{
    if ( (gy >= -10 && gy <= 10) && (gz >= -10 && gz <= 10) ) {  //LED is off between -10 and 10 degrees, in Y and Z directions;
        digitalWrite(SENSOR_LED, LOW);
    
    } else {  
        digitalWrite(SENSOR_LED, HIGH);    }
     
    Serial.print("ypr\t");
    Serial.print(gx);Serial.print("\t");  
    Serial.print(gy);Serial.print("\t");  
    Serial.println(gz);//Serial.print("\t");
}

void ledIMPACT (int ax, int ay, int az)
{
    if ( (ax > -3 && ax < 3) && (ay > -3 && ay < 3) && (az > -3 && az < 3) ) {  //LED is off between -3 and 3G in any direction;
        digitalWrite(SENSOR_LED, LOW);
        
    } else {  
        digitalWrite(SENSOR_LED, HIGH);    }
     
    Serial.print("areal\t");
    Serial.print(ax);Serial.print("\t");  
    Serial.print(ay);Serial.print("\t");  
    Serial.println(az);
}

void loop() 
{
    if (!dmpReady) return;
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();
    fifoCount = mpu.getFIFOCount();
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));

    } else if (mpuIntStatus & 0x02) {
        while (fifoCount < packetSize) {
          fifoCount = mpu.getFIFOCount();
        }
        mpu.getFIFOBytes(fifoBuffer, packetSize);    
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetAccel(&aa, fifoBuffer);
        mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        
        ledANGLE(ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI); //changes already YPR values from raw to angles
        ledIMPACT(aaReal.x / 8192, aaReal.y / 8192, aaReal.z / 8192);      //changes already acceleration values from raw to G's
    
    }
}

void dmpDataReady() 
{
    mpuInterrupt = true;
}

mercurifh:
actually I didn't upload my code on the first time because it's not working.

You would hardly be wasting your time here if it was working :slight_smile:

The problem is that Arduino reads only the second sub loop (ledIMPACT) and ignores the ledANGLE (probably because it reads the first and goes to next):

Just to be clear, do you mean that the line Serial.print("ypr\t"); and the 3 following lines never print? I can't see any obvious reason why not.

...R

Robin2:
Just to be clear, do you mean that the line Serial.print("ypr\t"); and the 3 following lines never print? I can't see any obvious reason why not.

on the serial monitor I see the gyro values and the accelerometer values... but the LED will only be 100% on if the accelerometer receives values above 3G. When there's only tilting above 10 degrees, the LED is also on but very weak (almost could not see its light).

Looks like to me that the two IF's are confusing the single LED

mercurifh:
on the serial monitor I see the gyro values and the accelerometer values... but the LED will only be 100% on if the accelerometer receives values above 3G. When there's only tilting above 10 degrees, the LED is also on but very weak (almost could not see its light).

Looks like to me that the two IF's are confusing the single LED

As you are using the same LED in the two functions that is not surprising. However I had understood from your earlier comment "reads only the second sub loop (ledIMPACT) and ignores the ledANGLE" that you code was not calling the function ledANGLE() at all. It did not occur to me to look at the variable names inside the function.

Try using two different LEDs (at least for debugging purposes).

...R