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.

TM4C123GH6PM with MPU9150 on I2C1 data spontaniously changing

Hello Ti Forum,

I just wasted three whole days to figure that Problem by myself - i so try to find someone who may can help us.

First: I have the Launchpad STellaris and ist Boosterpack SensorHub, it is working! I try to get our MPU9150 on our PCB working, i use the same code as in "compdcm_mpu9150" Example of the BoosterPack.

My Pin Configuration:

I2C1: SDA on PA7, SCL on PA6

IntMotion: GPIOA3

The actual Problem: I do not get any computed Euler Coordinates.

The data of magnetos are always 0.0 (after MPU9150DataMagnetoGetFloat(&g_sMPU9150Inst, &pfMag[0], &pfMag[1], &pfMag[2]);)

if i put filter Settings of the MPU9150 to

g_sMPU9150Inst.pui8Data[0] = MPU9150_CONFIG_DLPF_CFG_260_165;

g_sMPU9150Inst.pui8Data[1] = MPU9150_GYRO_CONFIG_FS_SEL_2000;

i get Data!! also Euler and Magnetos coming in. BUT: there are changing steadily and convergencing from 0.0 to the endvalue and repeating this..

 

So I have no idea what is wrong :( i have set stacksize to 4096, no heap, included the driverlib/sensorlib in the ARMLinker like in the example.

Do you have any experience?

 

I guess ist something with a Signal or a Timing Problem which overruns itself, but even Debugging brings no clear solution. And yes, i tried with another HW already! Must be some configurations settings

 

THANK YOU & happy eastern

 

 //
    // Setup the system clock to run at 80 Mhz from PLL with crystal reference
    //
    SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //  SYSCTL_XTAL_16MHZ);
    clockRate = SysCtlClockGet();

    //
    // Enable port B used for motion interrupt.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
    // The I2C3 peripheral must be enabled before use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Configure the pin muxing for I2C3 functions on port D0 and D1.
    //
    GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    GPIOPinConfigure(GPIO_PA7_I2C1SDA);

    //
    // Select the I2C function for these pins.  This function will also
    // configure the GPIO pins pins for I2C operation, setting them to
    // open-drain operation with weak pull-ups.  Consult the data sheet
    // to see which functions are allocated per pin.
    //
    	GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
    	GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);

    //
    // Configure and Enable the GPIO interrupt. Used for INT signal from the
    // MPU9150
    //GPIOIntRegister(GPIO_PORTA_BASE, IntGPIOa);
    		GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_3);
    		GPIOIntEnable(GPIO_PORTA_BASE, GPIO_PIN_3);

    		GPIOIntTypeSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_FALLING_EDGE);
    		IntEnable(INT_GPIOA);

    //
    // Keep only some parts of the systems running while in sleep mode.
    // GPIOB is for the MPU9150 interrupt pin.
    // UART0 is the virtual serial port
    // TIMER0, TIMER1 and WTIMER5 are used by the RGB driver
    // I2C3 is the I2C interface to the ISL29023
    //
    		SysCtlPeripheralClockGating(true);
    		SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_I2C1);
    		SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable interrupts to the processor.
    //
    IntMasterEnable();

    //
    // Initialize I2C3 peripheral.
    //
	//I2CIntRegister(I2C1_BASE, MPU9150I2CIntHandler);
    I2CMInit(&g_sI2CInst, I2C1_BASE, INT_I2C1, 0xff, 0xff,
    		clockRate);
//
    // Initialize the MPU9150 Driver.
    //
    MPU9150Init(&g_sMPU9150Inst, &g_sI2CInst, MPU9150_I2C_ADDRESS,
                MPU9150AppCallback, &g_sMPU9150Inst);

    //
    // Wait for transaction to complete
    //
    MPU9150AppI2CWait(__FILE__, __LINE__);

    //
    // Write application specifice sensor configuration such as filter settings
    // and sensor range settings.
    //
    g_sMPU9150Inst.pui8Data[0] = MPU9150_CONFIG_DLPF_CFG_;
    g_sMPU9150Inst.pui8Data[1] = MPU9150_GYRO_CONFIG_FS_SEL_250;
    g_sMPU9150Inst.pui8Data[2] = (MPU9150_ACCEL_CONFIG_ACCEL_HPF_5HZ |
                                  MPU9150_ACCEL_CONFIG_AFS_SEL_2G);
    MPU9150Write(&g_sMPU9150Inst, MPU9150_O_CONFIG, g_sMPU9150Inst.pui8Data, 3,
                 MPU9150AppCallback, &g_sMPU9150Inst);

    //
    // Wait for transaction to complete
    //
    MPU9150AppI2CWait(__FILE__, __LINE__);

    //
    // Configure the data ready interrupt pin output of the MPU9150.
    //
    g_sMPU9150Inst.pui8Data[0] = MPU9150_INT_PIN_CFG_INT_LEVEL |
                                    MPU9150_INT_PIN_CFG_INT_RD_CLEAR |
                                    MPU9150_INT_PIN_CFG_LATCH_INT_EN;
    g_sMPU9150Inst.pui8Data[1] = MPU9150_INT_ENABLE_DATA_RDY_EN;
    MPU9150Write(&g_sMPU9150Inst, MPU9150_O_INT_PIN_CFG,
                 g_sMPU9150Inst.pui8Data, 2, MPU9150AppCallback,
                 &g_sMPU9150Inst);

    //
    // Wait for transaction to complete
    //
    MPU9150AppI2CWait(__FILE__, __LINE__);

    //
    // Initialize the DCM system. 50 hz sample rate.
    // accel weight = .2, gyro weight = .8, mag weight = .2
    //
    CompDCMInit(&g_sCompDCMInst, 1.0f / 50.0f, 0.2f, 0.8f, 0.0f);


    //
    // Enable blinking indicates config finished successfully
    //


    ui32CompDCMStarted = 0;

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

        //
        // Clear the flag
        //
        g_vui8I2CDoneFlag = 0;

        //
        // Get floating point version of the Accel Data in m/s^2.
        //
        MPU9150DataAccelGetFloat(&g_sMPU9150Inst, &pfAccel[0], &pfAccel[1],
        		&pfAccel[2]);

        //
        // Get floating point version of angular velocities in rad/sec
        //
        MPU9150DataGyroGetFloat(&g_sMPU9150Inst, &pfGyro[0], &pfGyro[1],
        		&pfGyro[2]);

        //
        // Get floating point version of magnetic fields strength in tesla
        //
        MPU9150DataMagnetoGetFloat(&g_sMPU9150Inst, &pfMag[0], &pfMag[1], &pfMag[2]);


        //
        // Check if this is our first data ever.
        //
        if(ui32CompDCMStarted == 0)
        {
            //
            // Set flag indicating that DCM is started.
            // Perform the seeding of the DCM with the first data set.
            //
            ui32CompDCMStarted = 1;
            CompDCMMagnetoUpdate(&g_sCompDCMInst, pfMag[0], pfMag[1],
                                 pfMag[2]);
            CompDCMAccelUpdate(&g_sCompDCMInst, pfAccel[0], pfAccel[1],
                               pfAccel[2]);
            CompDCMGyroUpdate(&g_sCompDCMInst, pfGyro[0], pfGyro[1],
                              pfGyro[2]);

            CompDCMStart(&g_sCompDCMInst);
        }
        else
        {
            //
            // DCM Is already started.  Perform the incremental update.
            //
            CompDCMMagnetoUpdate(&g_sCompDCMInst, pfMag[0], pfMag[1],
                                 pfMag[2]);
            CompDCMAccelUpdate(&g_sCompDCMInst, pfAccel[0], pfAccel[1],
                               pfAccel[2]);
            CompDCMGyroUpdate(&g_sCompDCMInst, -pfGyro[0], -pfGyro[1],
                              -pfGyro[2]);

            CompDCMUpdate(&g_sCompDCMInst);
        }

        //
        // Increment the skip counter.  Skip counter is used so we do not
        // overflow the UART with data.
        //
        g_ui32PrintSkipCounter++;
        if(g_ui32PrintSkipCounter >= PRINT_SKIP_COUNT)
        {
            //
            // Reset skip counter.
            //
            g_ui32PrintSkipCounter = 0;

            //
            // Get Euler data. (Roll Pitch Yaw)
            //
            CompDCMComputeEulers(&g_sCompDCMInst, &pfEulers[0], &pfEulers[1],
            		&pfEulers[2]);

            //
            // Get Quaternions.
            //
            CompDCMComputeQuaternion(&g_sCompDCMInst, pfQuaternion);

            //
            // convert mag data to micro-tesla for better human interpretation.
            //
            pfMag[0] *= 1e6;
            pfMag[1] *= 1e6;
            pfMag[2] *= 1e6;

            //
            // Convert Eulers to degrees. 180/PI = 57.29...
            // Convert Yaw to 0 to 360 to approximate compass headings.
            //
            pfEulers[0] *= 57.295779513082320876798154814105f;
            pfEulers[1] *= 57.295779513082320876798154814105f;
            pfEulers[2] *= 57.295779513082320876798154814105f;
            if(pfEulers[2] < 0)
            {
                pfEulers[2] += 360.0f;
            }

  • //
    // Initialize the MPU9150 Driver.
    //
    MPU9150Init(&g_sMPU9150Inst, &g_sI2CInst, MPU9150_I2C_ADDRESS,
    MPU9150AppCallback, &g_sMPU9150Inst);

    //
    // Wait for transaction to complete
    //
    MPU9150AppI2CWait(__FILE__, __LINE__);

    //
    // Write application specifice sensor configuration such as filter settings
    // and sensor range settings.
    //
    g_sMPU9150Inst.pui8Data[0] = MPU9150_CONFIG_DLPF_CFG_;
    g_sMPU9150Inst.pui8Data[1] = MPU9150_GYRO_CONFIG_FS_SEL_250;
    g_sMPU9150Inst.pui8Data[2] = (MPU9150_ACCEL_CONFIG_ACCEL_HPF_5HZ |
    MPU9150_ACCEL_CONFIG_AFS_SEL_2G);
    MPU9150Write(&g_sMPU9150Inst, MPU9150_O_CONFIG, g_sMPU9150Inst.pui8Data, 3,
    MPU9150AppCallback, &g_sMPU9150Inst);

    //
    // Wait for transaction to complete
    //
    MPU9150AppI2CWait(__FILE__, __LINE__);

    //
    // Configure the data ready interrupt pin output of the MPU9150.
    //
    g_sMPU9150Inst.pui8Data[0] = MPU9150_INT_PIN_CFG_INT_LEVEL |
    MPU9150_INT_PIN_CFG_INT_RD_CLEAR |
    MPU9150_INT_PIN_CFG_LATCH_INT_EN;
    g_sMPU9150Inst.pui8Data[1] = MPU9150_INT_ENABLE_DATA_RDY_EN;
    MPU9150Write(&g_sMPU9150Inst, MPU9150_O_INT_PIN_CFG,
    g_sMPU9150Inst.pui8Data, 2, MPU9150AppCallback,
    &g_sMPU9150Inst);

    //
    // Wait for transaction to complete
    //
    MPU9150AppI2CWait(__FILE__, __LINE__);

    //
    // Initialize the DCM system. 50 hz sample rate.
    // accel weight = .2, gyro weight = .8, mag weight = .2
    //
    CompDCMInit(&g_sCompDCMInst, 1.0f / 50.0f, 0.2f, 0.8f, 0.0f);


    //
    // Enable blinking indicates config finished successfully
    //


    ui32CompDCMStarted = 0;

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

    //
    // Clear the flag
    //
    g_vui8I2CDoneFlag = 0;

    //
    // Get floating point version of the Accel Data in m/s^2.
    //
    MPU9150DataAccelGetFloat(&g_sMPU9150Inst, &pfAccel[0], &pfAccel[1],
    &pfAccel[2]);

    //
    // Get floating point version of angular velocities in rad/sec
    //
    MPU9150DataGyroGetFloat(&g_sMPU9150Inst, &pfGyro[0], &pfGyro[1],
    &pfGyro[2]);

    //
    // Get floating point version of magnetic fields strength in tesla
    //
    MPU9150DataMagnetoGetFloat(&g_sMPU9150Inst, &pfMag[0], &pfMag[1], &pfMag[2]);


    //
    // Check if this is our first data ever.
    //
    if(ui32CompDCMStarted == 0)
    {
    //
    // Set flag indicating that DCM is started.
    // Perform the seeding of the DCM with the first data set.
    //
    ui32CompDCMStarted = 1;
    CompDCMMagnetoUpdate(&g_sCompDCMInst, pfMag[0], pfMag[1],
    pfMag[2]);
    CompDCMAccelUpdate(&g_sCompDCMInst, pfAccel[0], pfAccel[1],
    pfAccel[2]);
    CompDCMGyroUpdate(&g_sCompDCMInst, pfGyro[0], pfGyro[1],
    pfGyro[2]);

    CompDCMStart(&g_sCompDCMInst);
    }
    else
    {
    //
    // DCM Is already started. Perform the incremental update.
    //
    CompDCMMagnetoUpdate(&g_sCompDCMInst, pfMag[0], pfMag[1],
    pfMag[2]);
    CompDCMAccelUpdate(&g_sCompDCMInst, pfAccel[0], pfAccel[1],
    pfAccel[2]);
    CompDCMGyroUpdate(&g_sCompDCMInst, -pfGyro[0], -pfGyro[1],
    -pfGyro[2]);

    CompDCMUpdate(&g_sCompDCMInst);
    }

    //
    // Increment the skip counter. Skip counter is used so we do not
    // overflow the UART with data.
    //
    g_ui32PrintSkipCounter++;
    if(g_ui32PrintSkipCounter >= PRINT_SKIP_COUNT)
    {
    //
    // Reset skip counter.
    //
    g_ui32PrintSkipCounter = 0;

    //
    // Get Euler data. (Roll Pitch Yaw)
    //
    CompDCMComputeEulers(&g_sCompDCMInst, &pfEulers[0], &pfEulers[1],
    &pfEulers[2]);

    //
    // Get Quaternions.
    //
    CompDCMComputeQuaternion(&g_sCompDCMInst, pfQuaternion);

    //
    // convert mag data to micro-tesla for better human interpretation.
    //
    pfMag[0] *= 1e6;
    pfMag[1] *= 1e6;
    pfMag[2] *= 1e6;

    //
    // Convert Eulers to degrees. 180/PI = 57.29...
    // Convert Yaw to 0 to 360 to approximate compass headings.
    //
    pfEulers[0] *= 57.295779513082320876798154814105f;
    pfEulers[1] *= 57.295779513082320876798154814105f;
    pfEulers[2] *= 57.295779513082320876798154814105f;
    if(pfEulers[2] < 0)
    {
    pfEulers[2] += 360.0f;
    }
  • Hello Peter,

    Is there a pull up on your board or are you relying on the Pull Up for I2C from Sensor Hub Booster Pack.

    Also it would be good to check the signal fall-rise and data transfer are happening correctly (timing related) between the Launch Pad v/s your custom board

    Regards
    Amit
  • Thank you!

    I measured today the i2C lines again. some kind of round clock pulses --> my pull up resistir were 10k ohm

    after checking the invensense user guide i figured out they use 2k ohms, my Team which designed the pcb didnt care about this..

    Ist working now!! Thank you very much, cool Forum (y)

  • Hello Peter,

    Looks like a quirk in the Invensense device ;-) (admit that TM4C also has it's quirk"s")

    Regards
    Amit