MPU6050 (Gyroscope + Accelerometer + Temperature) interface with AVR ATmega16.
Introduction
MPU6050 Module
MPU6050 sensor module is an integrated 6-axis Motion tracking device.
- It has a 3-axis Gyroscope, 3-axis Accelerometer, Digital Motion Processor and a Temperature sensor, all in a single IC.
- It can accept inputs from other sensors like 3-axis magnetometer, pressure sensor using its Auxiliary I2C bus.
- If external 3-axis magnetometer is connected, it can provide complete 9-axis Motion Fusion output.
- A microcontroller can communicate with this module using I2C communication protocol.
- Gyroscope and accelerometer reading along X, Y and Z axes are available in 2’s complement form. Temperature reading is available in signed integer form.
- Gyroscope readings are in degrees per second (dps) unit; Accelerometer readings are in g unit; and Temperature reading is in degrees Celsius.
For more information about MPU6050 Sensor Module and how to use it, refer the topic MPU6050 Sensor Module in the sensors and modules section.
Interfacing MPU6050 with AVR ATmega16
Interfacing of MPU-6050 module with ATmega16 is shown in below figure.
Interfacing MPU6050 With ATmega 16
Example
Let's program MPU6050 (Gyro meter + Accelerometer + Temperature) sensor module with AVR based ATmega16 to read all sensor values and send all values on computer terminals over USART.
- As MPU-6050 has I2C communication interface to connect it with I2C of ATmega16.
- Module requires +5V DC power supply, so connect it to VCC pin of module.
- Connect ground to GND pin of module.
- Here we have used FTDI serial to USB converter to send values serially to computer terminal.
Program
/*
* ATmega16 Interface with MPU6050
* http://www.electronicwings.com
*
*/
#define F_CPU 8000000UL /* Define CPU clock Frequency 8MHz */
#include <avr/io.h> /* Include AVR std. library file */
#include <util/delay.h> /* Include delay header file */
#include <inttypes.h> /* Include integer type header file */
#include <stdlib.h> /* Include standard library file */
#include <stdio.h> /* Include standard I/O library file */
#include "MPU6050_res_define.h" /* Include MPU6050 register define file */
#include "I2C_Master_H_file.h" /* Include I2C Master header file */
#include "USART_RS232_H_file.h" /* Include USART header file */
float Acc_x,Acc_y,Acc_z,Temperature,Gyro_x,Gyro_y,Gyro_z;
void Gyro_Init() /* Gyro initialization function */
{
_delay_ms(150); /* Power up time >100ms */
I2C_Start_Wait(0xD0); /* Start with device write address */
I2C_Write(SMPLRT_DIV); /* Write to sample rate register */
I2C_Write(0x07); /* 1KHz sample rate */
I2C_Stop();
I2C_Start_Wait(0xD0);
I2C_Write(PWR_MGMT_1); /* Write to power management register */
I2C_Write(0x01); /* X axis gyroscope reference frequency */
I2C_Stop();
I2C_Start_Wait(0xD0);
I2C_Write(CONFIG); /* Write to Configuration register */
I2C_Write(0x00); /* Fs = 8KHz */
I2C_Stop();
I2C_Start_Wait(0xD0);
I2C_Write(GYRO_CONFIG); /* Write to Gyro configuration register */
I2C_Write(0x18); /* Full scale range +/- 2000 degree/C */
I2C_Stop();
I2C_Start_Wait(0xD0);
I2C_Write(INT_ENABLE); /* Write to interrupt enable register */
I2C_Write(0x01);
I2C_Stop();
}
void MPU_Start_Loc()
{
I2C_Start_Wait(0xD0); /* I2C start with device write address */
I2C_Write(ACCEL_XOUT_H);/* Write start location address from where to read */
I2C_Repeated_Start(0xD1);/* I2C start with device read address */
}
void Read_RawValue()
{
MPU_Start_Loc(); /* Read Gyro values */
Acc_x = (((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack());
Acc_y = (((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack());
Acc_z = (((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack());
Temperature = (((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack());
Gyro_x = (((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack());
Gyro_y = (((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Ack());
Gyro_z = (((int)I2C_Read_Ack()<<8) | (int)I2C_Read_Nack());
I2C_Stop();
}
int main()
{
char buffer[20], float_[10];
float Xa,Ya,Za,t;
float Xg=0,Yg=0,Zg=0;
I2C_Init(); /* Initialize I2C */
Gyro_Init(); /* Initialize Gyro */
USART_Init(9600); /* Initialize USART with 9600 baud rate */
while(1)
{
Read_RawValue();
/* Divide raw value by sensitivity scale factor */
Xa = Acc_x/16384.0;
Ya = Acc_y/16384.0;
Za = Acc_z/16384.0;
Xg = Gyro_x/16.4;
Yg = Gyro_y/16.4;
Zg = Gyro_z/16.4;
/* Convert temperature in /c using formula */
t = (Temperature/340.00)+36.53;
/* Take values in buffer to send all parameters over USART */
dtostrf( Xa, 3, 2, float_ );
sprintf(buffer," Ax = %s g\t",float_);
USART_SendString(buffer);
dtostrf( Ya, 3, 2, float_ );
sprintf(buffer," Ay = %s g\t",float_);
USART_SendString(buffer);
dtostrf( Za, 3, 2, float_ );
sprintf(buffer," Az = %s g\t",float_);
USART_SendString(buffer);
dtostrf( t, 3, 2, float_ );
/* 0xF8 Ascii value of degree on serial */
sprintf(buffer," T = %s%cC\t",float_,0xF8);
USART_SendString(buffer);
dtostrf( Xg, 3, 2, float_ );
sprintf(buffer," Gx = %s%c/s\t",float_,0xF8);
USART_SendString(buffer);
dtostrf( Yg, 3, 2, float_ );
sprintf(buffer," Gy = %s%c/s\t",float_,0xF8);
USART_SendString(buffer);
dtostrf( Zg, 3, 2, float_ );
sprintf(buffer," Gz = %s%c/s\r\n",float_,0xF8);
USART_SendString(buffer);
}
}
Output Window of Terminal
Output window will show all values mentioned below
Ax = Accelerometer x axis data in g unit
Ay = Accelerometer y axis data in g unit
Az = Accelerometer z axis data in g unit
T = temperature in degree/celcius
Gx = Gyro x axis data in degree/seconds unit
Gy = Gyro y axis data in degree/seconds unit
Gz = Gyro z axis data in degree/seconds unit
No comments:
Post a Comment