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.

CCS/TM4C1294NCPDT: MPU6050/senosrlib

Part Number: TM4C1294NCPDT

Tool/software: Code Composer Studio

hello, all I'm trying to read the mpu6050 accelerometer and gyroscope data. but it is showing all the data zero.

I have already read. that query related to that issue.

but that was not working in my case I don't know why. 

The sensor is working properly with Arduino.

but showing zero values with tm4c1294.

this is my code.

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include "sensorlib/i2cm_drv.h"
#include "sensorlib/i2cm_drv.c"
#include "sensorlib/hw_mpu6050.h"
#include "sensorlib/mpu6050.h"
#include "sensorlib/mpu6050.c"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "inc/hw_i2c.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
#include "driverlib/i2c.h"
#include "driverlib/sysctl.h"
#include "utils/uartstdio.h"
#include "utils/uartstdio.c"
#include "driverlib/uart.h"
#include "driverlib/uart.c"

//
// A boolean that is set when a MPU6050 command has completed.
//
volatile bool g_bMPU6050Done = true;
tI2CMInstance g_sI2CMSimpleInst;
tMPU6050 sMPU6050;

void DelaySoft(volatile unsigned long ulDelay){
SysCtlDelay((SysCtlClockGet() / 10000) * ulDelay);
}

//
// The interrupt handler for the I2C module.
//
void I2CMSimpleIntHandler(void)
{
  //
  // Call the I2C master driver interrupt handler.
  //
  I2CMIntHandler(&g_sI2CMSimpleInst);
}

void MPU6050Callback1(void *pvCallbackData, uint_fast8_t ui8Status)
    {
//
// See if an error occurred.
//
        if(ui8Status != I2CM_STATUS_SUCCESS)
        {
//
// An error occurred, so handle it here if required.
//
        }
//
// Indicate that the MPU6050 transaction has completed.
//
        g_bMPU6050Done = true;
    }






void InitI2C0(void)
{
  //enable I2C module 0
  SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

  //enable GPIO peripheral that contains I2C 0
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

  // Configure the pin muxing for I2C0 functions on port B2 and B3.
  GPIOPinConfigure(GPIO_PB2_I2C0SCL);
  GPIOPinConfigure(GPIO_PB3_I2C0SDA);

  // Select the I2C function for these pins.
  GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
  GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

  I2CIntRegister(I2C0_BASE, &I2CMSimpleIntHandler);
  IntMasterEnable();

  // Initialize the I2C master driver.
  I2CMInit(&g_sI2CMSimpleInst, I2C0_BASE, INT_I2C0, 0xff, 0xff, SysCtlClockGet());
  I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), true);
}

// The function that is provided by this example as a callback when I2C transactions have completed.


//*****************************************************************************
// UARTstdio
//*****************************************************************************
void ConfigureUART(void)
{
// UART
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// UART0 Peripheral
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

// GPIO
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

// 16MHz
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
// Colsole I/O
UARTStdioConfig(0, 115200, 16000000);
}


char buf[100];
char* ftoa(float f)
{
int pos=0,ix,dp,num;
if (f<0)
{
buf[pos++]='-';
f = -f;
}
dp=0;
while (f>=10.0)
{
f=f/10.0;
dp++;
}
for (ix=1;ix<8;ix++)
{
num = (int)f;
f=f-num;
if (num>9)
buf[pos++]='#';
else
buf[pos++]='0'+num;
if (dp==0) buf[pos++]='.';
f=f*10.0;
dp--;
}
return buf;
}


void MPU6050Example(void) {
  float fAccel[3], fGyro[3];

  UARTprintf("MPU6050 initialization\n");
   // Write two bytes of data to the I2C device at address 0x3C.
  g_bMPU6050Done = false;
  uint_fast8_t result = MPU6050Init(&sMPU6050, &g_sI2CMSimpleInst, 0x68, MPU6050Callback1, 0);
 while(!g_bMPU6050Done)
 {
 }

  UARTprintf("Configure the MPU6050 for +/- 4 g accelerometer range\n");
  // Read four bytes of data from the I2C device at address 0x3C.
  g_bMPU6050Done = false;
  MPU6050ReadModifyWrite(&sMPU6050, MPU6050_O_ACCEL_CONFIG, ~MPU6050_ACCEL_CONFIG_AFS_SEL_M,
  MPU6050_ACCEL_CONFIG_AFS_SEL_4G, MPU6050Callback1, 0);
  while(!g_bMPU6050Done) {
  }

  // loop forever reading data from the MPU6050
  while(1) {
    // Request another reading from the MPU6050
    g_bMPU6050Done = false;
    MPU6050DataRead(&sMPU6050, MPU6050Callback1, 0);
    while(!g_bMPU6050Done) {
   }

    // Get the new accelerometer and gyroscope readings.
    MPU6050DataAccelGetFloat(&sMPU6050, &fAccel[0], &fAccel[1], &fAccel[2]);
    MPU6050DataGyroGetFloat(&sMPU6050, &fGyro[0], &fGyro[1], &fGyro[2]);

    UARTprintf("complete data receive from MPU6050\n");
    UARTprintf("Accel x = %s", ftoa(fAccel[0]));
    UARTprintf(", y = %s", ftoa(fAccel[1]));
    UARTprintf(", z = %s\n", ftoa(fAccel[2]));
   UARTprintf("Gyro x = %s", ftoa(fGyro[0]));
    UARTprintf(", y = %s", ftoa(fGyro[1]));
    UARTprintf(", z = %s\n", ftoa(fGyro[2]));

    //DelaySoft(1000);
  }
}

int main()
{
  //
  // Setup the system clock to run at 40 MHz from PLL with crystal reference
  //
  SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

  // UARTprintf()
  ConfigureUART();

  // Print start
  UARTprintf("\nConfigure UART\n");

  InitI2C0();

  MPU6050Example();

  return(0);
}

  • Hello m_vedsharma,

    Looking over your code, it looks like you made some modifications to the sensorlib example from the documentation. Have you attempted to use the example as is to start, and if so, were you success in reading data out? It'd be help to understand if the issue stems from the modifications you made, because if so, then we can really hone in on potential issues.

    Furthermore, can you use the debugger to check the output of MPU6050Init? That will tell us if the MPU6050 was properly initialized.

    I also noticed that sMPU6050 is brought out as a global variable, but it's not used in other functions, can you just return that back inside the MPU6050Example for now?
  • Thank you, Ralph Jacobi, for replying

    as you said to put  sMPU6050 back in the MPU6050Example.

    I did the same. 

    now I'm getting values from the sensor.

    but values are static which are not changing while I'm changing the sensor position

    #include <stdbool.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdarg.h>
    #include <stdbool.h>
    #include "sensorlib/i2cm_drv.h"
    #include "sensorlib/i2cm_drv.c"
    #include "sensorlib/hw_mpu6050.h"
    #include "sensorlib/mpu6050.h"
    #include "sensorlib/mpu6050.c"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_sysctl.h"
    #include "inc/hw_types.h"
    #include "inc/hw_i2c.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/debug.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/i2c.h"
    #include "driverlib/sysctl.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"
    #include "driverlib/uart.h"
    
    
    //
    // A boolean that is set when a MPU6050 command has completed.
    //
    volatile bool g_bMPU6050Done = true;
    tI2CMInstance g_sI2CMSimpleInst;
    
    
    void DelaySoft(volatile unsigned long ulDelay){
    SysCtlDelay((SysCtlClockGet() / 10000) * ulDelay);
    }
    
    //
    // The interrupt handler for the I2C module.
    //
    void I2CMSimpleIntHandler(void)
    {
      //
      // Call the I2C master driver interrupt handler.
      //
      I2CMIntHandler(&g_sI2CMSimpleInst);
    }
    
    void MPU6050Callback1(void *pvCallbackData, uint_fast8_t ui8Status)
        {
    //
    // See if an error occurred.
    //
            if(ui8Status != I2CM_STATUS_SUCCESS)
            {
    //
    // An error occurred, so handle it here if required.
    //
            }
    //
    // Indicate that the MPU6050 transaction has completed.
    //
            g_bMPU6050Done = true;
        }
    
    
    
    
    
    
    void InitI2C0(void)
    {
      //enable I2C module 0
      SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    
      //enable GPIO peripheral that contains I2C 0
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
      // Configure the pin muxing for I2C0 functions on port B2 and B3.
      GPIOPinConfigure(GPIO_PB2_I2C0SCL);
      GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    
      // Select the I2C function for these pins.
      GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
      GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
      I2CIntRegister(I2C0_BASE, &I2CMSimpleIntHandler);
      IntMasterEnable();
    
      // Initialize the I2C master driver.
      I2CMInit(&g_sI2CMSimpleInst, I2C0_BASE, INT_I2C0, 0xff, 0xff, SysCtlClockGet());
      I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), true);
    }
    
    // The function that is provided by this example as a callback when I2C transactions have completed.
    
    
    //*****************************************************************************
    // UARTstdio
    //*****************************************************************************
    void ConfigureUART(void)
    {
    // UART
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    // UART0 Peripheral
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
    // GPIO
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
    // 16MHz
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    // Colsole I/O
    UARTStdioConfig(0, 115200, 16000000);
    }
    
    
    char buf[100];
    char* ftoa(float f)
    {
    int pos=0,ix,dp,num;
    if (f<0)
    {
    buf[pos++]='-';
    f = -f;
    }
    dp=0;
    while (f>=10.0)
    {
    f=f/10.0;
    dp++;
    }
    for (ix=1;ix<8;ix++)
    {
    num = (int)f;
    f=f-num;
    if (num>9)
    buf[pos++]='#';
    else
    buf[pos++]='0'+num;
    if (dp==0) buf[pos++]='.';
    f=f*10.0;
    dp--;
    }
    return buf;
    }
    
    
    void MPU6050Example(void) {
      float fAccel[3], fGyro[3];
      tMPU6050 sMPU6050;
    
      UARTprintf("MPU6050 initialization\n");
       // Write two bytes of data to the I2C device at address 0x3C.
      g_bMPU6050Done = false;
      uint_fast8_t result = MPU6050Init(&sMPU6050, &g_sI2CMSimpleInst, 0x68, MPU6050Callback1, 0);
     while(!g_bMPU6050Done)
     {
     }
    
      UARTprintf("Configure the MPU6050 for +/- 4 g accelerometer range\n");
      // Read four bytes of data from the I2C device at address 0x3C.
      g_bMPU6050Done = false;
      MPU6050ReadModifyWrite(&sMPU6050, MPU6050_O_ACCEL_CONFIG, ~MPU6050_ACCEL_CONFIG_AFS_SEL_M,
      MPU6050_ACCEL_CONFIG_AFS_SEL_4G, MPU6050Callback1, 0);
      while(!g_bMPU6050Done) {
      }
    
      // loop forever reading data from the MPU6050
      while(1) {
        // Request another reading from the MPU6050
        g_bMPU6050Done = false;
        MPU6050DataRead(&sMPU6050, MPU6050Callback1, 0);
        while(!g_bMPU6050Done) {
       }
    
        // Get the new accelerometer and gyroscope readings.
        MPU6050DataAccelGetFloat(&sMPU6050, &fAccel[0], &fAccel[1], &fAccel[2]);
        MPU6050DataGyroGetFloat(&sMPU6050, &fGyro[0], &fGyro[1], &fGyro[2]);
    
       // UARTprintf("complete data receive from MPU6050\n");
        UARTprintf("Accel x = %s", ftoa(fAccel[0]));
        UARTprintf(", y = %s", ftoa(fAccel[1]));
        UARTprintf(", z = %s\n", ftoa(fAccel[2]));
       UARTprintf("Gyro x = %s", ftoa(fGyro[0]));
        UARTprintf(", y = %s", ftoa(fGyro[1]));
        UARTprintf(", z = %s\n", ftoa(fGyro[2]));
    
        //DelaySoft(1000);
      }
    }
    
    int main()
    {
      //
      // Setup the system clock to run at 40 MHz from PLL with crystal reference
      //
      SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
    
      // UARTprintf()
      ConfigureUART();
    
      // Print start
      UARTprintf("\nConfigure UART\n");
    
      InitI2C0();
    
      MPU6050Example();
    
      return(0);
    }
    

    .

    I'm getting static values.

  • m_vedsharma said:
    I'm getting static values.

    Even "static values" may prove, "Suspect Values."

    Have you examined the "most basic reasons for such,  "Static Readings?"

    Such should prove a good exercise for you - and your "review" should enable you to, "Add code which insures that your program performs, "Regular & Repeated Readings!"

    The vendor's program is a HUGE VIOLATION of  "KISS"  - too many functions - and with such bulk - any source of error(s) is "bound to be difficult to discover!"

    How can you, "Reduce & Simplify" that program?     And - would it not prove useful to employ "known, fixed values (not those "achieved from any sensor") - at least at this early "test stage" - so that you can "better understand" the program's "flow & objectives?"

    Complexity  IMPEDES - rather than ENHANCES - Understanding - does it not?

  • Hello m_vedsharma,

    I had inquired in my first response "Have you attempted to use the example as is to start, and if so, were you success in reading data out?" - did you have a chance to try this? That changing that one feature to be inside the API seems to have resulted in a positive point of progress. I had been wondering about the I2C portion as well, I feel like that could be not working as you desire since the structure isn't volatile but it is being used in an ISR.

    Looking into the details of what sensorlib provides, I would say you shouldn't have this line called after I2CMInit, that API handles this:

    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), true);

    Also I don't think you should have the following done:

    //
    // The interrupt handler for the I2C module.
    //
    void I2CMSimpleIntHandler(void)
    {
      //
      // Call the I2C master driver interrupt handler.
      //
      I2CMIntHandler(&g_sI2CMSimpleInst);
    }
    

    Rather I believe you should just directly add the I2CMIntHandler to your startup_ccs.c file:

    	I2CMIntHandler,                      // I2C0 Master and Slave

    That will allow you to not need the sI2CInst to need to be a global variable.

    You'd need to #include the i2cm_drv.h file in startup_ccs.c as well.