CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

i2c MPU-6050
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Thu Sep 18, 2014 1:21 pm     Reply with quote

hi guys. I was reading the data sheet than suddenly i saw that when power ups , chip is in sleep mode....

Code:
4 Register Descriptions
This section describes the function and contents of each register within the MPU-60X0.
Note: The device will come up in sleep mode upon power-up.


So i decided to configure the gyro but i got the same results....

Code:
#include <16f877a.h>

#fuses hs,nowrt,nowdt,nodebug,brownout,nolvp,nocpd,put,noprotect
#use delay (clock=20000000)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, SMBUS)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, errors)

#define LCD_ENABLE_PIN  PIN_B0            //#define use_portb_lcd TRUE                   
#define LCD_RS_PIN      PIN_B1                                   
#define LCD_RW_PIN      PIN_B2                                     
#define LCD_DATA4       PIN_B4                                     
#define LCD_DATA5       PIN_B5                                   
#define LCD_DATA6       PIN_B6                                   
#define LCD_DATA7       PIN_B7

#include <lcd.c>     // For LCD and has to be after #use delay()

#define MPU6050_SLAVE_WRT     0xD0
#define MPU6050_SLAVE_RD      0xD1
#define MPU6050_GYRO_CONFIG   0x1B // 0xE0
#define MPU6050_PWR_MGMT_1    0x6B // 0x80
#define MPU6050_WHO_AM_I      0X75
#define GYRO_XOUT_H  0x43
#define GYRO_XOUT_L  0x44

int8 lsb=0, msb=0;
int16 retval=0;

int16 MPU6050_read_word(int8 reg_addr)
{
 
i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(reg_addr);
i2c_start();
i2c_write(MPU6050_SLAVE_RD);
msb = i2c_read();   // Read MSB byte first.
lsb = i2c_read(0);  // Do a NACK on the last read
i2c_stop();   

retval = make16(msb, lsb);

return(retval);
}

void main()
{
   int16 x_gyro;
   int x=0;
   lcd_init();
   delay_ms(1000);
   printf(lcd_putc,"Ready");
   delay_ms(1000);
   
   i2c_start();
   i2c_write(MPU6050_SLAVE_WRT);
   i2c_write(MPU6050_WHO_AM_I);
   i2c_start();
   i2c_write(MPU6050_SLAVE_RD);
   x = i2c_read(0);   // Read MSB byte first.
   i2c_stop();
   
   delay_ms(500);
   printf(lcd_putc,"\f0x%X", x);
   delay_ms(500);
   
   printf(lcd_putc,"\fReseting");
   delay_ms(500);
     
   i2c_start();
   i2c_write(MPU6050_SLAVE_WRT);
   i2c_write(MPU6050_PWR_MGMT_1);
   i2c_write(0x20);
   i2c_stop();
     
   printf(lcd_putc,"\fConfigurating");
   delay_ms(500);
     
   i2c_start();
   i2c_write(MPU6050_SLAVE_WRT);
   i2c_write(MPU6050_GYRO_CONFIG);
   i2c_write(0xE0);
   i2c_stop();
     
      while (true)
      {
         x_gyro = MPU6050_read_word(GYRO_XOUT_H);
         printf(lcd_putc,"\fG=0x%X", x_gyro);
         delay_ms(500);
         printf(lcd_putc,"\fL=0x%X", lsb);
         delay_ms(500);
         printf(lcd_putc,"\fM=0x%X", msb);
         delay_ms(500);
       
         printf(lcd_putc,"\fG2=%lu", x_gyro);
         delay_ms(500);
         printf(lcd_putc,"\fL2=%u", lsb);
         delay_ms(500);
         printf(lcd_putc,"\fM2=%u", msb);
         delay_ms(500);
      }
}
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Fri Sep 19, 2014 9:24 am     Reply with quote

It's SOLVED....
As i said , we needed to wake it up by:
Code:

   i2c_start();
   i2c_write(MPU6050_SLAVE_WRT);
   i2c_write(MPU6050_PWR_MGMT_1);
   i2c_write(0x00);
   i2c_stop();
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Mon Sep 22, 2014 7:18 am     Reply with quote

Ok. So I have a new problem. How can I calculate the degrees with data I have???
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Sep 22, 2014 9:38 am     Reply with quote

Maybe read the manual or datasheet for your device????

I don't have your exact part and there is no 'standard' for data so you're best to read the datasheet for your device.They will have all the details for you, probably an example or two as well.

All else fails ask 'google' !!

jay
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Mon Sep 22, 2014 12:09 pm     Reply with quote

Thanks but all the "examples" in "google" are for arduino!!! I read the datasheet at least 5 times and this far I could do. I didn't understand all the data sheet so this is why I am asking.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 22, 2014 12:32 pm     Reply with quote

Not all of it. Just do a Google search like this:
Quote:
mpu6050 angle atan -arduino

I know from the literature that the atan() function is used in the angle
calculation code, so I search for that, and tell Google to exclude all
pages that reference the Arduino.

For example, this code uses the Microchip C30 compiler:
http://www.botched.co.uk/pic-tutorials/mpu6050-setup-data-aquisition/
https://github.com/big5824/Quadrocopter/blob/master/MPU6050.c

And even if you do find Arduino code, the calculations are pure C.
There's no "wire.xxx" stuff involved in atan() math, etc.
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Mon Sep 22, 2014 12:38 pm     Reply with quote

Thanks PCM. I will check them now. I hope you get your gyro. Smile
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 22, 2014 12:45 pm     Reply with quote

I have it. But you said you solved your problem (re power-down mode)
so I didn't do anything with the board yet.
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Mon Sep 22, 2014 2:21 pm     Reply with quote

Yes your right. I thought that it will be easy to calculate the angle and etc. but it has lots of noises and i don't know how to calculate the angle.
Ps: the links that you posted i have already read them before but....
still nothing... :(
So am waiting for your response and i read in datasheet that mpu6050 gives 5 volt in i2c so it is working with 16f877a.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 23, 2014 12:40 pm     Reply with quote

I translated some of the code in those links to CCS last night, and I got it
to work in a basic way. It puts out X and Y angles on TeraTerm. If I lift
up one edge of the little board, the Y value goes negative and becomes
more negative as I increase the angle. If I lay the board down again and
slowly rotate up the opposite edge, the Y value is a positive number and
increases as I rotate the board edge upwards. The same thing occurs on
the X-axis.

So it's basically working. But I didn't do any quantitative measurements.
I didn't lay the board against a protractor and try to judge if the reported
angle is perfectly accurate. There is also some noise. I did not
implement any filtering algorithms.

There are other ways to do it. This guy is using the internal processor
of the MPU-6050 to do the calculations. This might be a better approach.
http://davidegironi.blogspot.com/2013/02/avr-atmega-mpu6050-gyroscope-and.html#.VCG4KFNhDn4

I am not quadcopter developer. I've never made one. I'm just trying to
get your code to compile and work, somewhat. I don't want to do your
project for you.
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Tue Sep 23, 2014 11:49 pm     Reply with quote

Hi PCM. You are the greatest. Can you post the code you did. I want to see where I was wrong. I think I couldn't do the configuration right. I made some calculations and add timer1 to get angle but I didn't succeed. I promise I don't want you to do my project.
Thanks.
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Thu Sep 25, 2014 11:50 am     Reply with quote

Anyone? ??
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Thu Sep 25, 2014 11:55 am     Reply with quote

As a comment, do a search in this forum, for atan2.

This is the function most suited to converting two axis data into an angle. The CCS version has problems in some compiler versions, and I published a version that is smaller, faster, and works well for exactly this type of application.

Then search for 'Olympic average'. This is ideal for the sort of noise generated by this type of gyro.
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Thu Sep 25, 2014 12:05 pm     Reply with quote

Thanks. I am not sure about configuration of the gyro. And I don't know the formula to convert the data I get from gyro to angle. Atan is math calculation if I am not wrong. The thing is which data I need to use.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 25, 2014 12:20 pm     Reply with quote

Here is the ported code from the links I posted. This code does not use
the internal DMP mpu6050 to do the calculations. The calculations are
done in the PIC with the following code.

Here's the sample output I got. As I lift up one side of the mpu6050
board, the Y angle increases:
Quote:

Gyro X offset sum: -234453 Gyro X offset: -234
Gyro Y offset sum: 138770 Gyro Y offset: 138
Gyro Z offset sum: -78797 Gyro Z offset: -78
accel_xangle = 0
accel_yangle = 3

accel_xangle = 0
accel_yangle = 3

accel_xangle = 0
accel_yangle = 3

accel_xangle = 0
accel_yangle = 3

accel_xangle = 0
accel_yangle = 16

accel_xangle = 0
accel_yangle = 36

accel_xangle = 0
accel_yangle = 84


Test program:
Code:
#include <18F4620.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(internal=32M)
#use rs232(baud=9600, UART1, ERRORS)

// I'm using software i2c on these pins for the mpu6050
// because the hardware pins on C3 and C4 are already
// in use on my development board.
#use i2c(Master, scl=PIN_C0, sda=PIN_C1)

#include <math.h>

#define MPU6050_SLAVE_WRT  0xD0
#define MPU6050_SLAVE_RD   0xD1

// Register addresses
#define MPU6050_WHO_AM_I     0x05
#define MPU6050_SMPLRT_DIV   0x19
#define MPU6050_CONFIG       0x1A
#define MPU6050_GYRO_CONFIG  0x1B 
#define MPU6050_PWR_MGMT_1   0x6B 

#define ACCEL_XOUT_H  0x3B
#define ACCEL_XOUT_L  0x3C
#define ACCEL_YOUT_H  0x3D
#define ACCEL_YOUT_L  0x3E
#define ACCEL_ZOUT_H  0x3F
#define ACCEL_ZOUT_L  0x40

#define GYRO_XOUT_H  0x43
#define GYRO_XOUT_L  0x44
#define GYRO_YOUT_H  0x45
#define GYRO_YOUT_L  0x46
#define GYRO_ZOUT_H  0x47
#define GYRO_ZOUT_L  0x48


// In the +/- 500 degrees mode, the gyro sensitivity is 65.5 LSB/dps.
#define gyro_xsensitivity 66.5 //66.5 Dead on at last check
#define gyro_ysensitivity 66.5 //72.7 Dead on at last check
#define gyro_zsensitivity 65.5
#define a 0.01
#define dt 0.0025

// Global variables
float gyro_xrate;
float gyro_yrate;
float gyro_zrate;
//int16 gyro_xrateraw;
//int16 gyro_yrateraw;
//int16 gyro_zrateraw;
signed int16 gyro_xout;
signed int16 gyro_yout;
signed int16 gyro_zout;   
signed int16 accel_xout;
signed int16 accel_yout;
signed int16 accel_zout;

signed int16 gyro_xout_offset;
signed int16 gyro_yout_offset;
signed int16 gyro_zout_offset;
signed int32 gyro_xout_offset_1000sum;
signed int32 gyro_yout_offset_1000sum;
signed int32 gyro_zout_offset_1000sum;

float gyro_xangle;
float gyro_yangle;
float gyro_zangle;
//int32 gyro_xangleraw;
//int32 gyro_yangleraw;
//int32 gyro_zangleraw;
float accel_xangle;
float accel_yangle;
//float accel_zangle;
//float kalman_xangle;
//float kalman_yangle;
//float kalman_zangle;

//--------------------------------------------------
int16 MPU6050_read_word(int8 reg_addr)
{
int8 lsb, msb;
int16 retval;

i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(reg_addr);
i2c_start();
i2c_write(MPU6050_SLAVE_RD);
msb = i2c_read();   // Read MSB byte first.
lsb = i2c_read(0);  // Do a NACK on the last read
i2c_stop();   

retval = make16(msb, lsb);

return(retval);
}

//------------------------------------------------------
void Get_Accel_Values()
{
accel_xout = MPU6050_read_word(ACCEL_XOUT_H);
accel_yout = MPU6050_read_word(ACCEL_YOUT_H);
accel_zout = MPU6050_read_word(ACCEL_ZOUT_H);
}   

//----------------------------
void Get_Gyro_Rates()
{
gyro_xout = MPU6050_read_word(GYRO_XOUT_H) - gyro_xout_offset;
gyro_yout = MPU6050_read_word(GYRO_YOUT_H) - gyro_yout_offset;
gyro_zout = MPU6050_read_word(GYRO_ZOUT_H) - gyro_zout_offset;

gyro_xrate = (float)gyro_xout/gyro_xsensitivity;
gyro_yrate = (float)gyro_yout/gyro_ysensitivity;
gyro_zrate = (float)gyro_zout/gyro_zsensitivity;

gyro_xangle += gyro_xrate * dt;
gyro_yangle += gyro_yrate * dt;
gyro_zangle += gyro_zrate * dt;
}

//-----------------------------------------
void Get_Accel_Angles()
{
accel_xangle = 57.295*atan((float)accel_yout/ sqrt(pow((float)accel_zout,2)+pow((float)accel_xout,2)));
accel_yangle = 57.295*atan((float)-accel_xout/ sqrt(pow((float)accel_zout,2)+pow((float)accel_yout,2)));
}   

//--------------------------------------------------
void Calibrate_Gyros()
{
int16 x = 0;


gyro_xout_offset_1000sum = 0;
gyro_yout_offset_1000sum = 0;
gyro_zout_offset_1000sum = 0;

for(x=0; x<1000; x++)
   {
    gyro_xout = MPU6050_read_word(GYRO_XOUT_H);
    gyro_yout = MPU6050_read_word(GYRO_YOUT_H);
    gyro_zout = MPU6050_read_word(GYRO_ZOUT_H);

    gyro_xout_offset_1000sum += gyro_xout;
    gyro_yout_offset_1000sum += gyro_yout;
    gyro_zout_offset_1000sum += gyro_zout;

    delay_ms(1);
   }   

gyro_xout_offset = gyro_xout_offset_1000sum/1000;
gyro_yout_offset = gyro_yout_offset_1000sum/1000;
gyro_zout_offset = gyro_zout_offset_1000sum/1000;

printf("Gyro X offset sum: %ld Gyro X offset: %ld \n\r", gyro_xout_offset_1000sum, gyro_xout_offset);
printf("Gyro Y offset sum: %ld Gyro Y offset: %ld \n\r", gyro_yout_offset_1000sum, gyro_yout_offset);
printf("Gyro Z offset sum: %ld Gyro Z offset: %ld \n\r", gyro_zout_offset_1000sum, gyro_zout_offset);
}   

//--------------------------------------------
#define BW_256_HZ 0
#define BW_10_HZ  5
#define BW_5_HZ   6

void set_DLPF(int8 bandwidth)
{
i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(MPU6050_CONFIG);
i2c_write(bandwidth);
i2c_stop();
}

//--------------------------------------------
void Setup_mpu6050(void)
{
delay_ms(100);

i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(MPU6050_PWR_MGMT_1);
i2c_write(0x00);
i2c_stop();

i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(MPU6050_GYRO_CONFIG);
i2c_write(0x08);
i2c_stop();

i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(MPU6050_SMPLRT_DIV);   
i2c_write(0x07);
i2c_stop();

delay_ms(100);  // Gyro start-up time is 30ms after power-up.
}
//------------------------------------------------


//===================================
void main()
{
Setup_mpu6050();   

Calibrate_Gyros();

//set_DLPF(BW_5_HZ);

while(TRUE)
  {
   Get_Accel_Values();
   Get_Gyro_Rates();
   Get_Accel_Angles();

   printf("accel_xangle = %7.0f \n\r", accel_xangle);
   printf("accel_yangle = %7.0f \n\r", accel_yangle);
   printf("\n\r");
   delay_ms(2000);
  }


while(1);
}



This code is not mine. I just ported it to CCS. I don't want to trouble-
shoot the code. I don't want to explain it. I just wanted to get you going
on your project.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group