|
|
View previous topic :: View next topic |
Author |
Message |
Ruby
Joined: 04 Jul 2014 Posts: 44
|
|
Posted: Thu Sep 18, 2014 1:21 pm |
|
|
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
|
|
Posted: Fri Sep 19, 2014 9:24 am |
|
|
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
|
|
Posted: Mon Sep 22, 2014 7:18 am |
|
|
Ok. So I have a new problem. How can I calculate the degrees with data I have??? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9222 Location: Greensville,Ontario
|
|
Posted: Mon Sep 22, 2014 9:38 am |
|
|
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
|
|
Posted: Mon Sep 22, 2014 12:09 pm |
|
|
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
|
|
|
Ruby
Joined: 04 Jul 2014 Posts: 44
|
|
Posted: Mon Sep 22, 2014 12:38 pm |
|
|
Thanks PCM. I will check them now. I hope you get your gyro. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 22, 2014 12:45 pm |
|
|
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
|
|
Posted: Mon Sep 22, 2014 2:21 pm |
|
|
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
|
|
Posted: Tue Sep 23, 2014 12:40 pm |
|
|
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
|
|
Posted: Tue Sep 23, 2014 11:49 pm |
|
|
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
|
|
Posted: Thu Sep 25, 2014 11:50 am |
|
|
Anyone? ?? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19503
|
|
Posted: Thu Sep 25, 2014 11:55 am |
|
|
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
|
|
Posted: Thu Sep 25, 2014 12:05 pm |
|
|
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
|
|
Posted: Thu Sep 25, 2014 12:20 pm |
|
|
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. |
|
|
|
|
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
|