Hi,
I'm trying to use the eMPL library inside QNX in order to use the MPU6050 with an ARM Processor.
I've started from the example that provided for the msp430 microcontroller.
So, as requested, I've implemented the following functions:
1) i2c_write implemented as mpu6050_i2c_write
2) i2c_read implemented as mpu6050_i2c_read
3) delay_ms implemented as mpu6050_delay_ms
4) get_ms implemented as mpu6050_get_ms
5) log_i implemented as printf
6) log_e implemented as printf
After that, I started calling the functions to get the MPU6050 working with the DMP, following the instructions provided inside the example.
I've compiled the code with just the symbol "MPU6050". Is this correct or do I need some other symbol?
Following the snippet of code taken from the main that managee the Inertial Sensor:
int result;
unsigned char accel_fsr;
unsigned short gyro_rate, gyro_fsr;
unsigned long timestamp;
i2c_open();
result = mpu_init(NULL);
//if (result)
//msp430_reset();
/* If you're not using an MPU9150 AND you're not using DMP features, this
* function will place all slaves on the primary bus.
* mpu_set_bypass(1);
*/
/* Get/set hardware configuration. Start gyro. */
/* Wake up all sensors. */
mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL);
mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL);
mpu_set_sample_rate(DEFAULT_MPU_HZ);
mpu_get_sample_rate(&gyro_rate);
mpu_get_gyro_fsr(&gyro_fsr);
mpu_get_accel_fsr(&accel_fsr);
/* Initialize HAL state variables. */
memset(&hal, 0, sizeof(hal));
hal.sensors = ACCEL_ON | GYRO_ON;
hal.report = PRINT_QUAT;
/* To initialize the DMP:
* 1. Call dmp_load_motion_driver_firmware(). This pushes the DMP image in
* inv_mpu_dmp_motion_driver.h into the MPU memory.
* 2. Push the gyro and accel orientation matrix to the DMP.
* 3. Register gesture callbacks. Don't worry, these callbacks won't be
* executed unless the corresponding feature is enabled.
* 4. Call dmp_enable_feature(mask) to enable different features.
* 5. Call dmp_set_fifo_rate(freq) to select a DMP output rate.
* 6. Call any feature-specific control functions.
*
* To enable the DMP, just call mpu_set_dmp_state(1). This function can
* be called repeatedly to enable and disable the DMP at runtime.
*
* The following is a short summary of the features supported in the DMP
* image provided in inv_mpu_dmp_motion_driver.c:
* DMP_FEATURE_LP_QUAT: Generate a gyro-only quaternion on the DMP at
* 200Hz. Integrating the gyro data at higher rates reduces numerical
* errors (compared to integration on the MCU at a lower sampling rate).
* DMP_FEATURE_6X_LP_QUAT: Generate a gyro/accel quaternion on the DMP at
* 200Hz. Cannot be used in combination with DMP_FEATURE_LP_QUAT.
* DMP_FEATURE_TAP: Detect taps along the X, Y, and Z axes.
* DMP_FEATURE_ANDROID_ORIENT: Google's screen rotation algorithm. Triggers
* an event at the four orientations where the screen should rotate.
* DMP_FEATURE_GYRO_CAL: Calibrates the gyro data after eight seconds of
* no motion.
* DMP_FEATURE_SEND_RAW_ACCEL: Add raw accelerometer data to the FIFO.
* DMP_FEATURE_SEND_RAW_GYRO: Add raw gyro data to the FIFO.
* DMP_FEATURE_SEND_CAL_GYRO: Add calibrated gyro data to the FIFO. Cannot
* be used in combination with DMP_FEATURE_SEND_RAW_GYRO.
*/
dmp_load_motion_driver_firmware();
dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation));
//dmp_register_tap_cb(tap_cb);
//dmp_register_android_orient_cb(android_orient_cb);
// Removed DMP_FEATURE_TAP e DMP_FEATURE_ANDROID_ORIENT
hal.dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL;
dmp_enable_feature(hal.dmp_features);
int flag_fifo_rate = dmp_set_fifo_rate(DEFAULT_MPU_HZ);
printf("dmp_set_fifo_rate(DEFAULT_MPU_HZ): %dn",flag_fifo_rate);
mpu_set_dmp_state(1);
hal.dmp_on = 1;
unsigned long loop_delay;
mpudata_t mpu;
memset(&mpu, 0, sizeof(mpudata_t));
// reading data
while(true)
{
short sensors;
unsigned char more;
return -1;
if (dmp_read_fifo(mpu.rawGyro, mpu.rawAccel, mpu.rawQuat, &mpu.dmpTimestamp, &sensors, &more) < 0) {
printf("dmp_read_fifo() failedn");
return -1;
}
while (more) {
// Fell behind, reading again
if (dmp_read_fifo(mpu.rawGyro, mpu.rawAccel, mpu.rawQuat, &mpu.dmpTimestamp, &sensors, &more) < 0) {
printf("dmp_read_fifo() failedn");
return -1;
}
}
}
During the Debug of the code, I see that up to the while loop, the code works fine since every function return 0 as value.
I get an error when I try to read the fifo with the following message:
dmp_read_fifo() failed
I don't understand if I'm missing something else. For example, inside the example, before calling the mpu_set_sensors(...) function, the following code is run:
struct int_param_s int_param;
/* Set up MSP430 hardware. */
platform_init();
/* Set up gyro.
* Every function preceded by mpu_ is a driver function and can be found
* in inv_mpu.h.
*/
int_param.cb = gyro_data_ready_cb;
int_param.pin = INT_PIN_P20;
int_param.lp_exit = INT_EXIT_LPM0;
int_param.active_low = 1;
result = mpu_init(&int_param);
Going more in detail, I saw the platform_init() just initializes the i2c channel and USB. (In my case the i2c initialization is carried out by the i2c_open() function). Another problem is that, if I compile the code with the MPU6050 symbol, I don't have the following parameters available anymore:
/* Set up gyro.
* Every function preceded by mpu_ is a driver function and can be found
* in inv_mpu.h.
*/
int_param.cb = gyro_data_ready_cb;
int_param.pin = INT_PIN_P20;
int_param.lp_exit = INT_EXIT_LPM0;
int_param.active_low = 1;
Maybe is this a error?
Since I would read the calibrated data continuously, Do I strictly need to implement some routines for the interrupt management or not?
I also see that inside the mpu9150_init() the function msp430_reg_int_cb is called. Do I need to implement this function specifically for my platform?
Re: Re: porting of eMPL on QNX + ARM
The MotionFit eMPL library for MSP430 is posted as a combination of code and pre-built binaries for 9 axis sensor fusion, so it won't work unless recompiled for your platform and toolchain. If you don't have it already, send an email to developers@invensense.com with details on your project, to see if a library is available for your system. Optionally, you could port the 6 axis MotionDriver project, which is provided in full source.
Re: Re: porting of eMPL on QNX + ARM
Dear sectionsbest,
thanks for the reply.
I'm a bit confused (I don't have so much experience in embedded systems! :) )
So, I try to exaplain better what I did.
I've created a project in QNX Momentics with the correct toolchain and the correct settings for my processor (ARM9 Little Endian) and I added to my project the content of the eMPL directory which contain:
dmpKey.h
dmpmap.h
inv_mpu.c
inv_mpu.h
inv_mpu_dmp_motion_driver.c
inv_mpu_dmp_motion_driver.h
If I'm not wrong, the 6 axis MotionDriver project you're reffering to should be only the content of the eMPL directory. Am I right? If what I did is wrong, what is the 6 axis MotionDriver project and where can I download it?
So after that I started calling the mpu functions following the example that you provided (motion_driver_test.c)
I set every path and added a printf to see the return value of every function:
Running the code I get:
So, it seems that at least the initialization rountines work well. Am I right?
In fact the mpu_init routine gives me the following message:
Half sensitivity part found
So, at least the I2C communication should be ok. Right?
The problem is when I try to call the dmp_read_fifo function that give me the error dmp_read_fifo() failed
Am I missing somethings else? Am I misunderstood something else?
Thanks
Alessandro
Re: Re: porting of eMPL on QNX + ARM
1/2 sensitivity part found message is actually an error on our part. On startup the code attempts to self-identify the chip attached, and defualts to an early MPU-6050 release, which was half-sensitivity. This piece of code doesn't seem to be working for many developers. You should hard-code which chip you are testing, and jump past this piece of code. You should be able to verify that your I2C readbacks are occuring by breakpointing the hardware RX functions.
Re: Re: porting of eMPL on QNX + ARM
Hi,
I've changed the chip (MPU6050) to the last revision. Now i didn't get the "half sensitivity error" anymore.
However, I still get dmp_read_fifo() failed error.
I've put a printf inside the mpu_get_int_status() function as follows:
and I get
st.hw->addr; 68, st.reg->dmp_int_status: 39.
I didn't find on Register Map informations about register 39 (Hex), so I don't understand where is the error.
Anyway the status code in my case is 0x0117. Is this a valid status code?
In order to communicate with the MPU6050 I've connected just 3V3, GND, SDA and SCL pins but not INT pin. Maybe could be this the error? Can I use the dmp without interrupt?
Thanks
Re: Re: porting of eMPL on QNX + ARM
Yes, you'll want to connect the interrupt pin for the default project. This could be changed with your own code, but these were utilized on the MSP430.