This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Porting MPU-9150 SenseHub Example to MPU-6050 Problem

As the title suggests, I'm working to port this example so I'll have a guide to go by when operating with the MPU-6050. The INT pin on the MPU-6050 is configured to generate an interrupt for the Tiva C Launchpad (running at 80MHz). The problem is that the pin never changes to indicate data is ready and thus never generates an interrupt on the Tiva C. Here's a snippet of the altered example and almost everything else about the example has been kept the same (except for renaming functions and variables to MPU6050 instead of MPU9150 and including the appropriate headers):

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

    ConfigureUART();
    UARTprintf("\033[2JMPU6050 Raw Example\n");
    
    g_pui32Colors[RED] = 0x8000;
    g_pui32Colors[BLUE] = 0x8000;
    g_pui32Colors[GREEN] = 0x0000;

    RGBInit(0);
    RGBColorSet(g_pui32Colors);
    RGBIntensitySet(0.5f);
    RGBEnable();
    
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    ROM_GPIOPinConfigure(GPIO_PD0_I2C3SCL);
    ROM_GPIOPinConfigure(GPIO_PD1_I2C3SDA);

    GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
    ROM_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);
  
    ROM_GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_2);
    GPIOIntEnable(GPIO_PORTE_BASE, GPIO_PIN_2);
    ROM_GPIOIntTypeSet(GPIO_PORTE_BASE, GPIO_PIN_2, GPIO_FALLING_EDGE);
    ROM_IntEnable(INT_GPIOE);
    
    ROM_IntMasterEnable();

    ROM_SysCtlPeripheralClockGating(true);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOE);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_TIMER0);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_TIMER1);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_I2C3);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_WTIMER5);
    
    I2CMInit(&g_sI2CInst, I2C3_BASE, INT_I2C3, 0xff, 0xff,
             ROM_SysCtlClockGet());

    MPU6050Init(&g_sMPU6050Inst, &g_sI2CInst, MPU6050_I2C_ADDRESS,
                MPU6050AppCallback, &g_sMPU6050Inst);

    MPU6050AppI2CWait(__FILE__, __LINE__);      
    
    // Start here
    g_sMPU6050Inst.pui8Data[0] = MPU6050_CONFIG_DLPF_CFG_94_98;
    g_sMPU6050Inst.pui8Data[1] = MPU6050_GYRO_CONFIG_FS_SEL_250;
    g_sMPU6050Inst.pui8Data[2] = (MPU6050_ACCEL_CONFIG_AFS_SEL_2G);
    MPU6050Write(&g_sMPU6050Inst, MPU6050_O_CONFIG, g_sMPU6050Inst.pui8Data, 3,
                 MPU6050AppCallback, &g_sMPU6050Inst);

    MPU6050AppI2CWait(__FILE__, __LINE__);

    g_sMPU6050Inst.pui8Data[0] = MPU6050_INT_PIN_CFG_INT_LEVEL |
                                    MPU6050_INT_PIN_CFG_INT_RD_CLEAR |
                                    MPU6050_INT_PIN_CFG_LATCH_INT_EN;
    g_sMPU6050Inst.pui8Data[1] = MPU6050_INT_ENABLE_DATA_RDY_EN;
    MPU6050Write(&g_sMPU6050Inst, MPU6050_O_INT_PIN_CFG,
                 g_sMPU6050Inst.pui8Data, 2, MPU6050AppCallback,
                 &g_sMPU6050Inst);

    MPU6050AppI2CWait(__FILE__, __LINE__);

    CompDCMInit(&g_sCompDCMInst, 1.0f / 50.0f, 0.2f, 0.8f, 0.0f);

    UARTprintf("\033[2J\033[H");
    UARTprintf("MPU6050 6-Axis Simple Data Application Example\n\n");
    UARTprintf("\033[20GX\033[31G|\033[43GY\033[54G|\033[66GZ\n\n");
    UARTprintf("Accel\033[8G|\033[31G|\033[54G|\n\n");
    UARTprintf("Gyro\033[8G|\033[31G|\033[54G|\n\n");
    UARTprintf("Mag\033[8G|\033[31G|\033[54G|\n\n");
    UARTprintf("\n\033[20GRoll\033[31G|\033[43GPitch\033[54G|\033[66GYaw\n\n");
    UARTprintf("Eulers\033[8G|\033[31G|\033[54G|\n\n");

    UARTprintf("\n\033[17GQ1\033[26G|\033[35GQ2\033[44G|\033[53GQ3\033[62G|"
               "\033[71GQ4\n\n");
    UARTprintf("Q\033[8G|\033[26G|\033[44G|\033[62G|\n\n");

    RGBBlinkRateSet(1.0f);

    ui32CompDCMStarted = 0;  
    while(1){
        //
        // Go to sleep mode while waiting for data ready.
        //
        while(!g_vui8I2CDoneFlag)
        {
            ROM_SysCtlSleep();
        }

        //
        // Clear the flag
        //
        g_vui8I2CDoneFlag = 0;    // This point is never reached.

I2C3 is setup on port pins PD0 and PD1 to communicate with the MPU-6050 while the interrupt pin is set to PE2. Something that I noticed in the debugger is that after the interrupt logic level MPU6050_INT_PIN_CFG_INT_LEVEL write is performed the Port E Data register indicates that a change from 0 to 1 does occur on PE2 (which is correct operation but beyond that it never goes low no matter what even if a read on the MPU6050 is performed). If anyone has any suggestions for what wrong thing I am doing, feel free to chime in. I'm using CCS version 5.5 and am using TivaWare version 2.0.1.11577

 EDIT: Upon further investigation, the MPU6050DataRead function is always returning true but the values are never updated for use by the MPU6050DataAccelGetFloat and MPU6050DataGyroGetFloat. Both of those functions are always storing zeroes for some reason.

  • I found the problem! TI's example code does not take the MPU-6050 out of sleep mode during initialization, which I (wrongly) assumed it would. Thus, the values read from the MPU-6050 will always be zero. So, the code refused to work under any circumstances. 

    TI should really correct that problem/bug in their sensehub example or at least notify the user in their documentation of the MPU-6050 driver library that the initialization routine does NOT take the device out of reset. And, that it is up to the application to do so (if you would like data and all that). It took a while of looking through the implementation of the MPU-6050 source file's callback state machine function to find that the reset bit is never set to 0.

  • Believe that you've done a very nice job in finding & correcting that issue.  Thank you.

    That said - as you're porting from MPU-9150 to MPU-6050 - might that fact bedevil the original code and/or its proper, reset operation?  (i.e. should there be pin, signal and/or timing differences between these 2 devices - finding/correcting are the responsibility of the port operation)

  • I've raised a problem report against the developer of the example and sensorlib to correct the problem and improve the documentation. If we're lucky, this may make it into the next release.

  • @cb1_mobile

    The MPU-6050 driver provided by TI works well. I never had any direct problems with it as far as how well it can read or write to the MPU-6050. All I2C bus transactions were apparently completed in all the cases that I used it. Although occasionally when I was re-uploading programs to the Tiva C Launchpad, the I2C bus would sometimes "hang" and the driver could not recover it. This problem was solved by disconnecting power to the Launchpad and MPU-6050 and re-connecting.

    I don't think the MPU-6050 driver will need fixing but the compdcm_mpu9150 SenseHub board example provided in TivaWare does not take into account that the reset bit in the Power Management 1 register needs to be cleared before operation device can commence. I can't see how the example ever worked to begin with unless the MPU-9150 driver cleared that bit somewhere after calling its initialization function.

    @Dave Wilson

    Thanks!

  • @Trenton,

    Forceful, detailed report which substantially reduces my fear that, "something significant had been lost in your port exercise!"  (as you know - only one "gotcha/miscue" can render us, "bums.")

    Not too hard to see how the embedding of a critical reset bit - w/in some distinct accessory IC Register - may be missed by the original design team.  (one assumes they faced some time-crunch)

    The in depth explanation you provided should provide, "extra push" - such that the design group incorporates your findings.  Again - good job and many offer their thanks...

  • Hello Trenton,

    Could you please post the working project here please? I'm about to develop with the MPU6050 so it will be very helpful. Thanks!

    Francisco

  • I found problems with my project with MPU6050 and Tiva C. Could you help me?

  • Hello,

    I'm having this problem, solution?

    Thanks

  • Can you please explain how exactly you wake up the MPU-6050?
    I write the value 0x0 to PWR_MGMT_1 register and still receive zeroes when read from registers.
    I also tried to write values 0x01(reset val), 0x80(device reset), it was useless.

  • Hello Sergey,

    How are you putting the device into Sleep, i.e what is the value being written? Is the WHO_AM_I register access still working?

    Regards
    Amit
  • Hello,

    The problem was in API function that works with I2C:  to write value to register need to use Burst write sequence.

    In the end of sequence instead:

    MAP_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_STOP);

    should be used:

    MAP_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);

    Value that written to register should be only 0. If I write different from zero value, it doesn't work. Don't know how to turn off the temp sensor and chose the clock source.

  • Hello Sergey,

    The STOP condition puts an immediate STOP while FINISH condition will transmit another data and then STOP.

    Regards
    Amit
  • Could you let us know how do we clear the reset bit in the Power Management 1 register please? Thanks