If you want to use a Raspberry PI instead of an ATMega, see this post.
At first, I wrote two functions which can read from a register respectively write to a register:
void TWIM_WriteRegister(char reg, char value)
{
TWIM_Start(addr, TWIM_WRITE); // set device address and write mode
TWIM_Write(reg);
TWIM_Write(value);
TWIM_Stop();
}
char TWIM_ReadRegister(char reg)
{
TWIM_Start(addr, TWIM_WRITE);
TWIM_Write(reg);
TWIM_Stop();
TWIM_Start(addr, TWIM_READ); // set device address and read mode
char ret = TWIM_ReadNack();
TWIM_Stop();
return ret;
}
As a second step, I wrote two functions which read the acceleration and gyro data from the Sensor. Please note that you have to disable the sleep mode, this can be done by using
TWIM_WriteRegister(107, 0)
. double MPU6050_ReadAccel(int axis)//x = 0; y = 1; z = 2
{
char reg = axis * 2 + 59;
char AFS_SEL = TWIM_ReadRegister(28);
double factor = 1<<AFS_SEL;
factor = 16384/factor;
int val = 0;
double double_val = 0;
char ret = 0;
ret = TWIM_ReadRegister(reg);
val = ret << 8;
ret = TWIM_ReadRegister(reg+1);
val += ret;
if (val & 1<<15)
val -= 1<<16;
double_val = val;
double_val = double_val / factor;
return double_val;
}
double MPU6050_ReadGyro(int axis)//x = 0; y = 1; z = 2
{
char reg = axis * 2 + 67;
char FS_SEL = TWIM_ReadRegister(27);
double factor = 1<<FS_SEL;
factor = 131/factor;
int val = 0;
double double_val = 0;
char ret = 0;
ret = TWIM_ReadRegister(reg);
val = ret << 8;
ret = TWIM_ReadRegister(reg+1);
val += ret;
if (val & 1<<15)
val -= 1<<16;
double_val = val;
double_val = double_val / factor;
return double_val;
}
The values for the gyrometer are in degrees per second and in units of g for the accelerometer, further information is provided in the Register Map, especially at the explaination of FS_SEL and AFS_SEL: http://www.invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf
Thanks for this tutorial... but I have one problem :((
ReplyDeleteI done everything in Atmel Studio 6.1 but when I press Build Solution (F7) I get this errors:
Error 1 'addr' was not declared in this scope (Line 28)
Error 1 'addr' was not declared in this scope (Line 36)
Warning 3 left shift count >= width of type [enabled by default] (Line 63)
Warning 3 left shift count >= width of type [enabled by default] (Line 89)
Can you help me?? PLEASE
Hi David
Deletethe addr is the I2C address of the GPU-6050. In my case, the address is 0x68, so I have
#define addr 0x68
on the first line in my program.
If this address does not work, you could use an I2C Scanner which scans every I2C address and then prints out where there are devices.
Udo
:D :D..... THANKS FOR YOUR REPLAY!!!
DeleteAnd also I have one question, I make QuadCopter that uses MPU6050 for stabilization.... but I don't know how to get sensor date in characters... can you help me?? (send me example of something like that).....
I have everything but this chip is problem for me........ Only you can help me..
Thanks again bro :D
If you look into the ReadAccel and ReadGyro functions, you will see that I read out the values into "ret" which is a character variable, you can use this. I use int at first because both registers (8 bit each) together form the value - and thats 16 bit, more than a character variable. In the end, I convert it into a physical value (in m/s^2) in a double.
DeleteOK thank you for your help :DD I will try it..
DeleteAlso.... I have written small code for test:
Delete//----------
int main(void)
{
USARTInit(25);
TWIM_Init(25);
TWIM_WriteRegister(107,0);
while(1)
{
MPU6050_ReadGyro(0);
USARTWriteChar(ret);
_delay_ms(100);
}
}
//----------
but i get this error:
Error 3 'ret' was not declared in this scope
P.S. Im beginner and i don't know everything in programming... im learning.. and you help will be great :DD
Thanks!
Yeah, so you want to write "ret" to USART, but ret is nowhere defined. You could try something like
Deletechar ret = (char)MPU6050_ReadGyro(0);
if you want to write the Gyro out to the USART.
THANK YOU SO MUCH :D :D
DeleteThis comment has been removed by the author.
DeleteHi again.. ;))
ReplyDeleteIs here any functions to calibrate accel and gyro????
and can i interface compass magnetometer http://www.ebay.com/itm/400362466832 >>>> and GPS http://www.ebay.com/itm/Ublox-NEO-6M-GPS-Module-Aircraft-Flight-Controller-For-Arduino-MWC-IMU-APM2-BR-/151140071016?pt=LH_DefaultDomain_0&hash=item2330a67668 >>>> with same I2C?? (and which code i need to use(PLEASE HELP :)))))
DeleteThx for all!
TWIM_WriteRegister(107, 0)
ReplyDeleteError: expected declaration specifiers or '...' before numeric constant
Compiler: Atmel Studio 6.1
since the function has been defined as TWIM_WriteRegister(char reg, char value), can it accept 107, 0 as parameters? Should I change char to int? Please help!!
This comment has been removed by the author.
Deletewhat for you need to define it?
Deleteyou don't need to define it...... use this example code below...
int main(void)
{
TWIM_WriteRegister(107, 0);
while (1)
{
//Your code here!!
}
}
Its working...thanks a lot buddy :)...but I still can't understand how "TWIM_WriteRegister(107, 0);" is causing the above mentioned error outside the main function and working fine inside it...could you please explain?
ReplyDeleteI am not sure, i don't know programming well but i think that with that code > TWIM_WriteRegister(107, 0); < you write short function instead of that long code >>
DeleteTWIM_Start(addr, TWIM_WRITE);
TWIM_Write(reg);
TWIM_Write(value);
TWIM_Stop();
:)))
I'm not using any dev-boards...I'm making a simple circuit that interfaces ATmega16 and MPU6050...can I connect SCL and SDA pins of ATmega16 to SCL and SDA of MPU6050 directly? Or do I need level shifters?
ReplyDeleteSo... If you using 3.3V power supply for atmega than you don't need anything and you can directly connect SCL>SCL SDA>SDA... but if you have 5V power supply this product is for you >> http://www.ebay.com/itm/161108492494 << this board has it's 5V>3V3 converter... you can directly connect SCL>SCL SDA>SDA anyway... :))))))
DeleteYes...this is the product that I have...GY-521...so I will connect SDA and SCL directly. Thanks a lot for helping me out buddy...:) :)
Deletenp ;))
DeleteHey can you send me your code...?? I am interested with that..... :))))
Deletemy email is >> daduka_k@yahoo.com
DeleteThanks!! :D
I will...once i finish it...:)
Deleteok ty ;))
Deletethanks ur code is easy to understand...
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteAre there any other initialization parameters for the mpu6050 or just by calling the (107, 0) command I should be able to read from them?
ReplyDeleteI am trying to translate from this to ATxMEGA and I am currently struggling with the code
So basically you only have to disable the sleep mode (107,0) and then you shoud be able to read out the sensor values as described above. Keep in mind that the sensor is for 3.3V and 5V might work but might also destroy the sensor.
Deletehello david i want to interface mpu6050 with atmega 8..can you tell me what changes i have to do with this code...and which libraries i have to include before copying this code
ReplyDeleteHii i am also working with mpu6050 with atmega 16
ReplyDeleteso i just have to write this code in main to read the x axis of aclro. if i am using lcd as output
int main(void)
{
TWIM_WriteRegister(107,0);
while(1)
{
MPU6050_ReadAccel(0);
lcd=ret;
_delay_ms(100);
}
}
good its working thank.
ReplyDeletebut i cant fetch acelormetor reading
ReplyDeletemy code is.
TWIM_WriteRegister(107,0);
TWIM_Init(25);
while(1)
{
char ret = (char)MPU6050_ReadAccel(1);
printf(" %d\n",ret);
_delay_ms(100);
}
whats the problem ,gyro is comming.
by writing this TWIM_WriteRegister(107,0); my usart stop working.
ReplyDeleteinnahie_go_Little Rock Shawn Showcase https://www.prisonwrites.org/profile/anastasijdenbie/profile
ReplyDeletewietitbehnlas