EmbeddedRelated.com
Forums

Why is the raw data from mpu6050 always constant?

Started by captain_aaloo 5 years ago1 replylatest reply 5 years ago602 views

I'm trying to interface mpu6050 module with pic16f886 microcontroller. But, i'm getting x-axis, y-axis and z-axis as 0 and the raw data on all the axis as 255. Why is there no change in readings even when i move/rotate my mpu? 

Below's the images for x,y,z readings on all 3 axis and raw data .

aaaaaaaaaaaaa_10288.png



bbbbb_37339.png


source.c

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "all_header.h"0 
#define _XTAL_FREQ 4000000
#define I2C_SPEED 100000
#define baud 9600

void usart_init(){
    TRISC6=0;
    TRISC7=1;
//    SPBRG=_XTAL_FREQ/(16*baud) -1;
    SPBRG=25;                                                                   //pg.no - 163
    TXSTAbits.BRGH=1;
    TXSTAbits.SYNC=0;
    RCSTAbits.SPEN=1;
    TXSTAbits.TXEN=1;
    RCSTAbits.CREN=1;
    TXSTAbits.TX9=0;
    RCSTAbits.RX9=0;
    RCSTAbits.FERR = 0;     // Disable framing error
    RCSTAbits.OERR = 0;     // Disable overrun error
    
}


void usart_send_byte(char bt){
    while(TXIF==0);
    TXREG=bt;
}




void usart_send_string(char* str) {
    while(*str!= '\0')
        usart_send_byte(*str++);
}


//i2c


void i2c_init(void){
    TRISC3=1;
    TRISC4=1;
    
    SSPADD= ((_XTAL_FREQ/4)/I2C_SPEED)-1;
    SSPSTAT=0x80;
    SSPCON=0x28;
    SSPCON2=0x00;
}


void i2c_start_write(char slave_add){
    SSPCON2bits.SEN = 1;            /* Send START condition */
    while(SSPCON2bits.SEN);         /* Wait for completion of START */
    i2c_write(slave_add);           /* Write slave device address with write to communicate */
    
}


void i2c_stop(void){
    SSPCON2bits.PEN=1;
    while(!SSPIF);
    SSPIF=0;
}


void i2c_write(unsigned char data){
    SSPBUF=data;
    while(!SSPIF);
    SSPIF=0;
  
}


unsigned char i2c_read(unsigned ack){
    SSPCON2bits.RCEN=1;
    while(!SSPIF);
    SSPIF=0;
   
    return SSPBUF;
}




void mpu_init(){
     
    i2c_start_write(0xD0);                                                      //slave write address
    i2c_write(SMPLRT_DIV);                                                      //write to sample rate register(write to this address)
    i2c_write(0x07);                                                            //100KHZ sample rate(write to data)
    i2c_stop();
    
    i2c_start_write(0xD0);                                                      //slave write address
    i2c_write(PWR_MGMT_1);
    i2c_write(0x01);                                                            //x-axis gyro reference frequency
    i2c_stop();
    
    i2c_start_write(0xD0);                                                      //slave write address
    i2c_write(CONFIG);
    i2c_write(0x01);                                                            //fs=1KHZ
    i2c_stop();
    
    i2c_start_write(0xD0);                                                      //slave write address
    i2c_write(GYRO_CONFIG);
    i2c_write(0x18);                                                            //full scale range +/- 2000 deg/c
    i2c_stop();
    
    i2c_start_write(0xD0);                                                      //slave write address
    i2c_write(INT_ENABLE);
    i2c_write(0x01);
    i2c_stop();
}






void main(){


    char buffer[20];
    int  xh,xl,yh,yl,zh,zl,ax,ay,az;
    float xa,ya,za;
    OSCCON=0x64;                                                                
    usart_init();
    i2c_init();
    mpu_init();




    // Read accelerometer values out from H and L registers
    while(1){
    i2c_start_write(0xD0);
    i2c_write(ACCEL_XOUT_H);
    i2c_write(0xD1);
    xh=i2c_read(0);
    i2c_stop();
    
    i2c_start_write(0xD0);
    i2c_write(ACCEL_XOUT_L);
    i2c_write(0xD1);
    xl=i2c_read(0);
    i2c_stop();
    
    i2c_start_write(0xD0);
    i2c_write(ACCEL_YOUT_H);
    i2c_write(0xD1);
    yh=i2c_read(0);
    i2c_stop();
    
    i2c_start_write(0xD0);
    i2c_write(ACCEL_YOUT_L);
    i2c_write(0xD1);
    yl=i2c_read(0);
    i2c_stop();
    
    i2c_start_write(0xD0);
    i2c_write(ACCEL_ZOUT_H);
    i2c_write(0xD1);
    zh=i2c_read(0);
    i2c_stop();
    
    i2c_start_write(0xD0);
    i2c_write(ACCEL_ZOUT_L);
    i2c_write(0xD1);
    zl=i2c_read(0);
    i2c_stop();
    
    
    // Convert received data
    ax = ( xh<<8 | xl );
    ay= ( yh<<8 | yl );
    az = ( zh<<8 | zl );
    
    xa =(float)ax/16384.0;
    ya =(float)ay/16384.0;
    za =(float)az/16384.0;
    
        sprintf(buffer,"ax=%d g\r\n",xh);                                       //Take values in buffer and send it over to Usart
        usart_send_string(buffer);
        
        sprintf(buffer,"ay=%d g\r\n",yh);                                       
        usart_send_string(buffer);
        
        sprintf(buffer,"az=%d g\r\n",zh);                                       
        usart_send_string(buffer);
        
        sprintf(buffer,"axxxx=%d g\r\n",xl);                                       //Take values in buffer and send it over to Usart
        usart_send_string(buffer);
        
        sprintf(buffer,"ayyyy=%d g\r\n",yl);                                       
        usart_send_string(buffer);
        
        sprintf(buffer,"azzzz=%d g\r\n",zl);                                       
        usart_send_string(buffer);
    
    }

[ - ]
Reply by mr_banditFebruary 5, 2019

Do you have an oscope? Can you look at the I2C bus? can you look at the UART bus? Does your serial (RS232) bus have a level shifter, like a MAX3232?

Start with a simple I2C device, like https://www.digikey.com/product-detail/en/sparkfun...  This will tell you your I2C bus is working correctly. Read the temperature sensor in a loop. This is a great little test. That sensor is rather sensitive - touch the sensor with your finger && you can see the RAW value increase. (Be careful about static control.)

Get an Arduino with a spare serial port. (or use USB as a serial port to your PC, with the hardware serial port free to use). The MEGA has 4 serial ports. Use the Arduino serial RS232 library. For this test, keep things at the TTL level - with the same voltage (5 or 3.3, but do not mix!) Make the Arduino the RX side and your micro the TX side. The Arduino should read from the serial port and write the HEX values to the console. Once that works, reverse the direction - the Arduino is sending bytes, your system is receiving. Verify that works.

Good values to send are x55, xAA, x5A, xA5 : write the bit patterns && you can see why. Easy to see on an oscope.