Jump to content
altineller

MPU9150 working* with MSP430 and Tiva-C (almost)

Recommended Posts

Hello,

 

I managed to port the MPU9150Lib at https://github.com/richards-tech/MPU9150Lib to Energia.

 

I had to make few changes in defines in dmp code, and the provided CalLib, and now it compiles for MSP430G2553, MSP430F5xx, Stellaris Launchpad, and the Tiva-C series (TM4C123) launchpad. CalLib writes to either flash or eeprom depending on architecture.

 

It has failed for MSP430G2553, due to code size. It compiles for MSP430F5xx although I dont have a board yet to test. I have not tested the stellaris launchpad but I suspect it works, it does WORK on the Tiva-C series launchpad.

 

Here is the picture of the setup:

 

post-37459-0-23808600-1406421327_thumb.jpg

 

On one side I have an arduino nano v3 connected to a MPU9150 module (The cheap GY 9150) and on the other side I have a Tiva-C series launchpad with a sensorhub booster pack. (that contains a MPU9150 as well) and I have hooked up a usbee logic analyzer to i2c (sda, scl) of both mcus

 

For some reason, it is running slow on the TM4C123 then the arduino. It is supposed to work much faster on the Tiva-C launchpad, but on the contrary it does not. I measured mpu.read() times, and on Energia it wont go less then 50ms, where on arduino I have tested up to 200hz sensor read rates with no problem.

 

Here are two screenshots from the logic analyzer:

 

post-37459-0-86569300-1406421559_thumb.png

 

post-37459-0-81757700-1406421561_thumb.png

 

The top two signals are from arduino sda scl, the bottom is the sda(3) scl(3) of the Tiva-C

 

The MPU9150 is configured to update at 20Hz for both systems. however the i2c bus activity seems quite different. 

 

I am thinking there might be a problem with the i2c speed on Energia, or that it works different.

 

And finally here is my code:

 

MPU9150LibEnergia.rar

 

I will be posting all the code on github later - for now I made a zip file for all.

 

Best Regards,

Can

Share this post


Link to post
Share on other sites

YES. I managed to use the built-in MPU, and tested the measurements with a test jig. (a wooden box that is aligned north) so i can put the sensor on all sides.

 

DMP is FASTER.

 

DMP is much better then the DCM alg. in razor imu and similar.

 

That is why i ported this lib, since it works with DMP.

Share this post


Link to post
Share on other sites

Hello altineller,

I've tested your code by hooking up a 9150 module (similar to the one you connected to the Nano) to Tiva C. I had to add Wire.setModule(1) to the setup function of the Energia9150.ino file and then it worked, but as you said quite slowly.

The slow speed is probably related to the problem addressed by this pull request for the energia wire library: https://github.com/energia/Energia/pull/343

In the energia-0101E0012/hardware/lm4f/libraries/Wire/Wire.cpp file the TwoWire::getRxData and TwoWire::sendTxData both have a delay of 1ms build in. This is probably the cause of the delay you are seeing in the SCL of the Tiva. Moreover, the TwoWire::begin method limits the I2C speed to 100kbps.

I've tested your code also with a modified Wire.cpp file, forcing the speed to 400kbps and removing the delay(1) statements from the getRxData and sendTxData methods. This improved speed a lot, but wasn't stable (communictation with the module stopped at random times). To get it stable I had to add 10micro second delays (delayMicroseconds(10)) to the getRxData and sendTxData methods instead of the delay(1). With this change I could increase the MPU_UPDATA_RATE to 200 and the MAG_UPDATE_RATE to 100, resulting in an average sample time of less then 6ms.

Share this post


Link to post
Share on other sites

YES. I managed to use the built-in MPU, and tested the measurements with a test jig. (a wooden box that is aligned north) so i can put the sensor on all sides.

 

DMP is FASTER.

 

DMP is much better then the DCM alg. in razor imu and similar.

 

That is why i ported this lib, since it works with DMP.

 

Hello altineller.

I have tested your code against a SensorHub Boosterpack:

http://www.ti.com/tool/boostxl-senshub

 

I am using the m_fusedEulerPose to get roll, pitch and yaw, but I am seeing that yaw is not working at all (with some crossings when I move pitch and roll).

However if I use m_dmpEulerPose instead, the result is more similar to what is expected (but with a little error on yaw too).

 

Does it happen the same to you?

Regards

Share this post


Link to post
Share on other sites

how are you observing yaw?

 

I mistake I did at the beginning was to think that euler angles were YPR.

 

I got quarternions, and sent them over serial with the mpu6050 processing example. You give it quarternions, and it will rotate the little plane by these metrics.

 

I have used for the visualization  m_fusedQuaternion[4]

 

Also, on the boosterpack there is a design error. You have to unsolder 2 resistor from launcpad if you are using stellaris or tiva-c. basically, they shunted the i2c port to some other pins, in order to have backward pin compatibility, and you should also search for that and make sure your i2c bus is working as it should. Having i2c pins shunted to other mcu pins is not the best practice. It caused glitches and compass errors.

 

Are you also checking error codes from compass? Sometimes compass might fail to init, or dmp code might not load correctly, or work glitchy. (all because of those resistors)

 

Also what speed did you try at? You can try at different speeds and plot the results in order to gain more insight. Also, did you check compass calibration? When compass is calibrated, it works perfectly in 200hz.

 

Best Regards,

Share this post


Link to post
Share on other sites

Thank you for your answer.

 

I built a processing sketch to visualize the position of the board.

Will share it tomorrow (quite late here) and will try everything you say, so I can answer better.

 

Regards

Share this post


Link to post
Share on other sites

Hello again altineller.

I have tested theboosterpack with and without those  resistors, but you need them on the board to make the boosterpack works!!

Anyway I tested it both ways (with wires) and I am seeing the same behavior (so that's ok).

 

So if I use the m_fusedEulerPose I am noticing some drift in yaw if I turn or pitch the board, and it doesn't happen if I use the m_dmpEulerPose works more as expected (99% right).

 

To test both codes I wrote a processing sketch:

http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-components-files/908/3107.SENSORHUB_5F00_3D_5F00_SKETCH.zip

 

You can find more information about the sketch here:

http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/285768.aspx?pi307171=1

 

 

 

Also added a new printangle function in the MPU9150Lib.cpp file:



void MPU9150Lib::printAngles_Processing(float cnt_ini,short *Gyro,short *Acel,short *Mag,float *Euler)
{

//  short m_rawGyro[3];                                       // calibrated gyro output from the sensor
  //short m_rawAccel[3];                                      // raw accel data
  //short m_rawMag[3];  

//#define VEC3_X		0										// x offset
//#define VEC3_Y		1										// y offset
//#define VEC3_Z		2										// z offset



 Serial.print(cnt_ini);
 Serial.print(",");  
 ////////////////////////////////////////////////////
//Gyro                      
 Serial.print(Gyro[VEC3_X]);
 Serial.print(",");  
 Serial.print(Gyro[VEC3_Y]);  
 Serial.print(",");
 Serial.print(Gyro[VEC3_Z]);  
 Serial.print(",");      
 ////////////////////////////////////////////////////
//ACEL                      
 Serial.print(Acel[VEC3_X]);
 Serial.print(",");  
 Serial.print(Acel[VEC3_Y]);  
 Serial.print(",");
 Serial.print(Acel[VEC3_Z]);  
 Serial.print(",");     
////////////////////////////////////////////////////
//MAG                      
 Serial.print(Mag[VEC3_X]);
 Serial.print(",");  
 Serial.print(Mag[VEC3_Y]);  
 Serial.print(",");
 Serial.print(Mag[VEC3_Z]);  
 Serial.print(",");
Serial.print("100");
Serial.print(",");
///////////////////////////////////////////
//EULERS

   Serial.print(Euler[VEC3_X] * RAD_TO_DEGREE);  
  Serial.print(",");
   Serial.print(Euler[VEC3_Y] * RAD_TO_DEGREE);  
  Serial.print(",");
   Serial.print(Euler[VEC3_Z] * RAD_TO_DEGREE);
   Serial.print("!");    
}

To use it, in the main function yo need to write:

  //  MPU.printAngles(MPU.m_fusedEulerPose);                 // print the output of the data fusion

    MPU.m_dmpEulerPose[1]=-MPU.m_dmpEulerPose[1];
    MPU.m_dmpEulerPose[2]=-MPU.m_dmpEulerPose[2];
    MPU.printAngles_Processing(cnt_loop++,MPU.m_rawGyro,MPU.m_calAccel,MPU.m_rawMag,MPU.m_dmpEulerPose);                 // print the output of the data fusion
    Serial.println();

Could you test your results with the sketch? just to discard the effect of the boards.

 

Thank you

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×