2 Replies Latest reply on Jan 31, 2017 6:08 AM by user_376040860

    C programming problem with MPU-6050

    user_376040860

      Below is the main.c portion of two programs that I've combined and included in the uploaded project that I'm having trouble with. The two programs are a ble demo app that shows capsense data and the other is a larger project that grabs i2s data from a mpu-6050. Both of these programs work independently. The program that I've included has the portion where it grabs the I2C data commented out and the ble and capsense work as expected. If I try to grab the i2c data the ble seams to work but the capsense stops updating. Also if I just try to serial data out the capsense stops working. I think it might be an interrupt problem but my programming skills are weak...

         

      The device I am using is a CYBLE-222005 I'm pretty sure I have the pins defined correctly. I'm using a PSOC 4 042 BLE dev kit.

         

      Any help would be greatly appreciated.

         

       

         

      /******************************************************************************
      * Project Name        : PRoC_BLE_CapSense_Proximity
      * File Name            : main.c
      * Version             : 1.0
      * Device Used        : CYBL10563-56LQXI
      * Software Used        : PSoC Creator 3.3 SP1
      * Compiler            : ARM GCC 4.9.3, ARM MDK Generic
      * Related Hardware    : CY8CKIT-042-BLE Bluetooth Low Energy Pioneer Kit
      * Owner                : ROIT
      *
      ********************************************************************************
      * Copyright (2015-16), Cypress Semiconductor Corporation. All Rights Reserved.
      ********************************************************************************

      *
      * Use of this Software may be limited by and subject to the applicable Cypress
      * software license agreement.
      *******************************************************************************/
      ******************************************************************************/
      #include <main.h>
      #include <project.h>
      #include "mpu6050.h"
      #include <stdio.h>

         

      void I2CReadBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *value) {
          uint8_t i=0;
          I2C_MPU6050_I2CMasterSendStart(devAddr, I2C_MPU6050_I2C_WRITE_XFER_MODE);
          I2C_MPU6050_I2CMasterWriteByte(regAddr);
          I2C_MPU6050_I2CMasterSendRestart(devAddr, I2C_MPU6050_I2C_READ_XFER_MODE);
          while (i++ < (length-1)) {
              *value++ = I2C_MPU6050_I2CMasterReadByte(I2C_MPU6050_I2C_ACK_DATA);
          }
          *value = I2C_MPU6050_I2CMasterReadByte(I2C_MPU6050_I2C_NAK_DATA);
          I2C_MPU6050_I2CMasterSendStop();    
      }

         

      void I2CReadByte(uint8_t devAddr, uint8_t regAddr, uint8_t *value) {
          I2CReadBytes(devAddr, regAddr, 1, value);
      }

         

      void I2CReadBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *value) {
             uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
          I2CReadByte(devAddr, regAddr, value);
          *value &= mask;
          *value >>= (bitStart - length + 1);
      }

         

      void I2CReadBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *value) {
          I2CReadByte(devAddr, regAddr, value);
          *value = *value & (1 << bitNum);
      }
          
      void I2CWriteBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *value) {
          uint8_t i=0;
          I2C_MPU6050_I2CMasterSendStart(devAddr, I2C_MPU6050_I2C_WRITE_XFER_MODE);
          I2C_MPU6050_I2CMasterWriteByte(regAddr);
          while (i++ < length) {
              I2C_MPU6050_I2CMasterWriteByte(*value++);
          }
          I2C_MPU6050_I2CMasterSendStop();    
      }

         

      void I2CWriteByte(uint8_t devAddr, uint8_t regAddr, uint8_t value) {
          I2CWriteBytes(devAddr, regAddr, 1, &value);
      }

         

      void I2CWriteBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t value) {
          uint8_t b;
          uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
          I2CReadByte(devAddr, regAddr, &b);
          value <<= (bitStart - length + 1);
          value &= mask;
          b &= ~(mask);
          b |= value;
          I2CWriteByte(devAddr, regAddr, b);    
      }

         

      void I2CWriteBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t value) {
          uint8_t b;
          I2CReadByte(devAddr, regAddr, &b);
          b = (value != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
          I2CWriteByte(devAddr, regAddr, b);
      }

         

      void I2CWriteWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *value) {
          uint8_t i=0;
          I2C_MPU6050_I2CMasterSendStart(devAddr, I2C_MPU6050_I2C_WRITE_XFER_MODE);
          I2C_MPU6050_I2CMasterWriteByte(regAddr);
          while (i++ < length) {
              I2C_MPU6050_I2CMasterWriteByte(((uint8_t)*value) >> 8);
              I2C_MPU6050_I2CMasterWriteByte((uint8_t)*value++);
          }
          I2C_MPU6050_I2CMasterSendStop();        
      }

         

      void I2CWriteWord(uint8_t devAddr, uint8_t regAddr, uint16_t value) {
          I2CWriteWords(devAddr, regAddr, 1, &value);
      }

         

       

         

      /*'deviceConnected' flag is used by application to know whether a Central device  
      * has been connected. This is updated in BLE event callback */
      extern uint8 deviceConnected;

         

      /*'startNotification' flag is set when the central device writes to CCC (Client  
      * Characteristic Configuration) of the CapSense proximity characteristic to
      * enable notifications */
      extern uint8 startNotification;    

         

      /* 'restartAdvertisement' flag is used to restart advertisement */
      extern uint8 restartAdvertisement;

         

      /* 'initializeCapSenseBaseline' flag is used to call the function once that initializes
      * all CapSense baseline. The baseline is initialized when the first advertisement
      * is started. This is done so that any external disturbance while powering the kit does
      * not infliuence the baseline value, that may cause wrong readings. */
      uint8 initializeCapSenseBaseline = TRUE;

         

      /*******************************************************************************
      * Function Name: main
      ********************************************************************************
      * Summary:
      *        System entrance point. This calls the BLE routine functions as well as
      * function for handling CapSense Proximity changes
      *
      * Parameters:
      *  void
      *
      * Return:
      *  int
      *

         

      *******************************************************************************/
      int main()
      {
          
          int16_t ax, ay, az;
          int16_t gx, gy, gz;
          char buf[30];

         

          I2C_MPU6050_Start();
          SERIAL_Start();////////////////////////////////////////////////////////////////////////////////
          
          CyGlobalIntEnable;

         

          MPU6050_init();
          MPU6050_initialize();
          SERIAL_UartPutString(MPU6050_testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
          
          
          
          /* This function will initialize the system resources such as BLE and CapSense */
          InitializeSystem();
          
          for(;;)
          {
              
         /*     MPU6050_getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
              SERIAL_UartPutString("a/g:\t");
              sprintf(buf, "%d \t", ax);
              SERIAL_UartPutString(buf);
              sprintf(buf, "%d \t", ay);
              SERIAL_UartPutString(buf);
              sprintf(buf, "%d \t", az);
              SERIAL_UartPutString(buf);
              sprintf(buf, "%d \t", gx);
              SERIAL_UartPutString(buf);
              sprintf(buf, "%d \t", gy);
              SERIAL_UartPutString(buf);
              sprintf(buf, "%d \t", gz);
              SERIAL_UartPutString(buf);
              SERIAL_UartPutString("\n\r");
           */  
              /*Process Event callback to handle BLE events. The events generated and
              * used for this application are inside the 'CustomEventHandler' routine*/
              CyBle_ProcessEvents();
              
              /* Function to handle LED status depending on BLE state */
              HandleStatusLED();
              
              /* Handle proximity data and CCCD value update only if BLE device is connected */
              if(TRUE == deviceConnected)
              {
                  /* After the connection, send new connection parameter to the Client device
                  * to run the BLE communication on desired interval. This affects the data rate
                  * and power consumption. High connection interval will have lower data rate but
                  * lower power consumption. Low connection interval will have higher data rate at
                  * expense of higher power. This function is called only once per connection. */
                  UpdateConnectionParam();
                  
                  /* If CapSense Initialize Baseline API has not been called yet, call the
                  * API and reset the flag. */
                  if(initializeCapSenseBaseline)
                  {
                      /* Reset 'initializeCapSenseBaseline' flag*/
                      initializeCapSenseBaseline = FALSE;
                      
                      /* Initialize all CapSense Baseline */
                      CapSense_InitializeAllBaselines();
                  }
                  
                  /* Send proximity data when notifications are enabled */
                  if(startNotification == CCCD_NTF_BIT_MASK)
                  {
                      if(CYBLE_BLESS_STATE_ECO_STABLE ==CyBle_GetBleSsState())
                      {
                          /*Check for CapSense proximity change and report to BLE central device*/
                          HandleCapSenseProximity();
                          SERIAL_UartPutString("a/g:\t");
                      }
                  }
              }

         

              #ifdef ENABLE_LOW_POWER_MODE
                          
                  /* Put system to Deep sleep, including BLESS, and wakeup on interrupt.
                  * The source of the interrupt can be either BLESS Link Layer in case of
                  * BLE advertisement and connection or by User Button press during BLE
                  * disconnection */
                  HandleLowPowerMode();//////////////////////////////////////////////////////////////////////////////////
              #endif
              
              if(restartAdvertisement)
              {
                  /* Reset 'restartAdvertisement' flag*/
                  restartAdvertisement = FALSE;

         

                  /* Start Advertisement and enter Discoverable mode*/
                  CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);    
                  
              }
          }    /* This is end of for(;;) */
      }

         

      /*******************************************************************************
      * Function Name: InitializeSystem
      ********************************************************************************
      * Summary:
      *        Starts the components and initializes CapSense baselines
      *
      * Parameters:
      *  void
      *
      * Return:
      *  void
      *

         

      *******************************************************************************/
      void InitializeSystem(void)
      {
          /* Enable global interrupt mask */
          CyGlobalIntEnable;

         

          /* Start BLE component and register the CustomEventHandler function. This
          * function exposes the events from BLE component for application use */
          CyBle_Start(CustomEventHandler);                    
          
          /* Set drive mode of the status LED pin to Strong*/
          Status_LED_SetDriveMode(Status_LED_DM_STRONG);    
          
          #ifdef CAPSENSE_ENABLED
          /* Enable the proximity widget explicitly and start CapSense component.
          * Initialization of the baseline is done when the connection happens */
          CapSense_EnableWidget(CapSense_PROXIMITYSENSOR0__PROX);
          CapSense_Start();
          #endif
              
          /* Start the Button ISR to allow wakeup from sleep */
          isr_button_StartEx(MyISR);
      }

         

      /*******************************************************************************
      * Function Name: HandleCapSenseProximity
      ********************************************************************************
      * Summary:
      *       Read the proximity data from the sensor and update the BLE
      *        custom notification value.
      *
      * Parameters:
      *  void
      *
      * Return:
      *  void
      *
      *******************************************************************************/
      void HandleCapSenseProximity(void)
      {
          #ifdef CAPSENSE_ENABLED        
          /* Static variable to store last proximity value */
          static uint8 lastProximityValue = MAX_PROX_VALUE;
              
          /* 'proximityValue' stores the proximity value read from CapSense component */
          uint8 proximityValue;    
              
          /* Scan the Proximity Widget */
          CapSense_ScanWidget(CapSense_PROXIMITYSENSOR0__PROX);                
          
          /* Wait for CapSense scanning to be complete. This could take about 5 ms */
          while(CapSense_IsBusy())
          {
              #ifdef ENABLE_LOW_POWER_MODE
              /* While CapSense is scanning, put CPU to sleep to conserve power */
              CySysPmSleep();/////////////////////////////////////////////////////////////////////////////
              #endif
          }
          
          /* Update CapSense Baseline */
          CapSense_UpdateEnabledBaselines();            

         

          /* Get the Diffcount between proximity raw data and baseline */
          proximityValue = CapSense_GetDiffCountData(CapSense_PROXIMITYSENSOR0__PROX);
          
          /* Check if the proximity data is different from previous */
          if(lastProximityValue != proximityValue)                
          {
              /* Send the proximity data to BLE central device by notifications*/
              SendDataOverCapSenseNotification(proximityValue);
              
              /* Update present proximity value */
              lastProximityValue = proximityValue;                    
          }
          #endif
      }

         

      /* [] END OF FILE */

        • 1. Re: C programming problem with MPU-6050
          hima

          Hello,

             

           

             

          Are you able to see the UART data? Can you please try increasing the heap size and test the code?

             

           

             

          Thanks,

             

          Hima

          • 2. Re: C programming problem with MPU-6050
            user_376040860

            Hello Hima

               

            Thank you very much for your response. I've increased the heap size and I've moved some code around and I'm now able to get some i2c data printed to the serial port as well as the capsense working through the ble to my phone. The serial data is being corrupted a bit, I'm sure it some slight timing issus, not with the serial port but it being interupted somehow. I'll play with it. Thanks very much for the heap size suggestion as I think that got me to where I am.

               

            Regards,

               

            Kevin