Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
8 views5 pages

Transmitter Code

This document provides a tutorial on interfacing an Arduino with the MPU6050 accelerometer and gyroscope sensor. It includes code for reading accelerometer and gyroscope data, calculating angles using a complementary filter, and sending commands based on the sensor readings via Bluetooth. The tutorial also explains how to calculate and correct for sensor errors to improve accuracy.

Uploaded by

sriramaanusha3
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views5 pages

Transmitter Code

This document provides a tutorial on interfacing an Arduino with the MPU6050 accelerometer and gyroscope sensor. It includes code for reading accelerometer and gyroscope data, calculating angles using a complementary filter, and sending commands based on the sensor readings via Bluetooth. The tutorial also explains how to calculate and correct for sensor errors to improve accuracy.

Uploaded by

sriramaanusha3
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

/*

Arduino and MPU6050 Accelerometer and Gyroscope Sensor Tutorial


by Dejan, https://howtomechatronics.com/tutorials/arduino/arduino-and-mpu6050-
accelerometer-and-gyroscope-tutorial/
*/

#include <Wire.h>
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // CONNECT BT RX PIN TO ARDUINO 11 PIN | CONNECT
BT TX PIN TO ARDUINO 10 PIN

const int MPU_ADDRESS = 0x68; // MPU6050 I2C address

float AccX, AccY, AccZ;


float GyroX, GyroY, GyroZ;

float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;


float roll, pitch, yaw;

float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;

float elapsedTime, currentTime, previousTime;

int c = 0;

void setup()
{

Serial.begin(9600);
BTSerial.begin(9600); // HC-05 default speed in AT command more

Wire.begin(); // Initialize comunication


Wire.beginTransmission(MPU_ADDRESS); // Start communication with
MPU6050 // MPU=0x68
Wire.write(0x6B); // Talk to the register 6B
Wire.write(0x00); // Make reset - place a 0 into the 6B
register
Wire.endTransmission(true); //end the transmission

// Configure Accelerometer Sensitivity - Full Scale Range (default +/- 2g)


/* Wire.beginTransmission(MPU);
Wire.write(0x1C); //Talk to the ACCEL_CONFIG register (1C hex)
Wire.write(0x10); //Set the register bits as 00010000 (+/- 8g
full scale range)
Wire.endTransmission(true);

// Configure Gyro Sensitivity - Full Scale Range (default +/- 250deg/s)


Wire.beginTransmission(MPU);
Wire.write(0x1B); // Talk to the GYRO_CONFIG register (1B hex)
Wire.write(0x10); // Set the register bits as 00010000
(1000deg/s full scale)
Wire.endTransmission(true);
delay(20);

//Call this function if you need to get the IMU error values for your module*/
//while(true) calculate_IMU_error();

// delay(20);

void loop()
{

MPU_read_accel_data();
MPU_read_gyro_data();

// calculate time elapsed since last time we were here


previousTime = currentTime; // Previous time is stored before the actual
time read
currentTime = millis(); // Current time actual time read
elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get
seconds

// Complementary filter - combine acceleromter and gyro angle values


roll = 0.92 * (roll + (GyroX * elapsedTime)) + 0.08 * accAngleX;
pitch = 0.92 * (pitch + (GyroY * elapsedTime)) + 0.08 * accAngleY;
//yaw = gyroAngleZ;

// Currently the raw values are in degrees per seconds, deg/s, so we need to
multiply by sendonds (s) to get the angle in degrees
gyroAngleX += GyroX * elapsedTime; // deg/s * s = deg
gyroAngleY += GyroY * elapsedTime;
gyroAngleZ += GyroZ * elapsedTime;

/*by me */
// Print the values on the serial monitor
Serial.print("roll:");
Serial.print(roll);
Serial.print(" ");

Serial.print("pitch:");
Serial.println(pitch);

/* Serial.print(" ");
Serial.print("yaw:");
Serial.println(yaw);*/

/*Serial.print(" ");
/* made by me
// Print the values on the serial monitor
Serial.print(pitch);
Serial.print(" ");
Serial.print(accAngleY);
Serial.print(" ");
Serial.println(gyroAngleY);
*/
if(pitch<-17){
BTSerial.write('F');
}else if(pitch>20){
BTSerial.write('B');
}else if(roll>30){
BTSerial.write('R');
}else if(roll<-30){
BTSerial.write('L');
}else if(yaw>30){
BTSerial.write('r');
}else if(yaw<-30){
BTSerial.write('l');
}else
BTSerial.write('S');
}

void MPU_read_accel_data()
{
// === Read acceleromter data === //
Wire.beginTransmission(MPU_ADDRESS);
Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDRESS, 6, true); // Read 6 registers total, each axis
value is stored in 2 registers

//For a range of +-2g, we need to divide the raw values by 16384, according to
the datasheet
AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value

// Calculating Roll and Pitch from the accelerometer data


accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - (-
0.40); // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more
details
accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) -
(-3.75); // AccErrorY ~(-1.58)

void MPU_read_gyro_data()
{
// === Read gyroscope data === //
Wire.beginTransmission(MPU_ADDRESS);
Wire.write(0x43); // Gyro data first register address 0x43
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDRESS, 6, true); // Read 4 registers total, each axis
value is stored in 2 registers

// For a 250deg/s range we have to divide first the raw value by 131.0,
according to the datasheet
GyroX = (Wire.read() << 8 | Wire.read()) / 131.0;
GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;

// Correct the outputs with the calculated error values


GyroX = GyroX - (-0.68); // GyroErrorX = ~ (-2.12)
GyroY = GyroY - (-2.48); // GyroErrorY = ~ (4.12)
GyroZ = GyroZ - (-0.12); // GyroErrorZ = ~ (1.20)
}

void calculate_IMU_error()
{

// We can call this funtion in the setup section to calculate the accelerometer
and gyro data error. From here we will get the error values used in the above
equations printed on the Serial Monitor.
// Note that we should place the IMU flat in order to get the proper values, so
that we then can the correct values
// Read accelerometer values 200 times
while (c < 200)
{
Wire.beginTransmission(MPU_ADDRESS);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDRESS, 6, true);
AccX = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
AccY = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
// Sum all readings
AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2)))
* 180 / PI));
AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ),
2))) * 180 / PI));
c++;
}

//Divide the sum by 200 to get the error value


AccErrorX = AccErrorX / 200;
AccErrorY = AccErrorY / 200;

c = 0;

// Read gyro values 200 times


while (c < 200)
{
Wire.beginTransmission(MPU_ADDRESS);
Wire.write(0x43);
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDRESS, 6, true);

GyroX = Wire.read() << 8 | Wire.read();


GyroY = Wire.read() << 8 | Wire.read();
GyroZ = Wire.read() << 8 | Wire.read();

// Sum all readings


GyroErrorX = GyroErrorX + (GyroX / 131.0);
GyroErrorY = GyroErrorY + (GyroY / 131.0);
GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);

c++;

//Divide the sum by 200 to get the error value


GyroErrorX = GyroErrorX / 200;
GyroErrorY = GyroErrorY / 200;
GyroErrorZ = GyroErrorZ / 200;

// Print the error values on the Serial Monitor

Serial.print("AccErrorX: ");
Serial.print(AccErrorX);
Serial.print(" | AccErrorY: ");
Serial.print(AccErrorY);
Serial.print(" | GyroErrorX: ");
Serial.print(GyroErrorX);
Serial.print(" | GyroErrorY: ");
Serial.print(GyroErrorY);
Serial.print(" | GyroErrorZ: ");
Serial.println(GyroErrorZ);

delay(1000);
}

You might also like