kriswiner / MPU9250

Arduino sketches for MPU9250 9DoF with AHRS sensor fusion
1.03k stars 472 forks source link

QuaternionFilter Unstable q values #421

Closed beaumr2 closed 4 years ago

beaumr2 commented 4 years ago

Hi Kris

First of all, thank you for this.

So I'm using your code and having trouble with the QuaternionFilter. The accelerometer, gyroscope, and magnetometer values are stable but my q values vary wildly (and seem to want to alternate between positive and negative) which is messing up my pitch, roll, and yaw.

Do you have any idea what might be causing this? I'm using Arduino Uno and your code. I can paste the code if needed but here's the output:

x-axis self test: acceleration trim within : 0.7% of factory value y-axis self test: acceleration trim within : -0.5% of factory value z-axis self test: acceleration trim within : 2.3% of factory value x-axis self test: gyration trim within : 34.6% of factory value y-axis self test: gyration trim within : 14.5% of factory value z-axis self test: gyration trim within : 0.8% of factory value accel biases (mg) -318.97 370.91 -494.32 gyro biases (dps) -4.59 -9.87 -0.75 MPU9250 initialized for active data mode.... AK8963 I AM 48 I should be 48 AK8963 initialized for active data mode.... AK8963 mag biases (mG) 71.04 122.43 -36.90 AK8963 mag scale (mG) 1.01 1.03 0.96 Calibration values: X-Axis sensitivity adjustment value 1.16 Y-Axis sensitivity adjustment value 1.17 Z-Axis sensitivity adjustment value 1.13

ax = 0.73 ay = 0.37 az = 995.42 mg gx = -0.03 gy = -0.23 gz = -0.17 deg/s mx = 0 my = 0 mz = 0 mG q0 = 1.00 qx = 0.00 qy = 0.00 qz = 0.00 Gyro temperature is 34.0 degrees C Yaw, Pitch, Roll: 13.80, 0.00, 0.00 Grav_x, Grav_y, Grav_z: 0.00, 0.00, 1000.00 mg Lin_ax, Lin_ay, Lin_az: 0.73, 0.37, -4.58 mg rate = 1.04 Hz

ax = 0.55 ay = -1.34 az = 995.30 mg gx = 0.05 gy = 0.05 gz = -0.12 deg/s mx = 27111 my = 164 mz = 35 mG q0 = 0.64 qx = -0.00 qy = 0.00 qz = -0.77 Gyro temperature is 34.1 degrees C Yaw, Pitch, Roll: 273.04, 0.00, -0.13 Grav_x, Grav_y, Grav_z: 2.33, 0.08, 1000.00 mg Lin_ax, Lin_ay, Lin_az: -1.78, -1.43, -4.70 mg rate = 4.87 Hz

ax = 376.28 ay = -1855.29 az = 494.32 mg gx = 0.05 gy = 0.05 gz = -0.12 deg/s mx = 27111 my = 164 mz = 35 mG q0 = 0.51 qx = -0.33 qy = 0.60 qz = -0.52 Gyro temperature is 21.1 degrees C Yaw, Pitch, Roll: 268.09, 16.15, -86.28 Grav_x, Grav_y, Grav_z: 958.51, 278.15, 62.35 mg Lin_ax, Lin_ay, Lin_az: -582.23, -2133.44, 431.97 mg rate = 4.87 Hz

ax = 376.28 ay = -1855.29 az = 494.32 mg gx = 0.05 gy = 0.05 gz = -0.12 deg/s mx = 27111 my = 164 mz = 35 mG q0 = 0.41 qx = -0.17 qy = -0.18 qz = -0.88 Gyro temperature is 21.1 degrees C Yaw, Pitch, Roll: 241.13, -26.40, 10.91 Grav_x, Grav_y, Grav_z: -169.48, -444.57, 879.57 mg Lin_ax, Lin_ay, Lin_az: 545.76, -1410.72, -385.24 mg rate = 4.87 Hz

beaumr2 commented 4 years ago

I should mention this is with the MPU9250 on a flat table and not moving, of course

kriswiner commented 4 years ago

You are not getting any mag data, same corrupted output every cycle...

On Fri, Jun 12, 2020 at 3:19 PM beaumr2 notifications@github.com wrote:

I should mention this is with the MPU9250 on a flat table and not moving, of course

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-643504943, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKSAV53BIFISD5MFJC3RWKSVVANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

I get mag data after the first few iterations I thought: mx = 27111 my = 164 mz = 35 mG

If not then what would be preventing me from getting mag data?

kriswiner commented 4 years ago

our accel data is corrupted too:

ax = 376.28 ay = -1855.29 az = 494.32 mg

I would say your I2C API or conversion to int16_t is messed up. What is your MCU?

On Fri, Jun 12, 2020 at 3:41 PM beaumr2 notifications@github.com wrote:

I get mag data after the first few iterations I thought: mx = 27111 my = 164 mz = 35 mG

If not then what would be preventing me from getting mag data?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-643510497, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKXXFXC6XWXQHH6RZ33RWKVK7ANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

Arduino Uno

Not sure why it's corrupted? Here's the code I'm using. The quaternionfilter file is copied exactly from your website:

/*Demonstrate basic MPU-9250 functionality including parameterizing the register addresses, initializing the sensor, getting properly scaled accelerometer, gyroscope, and magnetometer data out. Addition of 9 DoF sensor fusion using open source Madgwick and Mahony filter algorithms. Sketch runs on the 3.3 V Dragonfly STM32L476 Breakout Board.

The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of only 1 microAmp. The choice will depend on the application.

SDA and SCL have 4K7 pull-up resistors (to 3.3V). */

include "Wire.h"

include "MPU9250.h"

include "RTC.h"

define SerialDebug true // set to true to get Serial output for debugging

// MPU9250 Configuration // Specify sensor full scale /* Choices are:

// Pin definitions int intPin = 9; // MPU9250 interrupt

bool intFlag = true; bool newMagData = false;

int16_t MPU9250Data[7]; // used to read all 14 bytes at once from the MPU9250 accel/gyro int16_t magCount[3]; // Stores the 16-bit signed magnetometer sensor output float magCalibration[3] = {0, 0, 0}; // Factory mag calibration and mag bias float temperature; // Stores the MPU9250 internal chip temperature in degrees Celsius float SelfTest[6]; // holds results of gyro and accelerometer self test

// These can be measured once and entered here or can be calculated each time the device is powered on float gyroBias[3] = {0.96, -0.21, 0.12}, accelBias[3] = {0.00299, -0.00916, 0.00952}; float magBias[3] = {71.04, 122.43, -36.90}, magScale[3] = {1.01, 1.03, 0.96}; // Bias corrections for gyro and accelerometer

uint32_t delt_t = 0; // used to control display output rate uint32_t count = 0, sumCount = 0; // used to control display output rate float pitch, yaw, roll; // absolute orientation float a12, a22, a31, a32, a33; // rotation matrix coefficients for Euler angles and gravity components float deltat = 0.0f, sum = 0.0f; // integration interval for both filter schemes uint32_t lastUpdate = 0, firstUpdate = 0; // used to calculate integration interval uint32_t Now = 0; // used to calculate integration interval

float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values float lin_ax, lin_ay, lin_az; // linear acceleration (acceleration with gravity component subtracted) float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion float eInt[3] = {0.0f, 0.0f, 0.0f}; // vector to hold integral error for Mahony method

MPU9250 MPU9250(intPin); // instantiate MPU9250 class

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

Wire.begin(); // set master mode, default on SDA/SCL for Ladybug
Wire.setClock(400000); // I2C frequency at 400 kHz delay(1000);

MPU9250.I2Cscan(); // should detect BME280 at 0x77, MPU9250 at 0x71

pinMode(intPin, INPUT);

/ Configure the MPU9250 / // Read the WHO_AM_I register, this is a good test of communication Serial.println("MPU9250 9-axis motion sensor..."); uint8_t c = MPU9250.getMPU9250ID(); Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX); Serial.print(" I should be "); Serial.println(0x71, HEX); delay(1000);

if (c == 0x71 ) // WHO_AM_I should always be 0x71 for MPU9250, 0x73 for MPU9255 {
Serial.println("MPU9250 is online...");

MPU9250.resetMPU9250(); // start by resetting MPU9250

MPU9250.SelfTest(SelfTest); // Start by performing self test and reporting values
Serial.print("x-axis self test: acceleration trim within : "); Serial.print(SelfTest[0],1); Serial.println("% of factory value");
Serial.print("y-axis self test: acceleration trim within : "); Serial.print(SelfTest[1],1); Serial.println("% of factory value");
Serial.print("z-axis self test: acceleration trim within : "); Serial.print(SelfTest[2],1); Serial.println("% of factory value");
Serial.print("x-axis self test: gyration trim within : "); Serial.print(SelfTest[3],1); Serial.println("% of factory value");
Serial.print("y-axis self test: gyration trim within : "); Serial.print(SelfTest[4],1); Serial.println("% of factory value");
Serial.print("z-axis self test: gyration trim within : "); Serial.print(SelfTest[5],1); Serial.println("% of factory value");
delay(1000);

// get sensor resolutions, only need to do this once aRes = MPU9250.getAres(Ascale); gRes = MPU9250.getGres(Gscale); mRes = MPU9250.getMres(Mscale);

// Comment out if using pre-measured, pre-stored offset biases MPU9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers Serial.println("accel biases (mg)"); Serial.println(1000.accelBias[0]); Serial.println(1000.accelBias[1]); Serial.println(1000.*accelBias[2]); Serial.println("gyro biases (dps)"); Serial.println(gyroBias[0]); Serial.println(gyroBias[1]); Serial.println(gyroBias[2]); delay(1000);

MPU9250.initMPU9250(Ascale, Gscale, sampleRate); Serial.println("MPU9250 initialized for active data mode...."); // Initialize device for active mode read of acclerometer, gyroscope, and temperature

// Read the WHO_AM_I register of the magnetometer, this is a good test of communication byte d = MPU9250.getAK8963CID(); // Read WHO_AM_I register for AK8963 Serial.print("AK8963 "); Serial.print("I AM "); Serial.print(d, HEX); Serial.print(" I should be "); Serial.println(0x48, HEX); delay(1000);

// Get magnetometer calibration from AK8963 ROM MPU9250.initAK8963Slave(Mscale, Mmode, magCalibration); Serial.println("AK8963 initialized for active data mode...."); // Initialize device for active mode read of magnetometer

// Comment out if using pre-measured, pre-stored offset biases // MPU9250.magcalMPU9250(magBias, magScale); Serial.println("AK8963 mag biases (mG)"); Serial.println(magBias[0]); Serial.println(magBias[1]); Serial.println(magBias[2]); Serial.println("AK8963 mag scale (mG)"); Serial.println(magScale[0]); Serial.println(magScale[1]); Serial.println(magScale[2]); delay(2000); // add delay to see results before serial spew of data

if(SerialDebug) { Serial.println("Calibration values: "); Serial.print("X-Axis sensitivity adjustment value "); Serial.println(magCalibration[0], 2); Serial.print("Y-Axis sensitivity adjustment value "); Serial.println(magCalibration[1], 2); Serial.print("Z-Axis sensitivity adjustment value "); Serial.println(magCalibration[2], 2);

attachInterrupt(intPin, myinthandler, RISING); // define interrupt for intPin output of MPU9250 }

} else { Serial.print("Could not connect to MPU9250: 0x"); Serial.println(c, HEX); while(1) ; // Loop forever if communication doesn't happen }

}

void loop() {
// If intPin goes high, either all data registers have new data if(intFlag == true) { // On interrupt, read data //intFlag = false; // reset newData flag

 MPU9250.readMPU9250Data(MPU9250Data); // INT cleared on any read

// Now we'll calculate the accleration value into actual g's
 ax = (float)MPU9250Data[0]*aRes - accelBias[0];  // get actual g value, this depends on scale being set
 ay = (float)MPU9250Data[1]*aRes - accelBias[1];   
 az = (float)MPU9250Data[2]*aRes - accelBias[2];  

// Calculate the gyro value into actual degrees per second
 gx = (float)MPU9250Data[4]*gRes;  // get actual gyro value, this depends on scale being set
 gy = (float)MPU9250Data[5]*gRes;  
 gz = (float)MPU9250Data[6]*gRes; 

if( MPU9250.checkNewMagData() == true) { // wait for magnetometer data ready bit to be set
  MPU9250.readMagData(magCount);  // Read the x/y/z adc values

// Calculate the magnetometer values in milliGauss
// Include factory calibration per data sheet and user environmental corrections
  mx = (float)magCount[0]*mRes*magCalibration[0] - magBias[0];  // get actual magnetometer value, this depends on scale being set
  my = (float)magCount[1]*mRes*magCalibration[1] - magBias[1];  
  mz = (float)magCount[2]*mRes*magCalibration[2] - magBias[2];  
  mx *= magScale[0];
  my *= magScale[1];
  mz *= magScale[2]; 
}

for(uint8_t i = 0; i < 10; i++) { // iterate a fixed number of times per data read cycle
Now = micros();
deltat = ((Now - lastUpdate)/1000000.0f); // set integration time by time elapsed since last filter update
lastUpdate = Now;

sum += deltat; // sum for averaging filter update rate
sumCount++;

MadgwickQuaternionUpdate(-ax, +ay, +az, gx*pi/180.0f, -gy*pi/180.0f, -gz*pi/180.0f,  my,  -mx, mz);
}

/* end of MPU9250 interrupt handling */

}

if(SerialDebug) {
Serial.print("ax = "); Serial.print((int)1000*ax);  
Serial.print(" ay = "); Serial.print((int)1000*ay); 
Serial.print(" az = "); Serial.print((int)1000*az); Serial.println(" mg");
Serial.print("gx = "); Serial.print( gx, 2); 
Serial.print(" gy = "); Serial.print( gy, 2); 
Serial.print(" gz = "); Serial.print( gz, 2); Serial.println(" deg/s");
Serial.print("mx = "); Serial.print( (int)mx ); 
Serial.print(" my = "); Serial.print( (int)my ); 
Serial.print(" mz = "); Serial.print( (int)mz ); Serial.println(" mG");

Serial.print("q0 = "); Serial.print(q[0]);
Serial.print(" qx = "); Serial.print(q[1]); 
Serial.print(" qy = "); Serial.print(q[2]); 
Serial.print(" qz = "); Serial.println(q[3]); 

temperature = ((float) MPU9250Data[3]) / 333.87f + 21.0f; // Gyro chip temperature in degrees Centigrade
// Print temperature in degrees Centigrade      
Serial.print("Gyro temperature is ");  Serial.print(temperature, 1);  Serial.println(" degrees C"); // Print T values to tenths of s degree C
}               

a12 =   2.0f * (q[1] * q[2] + q[0] * q[3]);
a22 =   q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3];
a31 =   2.0f * (q[0] * q[1] + q[2] * q[3]);
a32 =   2.0f * (q[1] * q[3] - q[0] * q[2]);
a33 =   q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
pitch = -asinf(a32);
roll  = atan2f(a31, a33);
yaw   = atan2f(a12, a22);
pitch *= 180.0f / pi;
yaw   *= 180.0f / pi; 
yaw   += 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04
if(yaw < 0) yaw   += 360.0f; // Ensure yaw stays between 0 and 360
roll  *= 180.0f / pi;
lin_ax = ax + a31;
lin_ay = ay + a32;
lin_az = az - a33;

if(SerialDebug) {
Serial.print("Yaw, Pitch, Roll: ");
Serial.print(yaw, 2);
Serial.print(", ");
Serial.print(pitch, 2);
Serial.print(", ");
Serial.println(roll, 2);

Serial.print("Grav_x, Grav_y, Grav_z: ");
Serial.print(-a31*1000.0f, 2);
Serial.print(", ");
Serial.print(-a32*1000.0f, 2);
Serial.print(", ");
Serial.print(a33*1000.0f, 2);  Serial.println(" mg");
Serial.print("Lin_ax, Lin_ay, Lin_az: ");
Serial.print(lin_ax*1000.0f, 2);
Serial.print(", ");
Serial.print(lin_ay*1000.0f, 2);
Serial.print(", ");
Serial.print(lin_az*1000.0f, 2);  Serial.println(" mg");

Serial.print("rate = "); Serial.print((float)sumCount/sum, 2); Serial.println(" Hz");
sumCount = 0;
sum = 0;    
delay(2000);
}

}

//=================================================================================================================== //====== Set of useful functions //===================================================================================================================

void myinthandler() { intFlag = true; }

kriswiner commented 4 years ago

First thing to try is connect out bolded lines here:

if( MPU9250.checkNewMagData() == true) { // wait for magnetometer data ready bit to be set MPU9250.readMagData(magCount); // Read the x/y/z adc values

// Calculate the magnetometer values in milliGauss // Include factory calibration per data sheet and user environmental corrections mx = (float)magCount[0]mResmagCalibration[0] - magBias[0]; // get actual magnetometer value, this depends on scale being set my = (float)magCount[1]mResmagCalibration[1] - magBias[1]; mz = (float)magCount[2]mResmagCalibration[2] - magBias[2]; mx = magScale[0]; my = magScale[1]; mz *= magScale[2];

}

and why is this line commented out?

//intFlag = false; // reset newData flag

shouldn't be...

On Fri, Jun 12, 2020 at 5:10 PM beaumr2 notifications@github.com wrote:

Arduino Uno

Not sure why it's corrupted? Here's the code I'm using. The quaternionfilter file is copied exactly from your website:

/*Demonstrate basic MPU-9250 functionality including parameterizing the register addresses, initializing the sensor, getting properly scaled accelerometer, gyroscope, and magnetometer data out. Addition of 9 DoF sensor fusion using open source Madgwick and Mahony filter algorithms. Sketch runs on the 3.3 V Dragonfly STM32L476 Breakout Board.

The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of only 1 microAmp. The choice will depend on the application.

SDA and SCL have 4K7 pull-up resistors (to 3.3V). */

include "Wire.h"

include "MPU9250.h"

include "RTC.h"

define SerialDebug true // set to true to get Serial output for debugging

// MPU9250 Configuration // Specify sensor full scale /* Choices are:

  • Gscale: GFS_250 == 250 dps, GFS_500 DPS == 500 dps, GFS_1000 == 1000 dps, and GFS_2000DPS == 2000 degrees per second gyro full scale
  • Ascale: AFS_2G == 2 g, AFS_4G == 4 g, AFS_8G == 8 g, and AFS_16G == 16 g accelerometer full scale
  • Mscale: MFS_14BITS == 0.6 mG per LSB and MFS_16BITS == 0.15 mG per LSB
  • Mmode: Mmode == M_8Hz for 8 Hz data rate or Mmode = M_100Hz for 100 Hz data rate
  • (1 + sampleRate) is a simple divisor of the fundamental 1000 kHz rate of the gyro and accel, so
  • sampleRate = 0x00 means 1 kHz sample rate for both accel and gyro, 0x04 means 200 Hz, etc. / uint8_t Gscale = GFS_250DPS, Ascale = AFS_2G, Mscale = MFS_16BITS, Mmode = M_100Hz, sampleRate = 0x04; float aRes, gRes, mRes; // scale resolutions per LSB for the sensors float motion = 0; // check on linear acceleration to determine motion // global constants for 9 DoF fusion and AHRS (Attitude and Heading Reference System) float pi = 3.141592653589793238462643383279502884f; float GyroMeasError = pi (40.0f / 180.0f); // gyroscope measurement error in rads/s (start at 40 deg/s) float GyroMeasDrift = pi (0.0f / 180.0f); // gyroscope measurement drift in rad/s/s (start at 0.0 deg/s/s) float beta = sqrtf(3.0f / 4.0f) GyroMeasError; // compute beta float zeta = sqrtf(3.0f / 4.0f) * GyroMeasDrift; // compute zeta, the other free parameter in the Madgwick scheme usually set to a small or zero value bool wakeup;

// Pin definitions int intPin = 9; // MPU9250 interrupt

bool intFlag = true; bool newMagData = false;

int16_t MPU9250Data[7]; // used to read all 14 bytes at once from the MPU9250 accel/gyro int16_t magCount[3]; // Stores the 16-bit signed magnetometer sensor output float magCalibration[3] = {0, 0, 0}; // Factory mag calibration and mag bias float temperature; // Stores the MPU9250 internal chip temperature in degrees Celsius float SelfTest[6]; // holds results of gyro and accelerometer self test

// These can be measured once and entered here or can be calculated each time the device is powered on float gyroBias[3] = {0.96, -0.21, 0.12}, accelBias[3] = {0.00299, -0.00916, 0.00952}; float magBias[3] = {71.04, 122.43, -36.90}, magScale[3] = {1.01, 1.03, 0.96}; // Bias corrections for gyro and accelerometer

uint32_t delt_t = 0; // used to control display output rate uint32_t count = 0, sumCount = 0; // used to control display output rate float pitch, yaw, roll; // absolute orientation float a12, a22, a31, a32, a33; // rotation matrix coefficients for Euler angles and gravity components float deltat = 0.0f, sum = 0.0f; // integration interval for both filter schemes uint32_t lastUpdate = 0, firstUpdate = 0; // used to calculate integration interval uint32_t Now = 0; // used to calculate integration interval

float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values float lin_ax, lin_ay, lin_az; // linear acceleration (acceleration with gravity component subtracted) float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion float eInt[3] = {0.0f, 0.0f, 0.0f}; // vector to hold integral error for Mahony method

MPU9250 MPU9250(intPin); // instantiate MPU9250 class

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

Wire.begin(); // set master mode, default on SDA/SCL for Ladybug Wire.setClock(400000); // I2C frequency at 400 kHz delay(1000);

MPU9250.I2Cscan(); // should detect BME280 at 0x77, MPU9250 at 0x71

pinMode(intPin, INPUT);

/ Configure the MPU9250 / // Read the WHO_AM_I register, this is a good test of communication Serial.println("MPU9250 9-axis motion sensor..."); uint8_t c = MPU9250.getMPU9250ID(); Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX); Serial.print(" I should be "); Serial.println(0x71, HEX); delay(1000);

if (c == 0x71 ) // WHO_AM_I should always be 0x71 for MPU9250, 0x73 for MPU9255 { Serial.println("MPU9250 is online...");

MPU9250.resetMPU9250(); // start by resetting MPU9250

MPU9250.SelfTest(SelfTest); // Start by performing self test and reporting values Serial.print("x-axis self test: acceleration trim within : "); Serial.print(SelfTest[0],1); Serial.println("% of factory value"); Serial.print("y-axis self test: acceleration trim within : "); Serial.print(SelfTest[1],1); Serial.println("% of factory value"); Serial.print("z-axis self test: acceleration trim within : "); Serial.print(SelfTest[2],1); Serial.println("% of factory value"); Serial.print("x-axis self test: gyration trim within : "); Serial.print(SelfTest[3],1); Serial.println("% of factory value"); Serial.print("y-axis self test: gyration trim within : "); Serial.print(SelfTest[4],1); Serial.println("% of factory value"); Serial.print("z-axis self test: gyration trim within : "); Serial.print(SelfTest[5],1); Serial.println("% of factory value"); delay(1000);

// get sensor resolutions, only need to do this once aRes = MPU9250.getAres(Ascale); gRes = MPU9250.getGres(Gscale); mRes = MPU9250.getMres(Mscale);

// Comment out if using pre-measured, pre-stored offset biases MPU9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers Serial.println("accel biases (mg)"); Serial.println(1000.accelBias[0]); Serial.println(1000.accelBias[1]); Serial.println(1000.*accelBias[2]); Serial.println("gyro biases (dps)"); Serial.println(gyroBias[0]); Serial.println(gyroBias[1]); Serial.println(gyroBias[2]); delay(1000);

MPU9250.initMPU9250(Ascale, Gscale, sampleRate); Serial.println("MPU9250 initialized for active data mode...."); // Initialize device for active mode read of acclerometer, gyroscope, and temperature

// Read the WHO_AM_I register of the magnetometer, this is a good test of communication byte d = MPU9250.getAK8963CID(); // Read WHO_AM_I register for AK8963 Serial.print("AK8963 "); Serial.print("I AM "); Serial.print(d, HEX); Serial.print(" I should be "); Serial.println(0x48, HEX); delay(1000);

// Get magnetometer calibration from AK8963 ROM MPU9250.initAK8963Slave(Mscale, Mmode, magCalibration); Serial.println("AK8963 initialized for active data mode...."); // Initialize device for active mode read of magnetometer

// Comment out if using pre-measured, pre-stored offset biases // MPU9250.magcalMPU9250(magBias, magScale); Serial.println("AK8963 mag biases (mG)"); Serial.println(magBias[0]); Serial.println(magBias[1]); Serial.println(magBias[2]); Serial.println("AK8963 mag scale (mG)"); Serial.println(magScale[0]); Serial.println(magScale[1]); Serial.println(magScale[2]); delay(2000); // add delay to see results before serial spew of data

if(SerialDebug) { Serial.println("Calibration values: "); Serial.print("X-Axis sensitivity adjustment value "); Serial.println(magCalibration[0], 2); Serial.print("Y-Axis sensitivity adjustment value "); Serial.println(magCalibration[1], 2); Serial.print("Z-Axis sensitivity adjustment value "); Serial.println(magCalibration[2], 2);

attachInterrupt(intPin, myinthandler, RISING); // define interrupt for intPin output of MPU9250 }

} else { Serial.print("Could not connect to MPU9250: 0x"); Serial.println(c, HEX); while(1) ; // Loop forever if communication doesn't happen }

}

void loop() { // If intPin goes high, either all data registers have new data if(intFlag == true) { // On interrupt, read data //intFlag = false; // reset newData flag

MPU9250.readMPU9250Data(MPU9250Data); // INT cleared on any read

// Now we'll calculate the accleration value into actual g's ax = (float)MPU9250Data[0]aRes - accelBias[0]; // get actual g value, this depends on scale being set ay = (float)MPU9250Data[1]aRes - accelBias[1]; az = (float)MPU9250Data[2]*aRes - accelBias[2];

// Calculate the gyro value into actual degrees per second gx = (float)MPU9250Data[4]gRes; // get actual gyro value, this depends on scale being set gy = (float)MPU9250Data[5]gRes; gz = (float)MPU9250Data[6]*gRes;

if( MPU9250.checkNewMagData() == true) { // wait for magnetometer data ready bit to be set MPU9250.readMagData(magCount); // Read the x/y/z adc values

// Calculate the magnetometer values in milliGauss // Include factory calibration per data sheet and user environmental corrections mx = (float)magCount[0]mResmagCalibration[0] - magBias[0]; // get actual magnetometer value, this depends on scale being set my = (float)magCount[1]mResmagCalibration[1] - magBias[1]; mz = (float)magCount[2]mResmagCalibration[2] - magBias[2]; mx = magScale[0]; my = magScale[1]; mz *= magScale[2]; }

for(uint8_t i = 0; i < 10; i++) { // iterate a fixed number of times per data read cycle Now = micros(); deltat = ((Now - lastUpdate)/1000000.0f); // set integration time by time elapsed since last filter update lastUpdate = Now;

sum += deltat; // sum for averaging filter update rate sumCount++;

MadgwickQuaternionUpdate(-ax, +ay, +az, gxpi/180.0f, -gypi/180.0f, -gz*pi/180.0f, my, -mx, mz); }

/ end of MPU9250 interrupt handling /

}

if(SerialDebug) { Serial.print("ax = "); Serial.print((int)1000ax); Serial.print(" ay = "); Serial.print((int)1000ay); Serial.print(" az = "); Serial.print((int)1000*az); Serial.println(" mg"); Serial.print("gx = "); Serial.print( gx, 2); Serial.print(" gy = "); Serial.print( gy, 2); Serial.print(" gz = "); Serial.print( gz, 2); Serial.println(" deg/s"); Serial.print("mx = "); Serial.print( (int)mx ); Serial.print(" my = "); Serial.print( (int)my ); Serial.print(" mz = "); Serial.print( (int)mz ); Serial.println(" mG");

Serial.print("q0 = "); Serial.print(q[0]); Serial.print(" qx = "); Serial.print(q[1]); Serial.print(" qy = "); Serial.print(q[2]); Serial.print(" qz = "); Serial.println(q[3]);

temperature = ((float) MPU9250Data[3]) / 333.87f + 21.0f; // Gyro chip temperature in degrees Centigrade // Print temperature in degrees Centigrade Serial.print("Gyro temperature is "); Serial.print(temperature, 1); Serial.println(" degrees C"); // Print T values to tenths of s degree C }

a12 = 2.0f (q[1] q[2] + q[0] q[3]); a22 = q[0] q[0] + q[1] q[1] - q[2] q[2] - q[3] q[3]; a31 = 2.0f (q[0] q[1] + q[2] q[3]); a32 = 2.0f (q[1] q[3] - q[0] q[2]); a33 = q[0] q[0] - q[1] q[1] - q[2] q[2] + q[3] q[3]; pitch = -asinf(a32); roll = atan2f(a31, a33); yaw = atan2f(a12, a22); pitch = 180.0f / pi; yaw = 180.0f / pi; yaw += 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04 if(yaw < 0) yaw += 360.0f; // Ensure yaw stays between 0 and 360 roll = 180.0f / pi; lin_ax = ax + a31; lin_ay = ay + a32; lin_az = az - a33;

if(SerialDebug) { Serial.print("Yaw, Pitch, Roll: "); Serial.print(yaw, 2); Serial.print(", "); Serial.print(pitch, 2); Serial.print(", "); Serial.println(roll, 2);

Serial.print("Grav_x, Grav_y, Grav_z: "); Serial.print(-a311000.0f, 2); Serial.print(", "); Serial.print(-a321000.0f, 2); Serial.print(", "); Serial.print(a331000.0f, 2); Serial.println(" mg"); Serial.print("Lin_ax, Lin_ay, Lin_az: "); Serial.print(lin_ax1000.0f, 2); Serial.print(", "); Serial.print(lin_ay1000.0f, 2); Serial.print(", "); Serial.print(lin_az1000.0f, 2); Serial.println(" mg");

Serial.print("rate = "); Serial.print((float)sumCount/sum, 2); Serial.println(" Hz"); sumCount = 0; sum = 0; delay(2000); }

}

//=================================================================================================================== //====== Set of useful functions

//===================================================================================================================

void myinthandler() { intFlag = true; }

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-643528373, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKUHCGHZWF53SRNRKPLRWK7ZDANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

When I leave intflag = false in there it never loops through and keeps spitting out the same data over and over

kriswiner commented 4 years ago

Then you are never getting an interrupt. Is pin 9 an interrupt pin on your MCU?

On Fri, Jun 12, 2020 at 5:20 PM beaumr2 notifications@github.com wrote:

When I leave intflag = false in there it never loops through and keeps spitting out the same data over and over

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-643530025, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKWS2TS3VYYCXSP4AF3RWLA6PANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

Honestly I don't understand the concept of an interrupt. I googled it and it said pin 2 was my interrupt. So I can change that in the code. Does pin 2 have to be wired to something on the MPU9250?

beaumr2 commented 4 years ago

Ah I connected it to the int pin on the MPU. Hold on

beaumr2 commented 4 years ago

Thank you for being patient with my stupidity. Let's try to start over. I pulled your exact code and just changed my intPin, date, and time. I believe there is still a problem as it never gets into this if statement:

if(alarmFlag) { // update RTC output (serial display) whenever the RTC alarm condition is achieved  
   alarmFlag = false;

Everything up to that point seems alright. If I comment out that if statement it gives me a slew of data that is still not accurate. I'll repost the full code but like I said it should be nearly exactly yours

/* 07/6/2017 Copyright Tlera Corporation

include "Wire.h"

include "MPU9250.h"

include "RTC.h"

define SerialDebug true // set to true to get Serial output for debugging

// RTC set time using STM32L4 natve RTC class / Change these values to set the current initial time / const uint8_t seconds = 30; const uint8_t minutes = 40; const uint8_t hours = 17;

/ Change these values to set the current initial date / const uint8_t day = 12; const uint8_t month = 6; const uint8_t year = 20;

uint8_t Seconds, Minutes, Hours, Day, Month, Year;

bool alarmFlag = false; // for RTC alarm interrupt

// MPU9250 Configuration // Specify sensor full scale /* Choices are:

// Pin definitions int intPin = 2; // MPU9250 interrupt int myLed = 13; // red led

bool intFlag = true; bool newMagData = false;

int16_t MPU9250Data[7]; // used to read all 14 bytes at once from the MPU9250 accel/gyro int16_t magCount[3]; // Stores the 16-bit signed magnetometer sensor output float magCalibration[3] = {0, 0, 0}; // Factory mag calibration and mag bias float temperature; // Stores the MPU9250 internal chip temperature in degrees Celsius float SelfTest[6]; // holds results of gyro and accelerometer self test

// These can be measured once and entered here or can be calculated each time the device is powered on float gyroBias[3] = {0.96, -0.21, 0.12}, accelBias[3] = {0.00299, -0.00916, 0.00952}; float magBias[3] = {71.04, 122.43, -36.90}, magScale[3] = {1.01, 1.03, 0.96}; // Bias corrections for gyro and accelerometer

uint32_t delt_t = 0; // used to control display output rate uint32_t count = 0, sumCount = 0; // used to control display output rate float pitch, yaw, roll; // absolute orientation float a12, a22, a31, a32, a33; // rotation matrix coefficients for Euler angles and gravity components float deltat = 0.0f, sum = 0.0f; // integration interval for both filter schemes uint32_t lastUpdate = 0, firstUpdate = 0; // used to calculate integration interval uint32_t Now = 0; // used to calculate integration interval

float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values float lin_ax, lin_ay, lin_az; // linear acceleration (acceleration with gravity component subtracted) float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion float eInt[3] = {0.0f, 0.0f, 0.0f}; // vector to hold integral error for Mahony method

MPU9250 MPU9250(intPin); // instantiate MPU9250 class

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

Wire.begin(); // set master mode, default on SDA/SCL for Ladybug
Wire.setClock(400000); // I2C frequency at 400 kHz delay(1000);

MPU9250.I2Cscan(); // should detect BME280 at 0x77, MPU9250 at 0x71

// Set up the interrupt pin, it's set as active high, push-pull pinMode(myLed, OUTPUT); digitalWrite(myLed, HIGH); // start with orange led on (active HIGH)

pinMode(intPin, INPUT);

/ Configure the MPU9250 / // Read the WHO_AM_I register, this is a good test of communication Serial.println("MPU9250 9-axis motion sensor..."); uint8_t c = MPU9250.getMPU9250ID(); Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX); Serial.print(" I should be "); Serial.println(0x71, HEX); delay(1000);

if (c == 0x71 ) // WHO_AM_I should always be 0x71 for MPU9250, 0x73 for MPU9255 {
Serial.println("MPU9250 is online...");

MPU9250.resetMPU9250(); // start by resetting MPU9250

MPU9250.SelfTest(SelfTest); // Start by performing self test and reporting values
Serial.print("x-axis self test: acceleration trim within : "); Serial.print(SelfTest[0],1); Serial.println("% of factory value");
Serial.print("y-axis self test: acceleration trim within : "); Serial.print(SelfTest[1],1); Serial.println("% of factory value");
Serial.print("z-axis self test: acceleration trim within : "); Serial.print(SelfTest[2],1); Serial.println("% of factory value");
Serial.print("x-axis self test: gyration trim within : "); Serial.print(SelfTest[3],1); Serial.println("% of factory value");
Serial.print("y-axis self test: gyration trim within : "); Serial.print(SelfTest[4],1); Serial.println("% of factory value");
Serial.print("z-axis self test: gyration trim within : "); Serial.print(SelfTest[5],1); Serial.println("% of factory value");
delay(1000);

// get sensor resolutions, only need to do this once aRes = MPU9250.getAres(Ascale); gRes = MPU9250.getGres(Gscale); mRes = MPU9250.getMres(Mscale);

// Comment out if using pre-measured, pre-stored offset biases MPU9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers Serial.println("accel biases (mg)"); Serial.println(1000.accelBias[0]); Serial.println(1000.accelBias[1]); Serial.println(1000.*accelBias[2]); Serial.println("gyro biases (dps)"); Serial.println(gyroBias[0]); Serial.println(gyroBias[1]); Serial.println(gyroBias[2]); delay(1000);

MPU9250.initMPU9250(Ascale, Gscale, sampleRate); Serial.println("MPU9250 initialized for active data mode...."); // Initialize device for active mode read of acclerometer, gyroscope, and temperature

// Read the WHO_AM_I register of the magnetometer, this is a good test of communication byte d = MPU9250.getAK8963CID(); // Read WHO_AM_I register for AK8963 Serial.print("AK8963 "); Serial.print("I AM "); Serial.print(d, HEX); Serial.print(" I should be "); Serial.println(0x48, HEX); delay(1000);

// Get magnetometer calibration from AK8963 ROM MPU9250.initAK8963Slave(Mscale, Mmode, magCalibration); Serial.println("AK8963 initialized for active data mode...."); // Initialize device for active mode read of magnetometer

// Comment out if using pre-measured, pre-stored offset biases // MPU9250.magcalMPU9250(magBias, magScale); Serial.println("AK8963 mag biases (mG)"); Serial.println(magBias[0]); Serial.println(magBias[1]); Serial.println(magBias[2]); Serial.println("AK8963 mag scale (mG)"); Serial.println(magScale[0]); Serial.println(magScale[1]); Serial.println(magScale[2]); delay(2000); // add delay to see results before serial spew of data

if(SerialDebug) { Serial.println("Calibration values: "); Serial.print("X-Axis sensitivity adjustment value "); Serial.println(magCalibration[0], 2); Serial.print("Y-Axis sensitivity adjustment value "); Serial.println(magCalibration[1], 2); Serial.print("Z-Axis sensitivity adjustment value "); Serial.println(magCalibration[2], 2);

attachInterrupt(intPin, myinthandler, RISING); // define interrupt for intPin output of MPU9250 }

} else { Serial.print("Could not connect to MPU9250: 0x"); Serial.println(c, HEX); while(1) ; // Loop forever if communication doesn't happen }

}

void loop() {
// If intPin goes high, either all data registers have new data if(intFlag == true) { // On interrupt, read data intFlag = false; // reset newData flag

 MPU9250.readMPU9250Data(MPU9250Data); // INT cleared on any read

// Now we'll calculate the accleration value into actual g's
 ax = (float)MPU9250Data[0]*aRes - accelBias[0];  // get actual g value, this depends on scale being set
 ay = (float)MPU9250Data[1]*aRes - accelBias[1];   
 az = (float)MPU9250Data[2]*aRes - accelBias[2];  

// Calculate the gyro value into actual degrees per second
 gx = (float)MPU9250Data[4]*gRes;  // get actual gyro value, this depends on scale being set
 gy = (float)MPU9250Data[5]*gRes;  
 gz = (float)MPU9250Data[6]*gRes; 

// if( MPU9250.checkNewMagData() == true) { // wait for magnetometer data ready bit to be set MPU9250.readMagData(magCount); // Read the x/y/z adc values

// Calculate the magnetometer values in milliGauss
// Include factory calibration per data sheet and user environmental corrections
  mx = (float)magCount[0]*mRes*magCalibration[0] - magBias[0];  // get actual magnetometer value, this depends on scale being set
  my = (float)magCount[1]*mRes*magCalibration[1] - magBias[1];  
  mz = (float)magCount[2]*mRes*magCalibration[2] - magBias[2];  
  mx *= magScale[0];
  my *= magScale[1];
  mz *= magScale[2]; 

// }

for(uint8_t i = 0; i < 10; i++) { // iterate a fixed number of times per data read cycle
Now = micros();
deltat = ((Now - lastUpdate)/1000000.0f); // set integration time by time elapsed since last filter update
lastUpdate = Now;

sum += deltat; // sum for averaging filter update rate
sumCount++;

MadgwickQuaternionUpdate(-ax, +ay, +az, gx*pi/180.0f, -gy*pi/180.0f, -gz*pi/180.0f,  my,  -mx, mz);
}

/* end of MPU9250 interrupt handling */

}

if(alarmFlag) { // update RTC output (serial display) whenever the RTC alarm condition is achieved  
   alarmFlag = false;

if(SerialDebug) {
Serial.print("ax = "); Serial.print((int)1000*ax);  
Serial.print(" ay = "); Serial.print((int)1000*ay); 
Serial.print(" az = "); Serial.print((int)1000*az); Serial.println(" mg");
Serial.print("gx = "); Serial.print( gx, 2); 
Serial.print(" gy = "); Serial.print( gy, 2); 
Serial.print(" gz = "); Serial.print( gz, 2); Serial.println(" deg/s");
Serial.print("mx = "); Serial.print( (int)mx ); 
Serial.print(" my = "); Serial.print( (int)my ); 
Serial.print(" mz = "); Serial.print( (int)mz ); Serial.println(" mG");

Serial.print("q0 = "); Serial.print(q[0]);
Serial.print(" qx = "); Serial.print(q[1]); 
Serial.print(" qy = "); Serial.print(q[2]); 
Serial.print(" qz = "); Serial.println(q[3]); 

temperature = ((float) MPU9250Data[3]) / 333.87f + 21.0f; // Gyro chip temperature in degrees Centigrade
// Print temperature in degrees Centigrade      
Serial.print("Gyro temperature is ");  Serial.print(temperature, 1);  Serial.println(" degrees C"); // Print T values to tenths of s degree C
}               

a12 =   2.0f * (q[1] * q[2] + q[0] * q[3]);
a22 =   q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3];
a31 =   2.0f * (q[0] * q[1] + q[2] * q[3]);
a32 =   2.0f * (q[1] * q[3] - q[0] * q[2]);
a33 =   q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
pitch = -asinf(a32);
roll  = atan2f(a31, a33);
yaw   = atan2f(a12, a22);
pitch *= 180.0f / pi;
yaw   *= 180.0f / pi; 
yaw   += 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04
if(yaw < 0) yaw   += 360.0f; // Ensure yaw stays between 0 and 360
roll  *= 180.0f / pi;
lin_ax = ax + a31;
lin_ay = ay + a32;
lin_az = az - a33;

if(SerialDebug) {
Serial.print("Yaw, Pitch, Roll: ");
Serial.print(yaw, 2);
Serial.print(", ");
Serial.print(pitch, 2);
Serial.print(", ");
Serial.println(roll, 2);

Serial.print("Grav_x, Grav_y, Grav_z: ");
Serial.print(-a31*1000.0f, 2);
Serial.print(", ");
Serial.print(-a32*1000.0f, 2);
Serial.print(", ");
Serial.print(a33*1000.0f, 2);  Serial.println(" mg");
Serial.print("Lin_ax, Lin_ay, Lin_az: ");
Serial.print(lin_ax*1000.0f, 2);
Serial.print(", ");
Serial.print(lin_ay*1000.0f, 2);
Serial.print(", ");
Serial.print(lin_az*1000.0f, 2);  Serial.println(" mg");

Serial.print("rate = "); Serial.print((float)sumCount/sum, 2); Serial.println(" Hz");
sumCount = 0;
sum = 0;    
}

} / end of alarm handling /

}

//=================================================================================================================== //====== Set of useful functions //===================================================================================================================

void myinthandler() { intFlag = true; }

void alarmMatch() { alarmFlag = true; }

kriswiner commented 4 years ago

Does your Uno have an RTC?

On Fri, Jun 12, 2020 at 5:51 PM beaumr2 notifications@github.com wrote:

Thank you for being patient with my stupidity. Let's try to start over. I pulled your exact code and just changed my intPin, date, and time. I believe there is still a problem as it never gets into this if statement:

if(alarmFlag) { // update RTC output (serial display) whenever the RTC alarm condition is achieved alarmFlag = false;

Everything up to that point seems alright. If I comment out that if statement it gives me a slew of data that is still not accurate. I'll repost the full code but like I said it should be nearly exactly yours

/ 07/6/2017 Copyright Tlera Corporation

  • Created by Kris Winer

Demonstrate basic MPU-9250 functionality including parameterizing the register addresses, initializing the sensor, getting properly scaled accelerometer, gyroscope, and magnetometer data out. Addition of 9 DoF sensor fusion using open source Madgwick and Mahony filter algorithms. Sketch runs on the 3.3 V Dragonfly STM32L476 Breakout Board.

The BME280 is a simple but high resolution pressure/humidity/temperature sensor, which can be used in its high resolution mode but with power consumption of 20 microAmp, or in a lower resolution mode with power consumption of only 1 microAmp. The choice will depend on the application.

SDA and SCL have 4K7 pull-up resistors (to 3.3V).

Library may be used freely and without limit with attribution. */

include "Wire.h"

include "MPU9250.h"

include "RTC.h"

define SerialDebug true // set to true to get Serial output for debugging

// RTC set time using STM32L4 natve RTC class / Change these values to set the current initial time / const uint8_t seconds = 30; const uint8_t minutes = 40; const uint8_t hours = 17;

/ Change these values to set the current initial date / const uint8_t day = 12; const uint8_t month = 6; const uint8_t year = 20;

uint8_t Seconds, Minutes, Hours, Day, Month, Year;

bool alarmFlag = false; // for RTC alarm interrupt

// MPU9250 Configuration // Specify sensor full scale /* Choices are:

  • Gscale: GFS_250 == 250 dps, GFS_500 DPS == 500 dps, GFS_1000 == 1000 dps, and GFS_2000DPS == 2000 degrees per second gyro full scale
  • Ascale: AFS_2G == 2 g, AFS_4G == 4 g, AFS_8G == 8 g, and AFS_16G == 16 g accelerometer full scale
  • Mscale: MFS_14BITS == 0.6 mG per LSB and MFS_16BITS == 0.15 mG per LSB
  • Mmode: Mmode == M_8Hz for 8 Hz data rate or Mmode = M_100Hz for 100 Hz data rate
  • (1 + sampleRate) is a simple divisor of the fundamental 1000 kHz rate of the gyro and accel, so
  • sampleRate = 0x00 means 1 kHz sample rate for both accel and gyro, 0x04 means 200 Hz, etc. / uint8_t Gscale = GFS_250DPS, Ascale = AFS_2G, Mscale = MFS_16BITS, Mmode = M_100Hz, sampleRate = 0x04; float aRes, gRes, mRes; // scale resolutions per LSB for the sensors float motion = 0; // check on linear acceleration to determine motion // global constants for 9 DoF fusion and AHRS (Attitude and Heading Reference System) float pi = 3.141592653589793238462643383279502884f; float GyroMeasError = pi (40.0f / 180.0f); // gyroscope measurement error in rads/s (start at 40 deg/s) float GyroMeasDrift = pi (0.0f / 180.0f); // gyroscope measurement drift in rad/s/s (start at 0.0 deg/s/s) float beta = sqrtf(3.0f / 4.0f) GyroMeasError; // compute beta float zeta = sqrtf(3.0f / 4.0f) * GyroMeasDrift; // compute zeta, the other free parameter in the Madgwick scheme usually set to a small or zero value bool wakeup;

// Pin definitions int intPin = 2; // MPU9250 interrupt int myLed = 13; // red led

bool intFlag = true; bool newMagData = false;

int16_t MPU9250Data[7]; // used to read all 14 bytes at once from the MPU9250 accel/gyro int16_t magCount[3]; // Stores the 16-bit signed magnetometer sensor output float magCalibration[3] = {0, 0, 0}; // Factory mag calibration and mag bias float temperature; // Stores the MPU9250 internal chip temperature in degrees Celsius float SelfTest[6]; // holds results of gyro and accelerometer self test

// These can be measured once and entered here or can be calculated each time the device is powered on float gyroBias[3] = {0.96, -0.21, 0.12}, accelBias[3] = {0.00299, -0.00916, 0.00952}; float magBias[3] = {71.04, 122.43, -36.90}, magScale[3] = {1.01, 1.03, 0.96}; // Bias corrections for gyro and accelerometer

uint32_t delt_t = 0; // used to control display output rate uint32_t count = 0, sumCount = 0; // used to control display output rate float pitch, yaw, roll; // absolute orientation float a12, a22, a31, a32, a33; // rotation matrix coefficients for Euler angles and gravity components float deltat = 0.0f, sum = 0.0f; // integration interval for both filter schemes uint32_t lastUpdate = 0, firstUpdate = 0; // used to calculate integration interval uint32_t Now = 0; // used to calculate integration interval

float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values float lin_ax, lin_ay, lin_az; // linear acceleration (acceleration with gravity component subtracted) float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion float eInt[3] = {0.0f, 0.0f, 0.0f}; // vector to hold integral error for Mahony method

MPU9250 MPU9250(intPin); // instantiate MPU9250 class

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

Wire.begin(); // set master mode, default on SDA/SCL for Ladybug Wire.setClock(400000); // I2C frequency at 400 kHz delay(1000);

MPU9250.I2Cscan(); // should detect BME280 at 0x77, MPU9250 at 0x71

// Set up the interrupt pin, it's set as active high, push-pull pinMode(myLed, OUTPUT); digitalWrite(myLed, HIGH); // start with orange led on (active HIGH)

pinMode(intPin, INPUT);

/ Configure the MPU9250 / // Read the WHO_AM_I register, this is a good test of communication Serial.println("MPU9250 9-axis motion sensor..."); uint8_t c = MPU9250.getMPU9250ID(); Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX); Serial.print(" I should be "); Serial.println(0x71, HEX); delay(1000);

if (c == 0x71 ) // WHO_AM_I should always be 0x71 for MPU9250, 0x73 for MPU9255 { Serial.println("MPU9250 is online...");

MPU9250.resetMPU9250(); // start by resetting MPU9250

MPU9250.SelfTest(SelfTest); // Start by performing self test and reporting values Serial.print("x-axis self test: acceleration trim within : "); Serial.print(SelfTest[0],1); Serial.println("% of factory value"); Serial.print("y-axis self test: acceleration trim within : "); Serial.print(SelfTest[1],1); Serial.println("% of factory value"); Serial.print("z-axis self test: acceleration trim within : "); Serial.print(SelfTest[2],1); Serial.println("% of factory value"); Serial.print("x-axis self test: gyration trim within : "); Serial.print(SelfTest[3],1); Serial.println("% of factory value"); Serial.print("y-axis self test: gyration trim within : "); Serial.print(SelfTest[4],1); Serial.println("% of factory value"); Serial.print("z-axis self test: gyration trim within : "); Serial.print(SelfTest[5],1); Serial.println("% of factory value"); delay(1000);

// get sensor resolutions, only need to do this once aRes = MPU9250.getAres(Ascale); gRes = MPU9250.getGres(Gscale); mRes = MPU9250.getMres(Mscale);

// Comment out if using pre-measured, pre-stored offset biases MPU9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers Serial.println("accel biases (mg)"); Serial.println(1000.accelBias[0]); Serial.println(1000.accelBias[1]); Serial.println(1000.*accelBias[2]); Serial.println("gyro biases (dps)"); Serial.println(gyroBias[0]); Serial.println(gyroBias[1]); Serial.println(gyroBias[2]); delay(1000);

MPU9250.initMPU9250(Ascale, Gscale, sampleRate); Serial.println("MPU9250 initialized for active data mode...."); // Initialize device for active mode read of acclerometer, gyroscope, and temperature

// Read the WHO_AM_I register of the magnetometer, this is a good test of communication byte d = MPU9250.getAK8963CID(); // Read WHO_AM_I register for AK8963 Serial.print("AK8963 "); Serial.print("I AM "); Serial.print(d, HEX); Serial.print(" I should be "); Serial.println(0x48, HEX); delay(1000);

// Get magnetometer calibration from AK8963 ROM MPU9250.initAK8963Slave(Mscale, Mmode, magCalibration); Serial.println("AK8963 initialized for active data mode...."); // Initialize device for active mode read of magnetometer

// Comment out if using pre-measured, pre-stored offset biases // MPU9250.magcalMPU9250(magBias, magScale); Serial.println("AK8963 mag biases (mG)"); Serial.println(magBias[0]); Serial.println(magBias[1]); Serial.println(magBias[2]); Serial.println("AK8963 mag scale (mG)"); Serial.println(magScale[0]); Serial.println(magScale[1]); Serial.println(magScale[2]); delay(2000); // add delay to see results before serial spew of data

if(SerialDebug) { Serial.println("Calibration values: "); Serial.print("X-Axis sensitivity adjustment value "); Serial.println(magCalibration[0], 2); Serial.print("Y-Axis sensitivity adjustment value "); Serial.println(magCalibration[1], 2); Serial.print("Z-Axis sensitivity adjustment value "); Serial.println(magCalibration[2], 2);

attachInterrupt(intPin, myinthandler, RISING); // define interrupt for intPin output of MPU9250 }

} else { Serial.print("Could not connect to MPU9250: 0x"); Serial.println(c, HEX); while(1) ; // Loop forever if communication doesn't happen }

}

void loop() { // If intPin goes high, either all data registers have new data if(intFlag == true) { // On interrupt, read data intFlag = false; // reset newData flag

MPU9250.readMPU9250Data(MPU9250Data); // INT cleared on any read

// Now we'll calculate the accleration value into actual g's ax = (float)MPU9250Data[0]aRes - accelBias[0]; // get actual g value, this depends on scale being set ay = (float)MPU9250Data[1]aRes - accelBias[1]; az = (float)MPU9250Data[2]*aRes - accelBias[2];

// Calculate the gyro value into actual degrees per second gx = (float)MPU9250Data[4]gRes; // get actual gyro value, this depends on scale being set gy = (float)MPU9250Data[5]gRes; gz = (float)MPU9250Data[6]*gRes;

// if( MPU9250.checkNewMagData() == true) { // wait for magnetometer data ready bit to be set MPU9250.readMagData(magCount); // Read the x/y/z adc values

// Calculate the magnetometer values in milliGauss // Include factory calibration per data sheet and user environmental corrections mx = (float)magCount[0]mResmagCalibration[0] - magBias[0]; // get actual magnetometer value, this depends on scale being set my = (float)magCount[1]mResmagCalibration[1] - magBias[1]; mz = (float)magCount[2]mResmagCalibration[2] - magBias[2]; mx = magScale[0]; my = magScale[1]; mz *= magScale[2];

// }

for(uint8_t i = 0; i < 10; i++) { // iterate a fixed number of times per data read cycle Now = micros(); deltat = ((Now - lastUpdate)/1000000.0f); // set integration time by time elapsed since last filter update lastUpdate = Now;

sum += deltat; // sum for averaging filter update rate sumCount++;

MadgwickQuaternionUpdate(-ax, +ay, +az, gxpi/180.0f, -gypi/180.0f, -gz*pi/180.0f, my, -mx, mz); }

/ end of MPU9250 interrupt handling /

}

if(alarmFlag) { // update RTC output (serial display) whenever the RTC alarm condition is achieved alarmFlag = false;

if(SerialDebug) { Serial.print("ax = "); Serial.print((int)1000ax); Serial.print(" ay = "); Serial.print((int)1000ay); Serial.print(" az = "); Serial.print((int)1000*az); Serial.println(" mg"); Serial.print("gx = "); Serial.print( gx, 2); Serial.print(" gy = "); Serial.print( gy, 2); Serial.print(" gz = "); Serial.print( gz, 2); Serial.println(" deg/s"); Serial.print("mx = "); Serial.print( (int)mx ); Serial.print(" my = "); Serial.print( (int)my ); Serial.print(" mz = "); Serial.print( (int)mz ); Serial.println(" mG");

Serial.print("q0 = "); Serial.print(q[0]); Serial.print(" qx = "); Serial.print(q[1]); Serial.print(" qy = "); Serial.print(q[2]); Serial.print(" qz = "); Serial.println(q[3]);

temperature = ((float) MPU9250Data[3]) / 333.87f + 21.0f; // Gyro chip temperature in degrees Centigrade // Print temperature in degrees Centigrade Serial.print("Gyro temperature is "); Serial.print(temperature, 1); Serial.println(" degrees C"); // Print T values to tenths of s degree C }

a12 = 2.0f (q[1] q[2] + q[0] q[3]); a22 = q[0] q[0] + q[1] q[1] - q[2] q[2] - q[3] q[3]; a31 = 2.0f (q[0] q[1] + q[2] q[3]); a32 = 2.0f (q[1] q[3] - q[0] q[2]); a33 = q[0] q[0] - q[1] q[1] - q[2] q[2] + q[3] q[3]; pitch = -asinf(a32); roll = atan2f(a31, a33); yaw = atan2f(a12, a22); pitch = 180.0f / pi; yaw = 180.0f / pi; yaw += 13.8f; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04 if(yaw < 0) yaw += 360.0f; // Ensure yaw stays between 0 and 360 roll = 180.0f / pi; lin_ax = ax + a31; lin_ay = ay + a32; lin_az = az - a33;

if(SerialDebug) { Serial.print("Yaw, Pitch, Roll: "); Serial.print(yaw, 2); Serial.print(", "); Serial.print(pitch, 2); Serial.print(", "); Serial.println(roll, 2);

Serial.print("Grav_x, Grav_y, Grav_z: "); Serial.print(-a311000.0f, 2); Serial.print(", "); Serial.print(-a321000.0f, 2); Serial.print(", "); Serial.print(a331000.0f, 2); Serial.println(" mg"); Serial.print("Lin_ax, Lin_ay, Lin_az: "); Serial.print(lin_ax1000.0f, 2); Serial.print(", "); Serial.print(lin_ay1000.0f, 2); Serial.print(", "); Serial.print(lin_az1000.0f, 2); Serial.println(" mg");

Serial.print("rate = "); Serial.print((float)sumCount/sum, 2); Serial.println(" Hz"); sumCount = 0; sum = 0; }

} / end of alarm handling /

}

//=================================================================================================================== //====== Set of useful functions

//===================================================================================================================

void myinthandler() { intFlag = true; }

void alarmMatch() { alarmFlag = true; }

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-643544237, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKUMKR7RDEN3TQUVG2DRWLESRANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

No it does not. I see the problem now. What MCU do you use? I'll buy that one unless there's an easy workaround for the RTC code

kriswiner commented 4 years ago

You need something better than an Uno anyway if you have any hope of sensor fusion rates fast enough for accuracy. Cheap, go with this https://www.tindie.com/products/tleracorp/ladybug-stm32l432-development-board/. But I would recommend this https://www.tindie.com/products/tleracorp/dragonfly-stm32l47696-development-board/ .

Both open source so easy to customize, both programmable using the Arduino IDE via USB.

On Fri, Jun 12, 2020 at 5:58 PM beaumr2 notifications@github.com wrote:

No it does not. I see the problem now. What MCU do you use? I'll buy that one unless there's an easy workaround for the RTC code

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-643545210, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKTVO4VQJYWCJ45IT6TRWLFM5ANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

Thank you I just placed an order for both. I will update you when I get the boards. Thanks again!

beaumr2 commented 4 years ago

So I'm now using that Dragonfly STM32L47696 Board and using Pin 9 as the interrupt and having the same issue. The RTC flag isn't changing to true. I have input my current date and time

kriswiner commented 4 years ago

" and having the same issue"

remind me what the issue is?

On Wed, Jun 17, 2020 at 6:13 PM beaumr2 notifications@github.com wrote:

So I'm now using that Dragonfly STM32L47696 Board and using Pin 9 as the interrupt and having the same issue. The RTC flag isn't changing to true. I have input my current date and time

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-645709619, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKUD6G3VNBAGM7R5RULRXFS4XANCNFSM4N4V4CIQ .

kriswiner commented 4 years ago

Since you have a Dragonfly, try this:

https://github.com/kriswiner/Dragonfly/blob/master/MPU9250Optimized/MPU9250BasicAHRS3_Dragonfly.ino

On Wed, Jun 17, 2020 at 6:19 PM Tlera Corporation tleracorp@gmail.com wrote:

" and having the same issue"

remind me what the issue is?

On Wed, Jun 17, 2020 at 6:13 PM beaumr2 notifications@github.com wrote:

So I'm now using that Dragonfly STM32L47696 Board and using Pin 9 as the interrupt and having the same issue. The RTC flag isn't changing to true. I have input my current date and time

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-645709619, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKUD6G3VNBAGM7R5RULRXFS4XANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

So I downloaded that and get a new error: exit status 1 no matching function for call to 'TwoWireEx::begin(int, int, bool)'

Weirdly it highlights this line of code: Wire.begin(0, 400000, true); // set master mode, I2C frequncy at 400 kHz delay(1000);

I put the Wire folder in with your Dragonfly-Master. Is there a folder called TwoWireEx I need?

beaumr2 commented 4 years ago

I see the TwoWireEx in GrumpyOldPizza's Wire.cpp file. I downloaded the board from here:

https://github.com/GrumpyOldPizza/arduino-STM32L4

I'm thinking there's been an update that no longer likes his code for TwoWireEx::begin

kriswiner commented 4 years ago

This looks like an old context for Wire, try this instead:

Wire.begin(TWI_PINS_20_21); // set master mode Wire.setClock(400000); // I2C frequency at 400 kHz

On Wed, Jun 17, 2020 at 7:13 PM beaumr2 notifications@github.com wrote:

I see the TwoWireEx in GrumpyOldPizza's Wire.cpp file. I downloaded the board from here:

https://github.com/GrumpyOldPizza/arduino-STM32L4

I'm thinking there's been an update that no longer likes his code for TwoWireEx::begin

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-645726821, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKRWAENSZEXXPYJ4P3TRXFZ5FANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

Okay and that seems to work. Does this wiring sound good:

3V3->VCC GND->GND SDA->SDA SCL->SCL 9->INT this is the one I'm really asking about. Based on your link here: https://github.com/kriswiner/Dragonfly or do I have to solder a wire to the back pad 41 that is INT? Then I might as well also solder to SDA and SCL

kriswiner commented 4 years ago

I usually use pins 20 and 21 for I2C (SDA and SCL). You can use any other pins for the interrupt. 8, 9, 10 are convenient but any pin will do. I wouldn;t solder anything until you are sure everything is working as it should.

Just make sure whichever pin you select as interrupt is specified in the sketch.

[image: image.png]

On Wed, Jun 17, 2020 at 7:41 PM beaumr2 notifications@github.com wrote:

Okay and that seems to work. Does this wiring sound good:

3V3->VCC GND->GND SDA->SDA SCL->SCL 9->INT this is the one I'm really asking about. Based on your link here: https://github.com/kriswiner/Dragonfly or do I have to solder a wire to the back pad 41 that is INT? Then I might as well also solder to SDA and SCL

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-645734950, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKVMZWTUIDB2OQSLM3TRXF5EHANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

So many issues... didn't even get to test it. I had no serial port showing up even though it still showed with my Arduino Uno. Now when I plug in the Dragonfly STM32L476 the light on it doesn't even come one

kriswiner commented 4 years ago

Is there a problem with your USB cable then? Do you have a multimeter? Can you verify that there is 3V3 on the board?

If there is no power issue, close the Arduino IDE, plug in the USB cable, press and hold boot, press and release reset, release boot. Then open the Arduino IDE, select the proper board variant and flash a known good program. This recovery procedure will fix problems usually due to trying to flash with the wrong board variant selected.

What I don;t understand is I thought you said it was working, and now it is totally fubared. What happened in between?

On Thu, Jun 18, 2020 at 8:16 AM beaumr2 notifications@github.com wrote:

So many issues... didn't even get to test it. I had no serial port showing up even though it still showed with my Arduino Uno. Now when I plug in the Dragonfly STM32L476 the light on it doesn't even come one

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-646087734, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKTC6IXEOWD2ES2N2RTRXIVTHANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

It was working originally and then all of a sudden the port for it disappeared. I tried multiple USB cables and even plugged it into the wall and it doesn't light up. But I used a multimeter to the ground and 3.3V and measured 3.3V so I guess it's working?

Did all that and still no serial port. Like I said the serial port just disappeared. I was trying to mess around with FTDI drivers and CH340 based on what I saw online but to be honest this stuff is over my head and I don't really understand it. I'm operating on OS X Catalina. I also plugged in my arduino Uno and it discovered that port just fine

kriswiner commented 4 years ago

Did you follow the reboot procedure I specified? Can you verify that the Dragonfly is in STM32 boot loader mode before flashing?

On Thu, Jun 18, 2020 at 8:38 AM beaumr2 notifications@github.com wrote:

It was working originally and then all of a sudden the port for it disappeared. I tried multiple USB cables and even plugged it into the wall and it doesn't light up. But I used a multimeter to the ground and 3.3V and measured 3.3V so I guess it's working?

Did all that and still no serial port. Like I said the serial port just disappeared. I was trying to mess around with FTDI drivers and CH340 based on what I saw online but to be honest this stuff is over my head and I don't really understand it. I'm operating on OS X Catalina. I also plugged in my arduino Uno and it discovered that port just fine

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-646105880, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKQLRVTUHUXZA3UVSLLRXIYF3ANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

Just got it to appear again by moving around my FTDIusbSerial.kext file. Uploaded code fine even though there is no light and I got a new prompt to wave the board in a figure 8 to calibrate the magnetometer. Can't really do that with how my wires are currently set up and I have to leave for work. Tonight or tomorrow I'll solder some and update you. Thanks for everything! (And yes I tried your method, the blink file uploaded and worked even without the Serial port being there)

kriswiner commented 4 years ago

FTDIusbSerial.kext file

Not sure what this is, a Mac thing?

On Thu, Jun 18, 2020 at 8:48 AM beaumr2 notifications@github.com wrote:

Just got it to appear again by moving around my FTDIusbSerial.kext file. Uploaded code fine even though there is no light and I got a new prompt to wave the board in a figure 8 to calibrate the magnetometer. Can't really do that with how my wires are currently set up and I have to leave for work. Tonight or tomorrow I'll solder some and update you. Thanks for everything! (And yes I tried your method, the blink file uploaded and worked even without the Serial port being there)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-646114341, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKVWTNIYBQPVWEZHISTRXIZNPANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

Yeah. And sorry I'm in the army and yesterday I got orders to move halfway across the country in <3 weeks. May be a little bit before I get back to this but I'll let you know when I do

beaumr2 commented 4 years ago

I got some free time and put it all together. Everything seems to be working! I do have some questions: what are my options as far as calibration goes? I'd like to not have to wave it in a figure eight to do the magnetic calibration every time I turn it on. I would like to permanently mount it in my vehicle. Maybe a way to save the calibration values?

kriswiner commented 4 years ago

Save them in the sketch or on emulated eeprom.

On Tue, Jun 30, 2020 at 2:06 PM beaumr2 notifications@github.com wrote:

I got some free time and put it all together. Everything seems to be working! I do have some questions: what are my options as far as calibration goes? I'd like to not have to wave it in a figure eight to do the magnetic calibration every time I turn it on. I would like to permanently mount it in my vehicle. Maybe a way to save the calibration values?

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-652043495, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKXQ7M3KHS7X62V5CRLRZJHUJANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

I think I finally got it all working. Now I have a new problem trying to run different code. I took some LCD display code from my Arduino Uno handbook. The LCD screen gets power but doesn't display anything. Does the liquid crystal library work with the dragonfly board? Or are the pins I'm choosing not digital outputs

Code:

include

LiquidCrystal lcd(8, 7, 5, 4, 3, 2);

const int switchPin = 6; int switchState = 0; int prevSwitchState = 0;

void setup() { lcd.begin(16, 2); pinMode(switchPin, INPUT);

}

void loop() { lcd.clear(); lcd.print("Pitch"); lcd.setCursor(0, 1); lcd.print("Roll"); switchState = digitalRead(switchPin); if (switchState != prevSwitchState) { if (switchState == LOW) { lcd.setCursor(0,0); lcd.print("Max values:"); lcd.setCursor(0,1); lcd.print("Pitch and roll"); delay(5000); } } prevSwitchState = switchState; }

beaumr2 commented 4 years ago

Or is it possible the LCD screen wants 5V and the dragonfly only provides 3.3V

kriswiner commented 4 years ago

I don't know the answer to your questions. I haven't used this display before. I have used TFT displays with success using Adafruit's graphics library

On Wed, Jul 22, 2020 at 1:22 PM beaumr2 notifications@github.com wrote:

Or is it possible the LCD screen wants 5V and the dragonfly only provides 3.3V

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-662676528, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKQVXAYGWMJQJJNMHNTR45DBZANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

Are pins 2-8 all digital output?

kriswiner commented 4 years ago

yes

On Wed, Jul 22, 2020 at 1:32 PM beaumr2 notifications@github.com wrote:

Are pins 2-8 all digital output?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-662681118, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKR5EPSZIA43USCMAKDR45EGTANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

And is there any way to get 5V from this board? I don't believe so based on the pinout I only see 3.3V

kriswiner commented 4 years ago

Dragonfly is 3v3.

On Thu, Jul 23, 2020 at 12:09 PM beaumr2 notifications@github.com wrote:

And is there any way to get 5V from this board? I don't believe so based on the pinout I only see 3.3V

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-663182007, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKRKJR6MCQWGBGM2XALR5CDEVANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

Okay thanks! I'll get a 3V LCD

beaumr2 commented 4 years ago

Is this a normal amount of variance? This is with the Dragonfly and MPU9250 totally still, seems like it's accurate to within ~8 degrees:

Pitch & Roll: 5.81, -0.66 Pitch & Roll: 5.10, 6.83 Pitch & Roll: -2.27, 0.69 Pitch & Roll: 5.57, -3.60 Pitch & Roll: 0.37, -1.00 Pitch & Roll: -0.41, 0.63 Pitch & Roll: -4.34, 3.57 Pitch & Roll: -2.13, 2.08 Pitch & Roll: 1.52, 1.44 Pitch & Roll: 4.12, -0.08 Pitch & Roll: -0.42, -0.82 Pitch & Roll: -0.59, -5.62 Pitch & Roll: 1.99, 0.90 Pitch & Roll: -3.62, -1.53 Pitch & Roll: -0.76, 1.97 Pitch & Roll: 1.04, 2.14 Pitch & Roll: -1.76, 1.12 Pitch & Roll: 1.46, 1.07 Pitch & Roll: 2.63, 3.01 Pitch & Roll: 2.31, 1.15 Pitch & Roll: 3.60, -0.02 Pitch & Roll: -1.72, 6.03 Pitch & Roll: -3.40, 1.09 Pitch & Roll: 0.49, 0.72 Pitch & Roll: 3.77, -0.80 Pitch & Roll: 1.62, -0.09 Pitch & Roll: 1.73, 0.76 Pitch & Roll: 0.12, 1.48

kriswiner commented 4 years ago

No. This is way bad.

How did you calibrate your accel and gyro? What sensor settings are you using?

On Wed, Aug 12, 2020 at 3:01 PM beaumr2 notifications@github.com wrote:

Is this a normal amount of variance? This is with the Dragonfly and MPU9250 totally still, seems like it's accurate to within ~8 degrees:

Pitch & Roll: 5.81, -0.66 Pitch & Roll: 5.10, 6.83 Pitch & Roll: -2.27, 0.69 Pitch & Roll: 5.57, -3.60 Pitch & Roll: 0.37, -1.00 Pitch & Roll: -0.41, 0.63 Pitch & Roll: -4.34, 3.57 Pitch & Roll: -2.13, 2.08 Pitch & Roll: 1.52, 1.44 Pitch & Roll: 4.12, -0.08 Pitch & Roll: -0.42, -0.82 Pitch & Roll: -0.59, -5.62 Pitch & Roll: 1.99, 0.90 Pitch & Roll: -3.62, -1.53 Pitch & Roll: -0.76, 1.97 Pitch & Roll: 1.04, 2.14 Pitch & Roll: -1.76, 1.12 Pitch & Roll: 1.46, 1.07 Pitch & Roll: 2.63, 3.01 Pitch & Roll: 2.31, 1.15 Pitch & Roll: 3.60, -0.02 Pitch & Roll: -1.72, 6.03 Pitch & Roll: -3.40, 1.09 Pitch & Roll: 0.49, 0.72 Pitch & Roll: 3.77, -0.80 Pitch & Roll: 1.62, -0.09 Pitch & Roll: 1.73, 0.76 Pitch & Roll: 0.12, 1.48

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-673132263, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKXYLVMFMTZVMT7V2A3SAMGMLANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

So I notice after leaving it still for a while (~5minutes) it becomes steady:

Pitch & Roll: 2.52, 176.42 Pitch & Roll: 2.52, 176.45 Pitch & Roll: 2.50, 176.42 Pitch & Roll: 2.44, 176.34 Pitch & Roll: 2.41, 176.32 Pitch & Roll: 2.53, 176.43 Pitch & Roll: 2.39, 176.28 Pitch & Roll: 2.59, 176.53 Pitch & Roll: 2.39, 176.27 Pitch & Roll: 2.44, 176.31 Pitch & Roll: 2.55, 176.45 Pitch & Roll: 2.56, 176.47 Pitch & Roll: 2.52, 176.40 Pitch & Roll: 2.43, 176.32 Pitch & Roll: 2.47, 176.37 Pitch & Roll: 2.56, 176.47 Pitch & Roll: 2.50, 176.38 Pitch & Roll: 2.63, 176.56 Pitch & Roll: 2.42, 176.31 Pitch & Roll: 2.41, 176.31 Pitch & Roll: 2.41, 176.30 Pitch & Roll: 2.43, 176.32 Pitch & Roll: 2.53, 176.40 Pitch & Roll: 2.58, 176.44 Pitch & Roll: 2.56, 176.39 Pitch & Roll: 2.67, 176.51 Pitch & Roll: 2.67, 176.51 Pitch & Roll: 2.54, 176.37 Pitch & Roll: 2.41, 176.22

It asks me to calibrate by waving in a circle. I found that not waving it actually gave it better results. Not sure what you mean by sensor setting

kriswiner commented 4 years ago

Sensor setting means full scale range, sample rate, bandwidth, etc.

Are you calibrating the gyro and accel? How?

On Wed, Aug 12, 2020 at 3:51 PM beaumr2 notifications@github.com wrote:

So I notice after leaving it still for a while (~5minutes) it becomes steady:

Pitch & Roll: 2.52, 176.42 Pitch & Roll: 2.52, 176.45 Pitch & Roll: 2.50, 176.42 Pitch & Roll: 2.44, 176.34 Pitch & Roll: 2.41, 176.32 Pitch & Roll: 2.53, 176.43 Pitch & Roll: 2.39, 176.28 Pitch & Roll: 2.59, 176.53 Pitch & Roll: 2.39, 176.27 Pitch & Roll: 2.44, 176.31 Pitch & Roll: 2.55, 176.45 Pitch & Roll: 2.56, 176.47 Pitch & Roll: 2.52, 176.40 Pitch & Roll: 2.43, 176.32 Pitch & Roll: 2.47, 176.37 Pitch & Roll: 2.56, 176.47 Pitch & Roll: 2.50, 176.38 Pitch & Roll: 2.63, 176.56 Pitch & Roll: 2.42, 176.31 Pitch & Roll: 2.41, 176.31 Pitch & Roll: 2.41, 176.30 Pitch & Roll: 2.43, 176.32 Pitch & Roll: 2.53, 176.40 Pitch & Roll: 2.58, 176.44 Pitch & Roll: 2.56, 176.39 Pitch & Roll: 2.67, 176.51 Pitch & Roll: 2.67, 176.51 Pitch & Roll: 2.54, 176.37 Pitch & Roll: 2.41, 176.22

It asks me to calibrate by waving in a circle. I found that not waving it actually gave it better results. Not sure what you mean by sensor setting

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-673148149, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKTO7NDWT36T2P3VEKLSAMMG5ANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

For sensor settings I'm using the following:

uint8_t Gscale = GFS_250DPS; uint8_t Ascale = AFS_2G; uint8_t Mscale = MFS_16BITS; // Choose either 14-bit or 16-bit magnetometer resolution uint8_t Mmode = 0x06; // 2 for 8 Hz, 6 for 100 Hz continuous magnetometer data read

To calibrate gyro and accel I'm using your calibrateMPU9250 function. I see this part of that function's code near the end is commented out. Should I uncomment it?

// Apparently this is not working for the acceleration biases in the MPU-9250 // Are we handling the temperature correction bit properly? // Push accelerometer biases to hardware registers // writeByte(MPU9250_ADDRESS, XA_OFFSET_H, data[0]); // writeByte(MPU9250_ADDRESS, XA_OFFSET_L, data[1]); // writeByte(MPU9250_ADDRESS, YA_OFFSET_H, data[2]); // writeByte(MPU9250_ADDRESS, YA_OFFSET_L, data[3]); // writeByte(MPU9250_ADDRESS, ZA_OFFSET_H, data[4]); // writeByte(MPU9250_ADDRESS, ZA_OFFSET_L, data[5]);

kriswiner commented 4 years ago

Seems fine.

How did you check the calibration?

What is your fusion rate?

On Thu, Aug 13, 2020 at 10:18 AM beaumr2 notifications@github.com wrote:

For sensor settings I'm using the following:

uint8_t Gscale = GFS_250DPS; uint8_t Ascale = AFS_2G; uint8_t Mscale = MFS_16BITS; // Choose either 14-bit or 16-bit magnetometer resolution uint8_t Mmode = 0x06; // 2 for 8 Hz, 6 for 100 Hz continuous magnetometer data read

To calibrate gyro and accel I'm using your calibrateMPU9250 function. I see this part of that function's code near the end is commented out. Should I uncomment it?

// Apparently this is not working for the acceleration biases in the MPU-9250 // Are we handling the temperature correction bit properly? // Push accelerometer biases to hardware registers // writeByte(MPU9250_ADDRESS, XA_OFFSET_H, data[0]); // writeByte(MPU9250_ADDRESS, XA_OFFSET_L, data[1]); // writeByte(MPU9250_ADDRESS, YA_OFFSET_H, data[2]); // writeByte(MPU9250_ADDRESS, YA_OFFSET_L, data[3]); // writeByte(MPU9250_ADDRESS, ZA_OFFSET_H, data[4]); // writeByte(MPU9250_ADDRESS, ZA_OFFSET_L, data[5]);

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-673602543, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKRBXF7GUZNEHFOAF7LSAQN4RANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

I did not check the calibration. What should those values be?

Also do not know what my fusion rate is or how to check that :/

kriswiner commented 4 years ago

Sketch should output the fusion rate.

accel should be 0.0, 0.0, 1000 millig to within a few millig

gyro should be 0.0, 0.0, 0.0 dps to within a few millidps when the device is flat and motionless...

On Thu, Aug 13, 2020 at 10:38 AM beaumr2 notifications@github.com wrote:

I did not check the calibration. What should those values be?

Also do not know what my fusion rate is or how to check that :/

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/421#issuecomment-673612933, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKXKWDWDVNRPYMOPZ53SAQQJBANCNFSM4N4V4CIQ .

beaumr2 commented 4 years ago

This is what I have: Looks like the access biases are way off. That's with the device totally still, not even moving it when it asks for it to be waved in a figure 8. Don't see anything about a fusion rate. I'll post another output for when I wave it in a figure 8

MPU9250 is online... x-axis self test: acceleration trim within : -0.2% of factory value y-axis self test: acceleration trim within : -0.5% of factory value z-axis self test: acceleration trim within : 1.5% of factory value x-axis self test: gyration trim within : 33.5% of factory value y-axis self test: gyration trim within : 13.8% of factory value z-axis self test: gyration trim within : 0.4% of factory value accel biases (mg) -1726.07 120.54 -997.19 gyro biases (dps) -4.50 -9.84 -0.52 MPU9250 initialized for active data mode.... AK8963 I AM 48 I should be 48 AK8963 initialized for active data mode.... Mag Calibration: Wave device in a figure eight until done! Mag Calibration done! AK8963 mag biases (mG) 183.27 1294.17 -220.05 AK8963 mag scale (mG) 1.08 1.08 0.88 Calibration values: X-Axis sensitivity adjustment value 1.16 Y-Axis sensitivity adjustment value 1.17 Z-Axis sensitivity adjustment value 1.13

beaumr2 commented 4 years ago

Ignore that last part I said, I realized it puts out calibration values for accelerometer and gyroscope before doing the figure 8 magnetic calibration