/* Get tilt angles on X and Y, and rotation angle on Z
* Angles are given in degrees, displays on SSD1306 OLED
*
* License: MIT
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050_light.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
MPU6050 mpu(Wire);
unsigned long timer = 0;
void setup() {
Serial.begin(115200); // Ensure serial monitor set to this value also
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) // Address 0x3C for most of these displays, if doesn't work try 0x3D
{
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.clearDisplay();
Wire.begin();
mpu.begin();
display.println(F("Calculating gyro offset, do not move MPU6050"));
display.display();
mpu.calcGyroOffsets(); // This does the calibration
display.setTextSize(2);
}
void loop() {
mpu.update();
if((millis()-timer)>10) // print data every 10ms
{
display.clearDisplay(); // clear screen
display.setCursor(0,0);
display.print("P : ");
display.println((int)mpu.getAngleX());
display.print("R : ");
display.println((int)mpu.getAngleY());
display.print("Y : ");
display.print((int)mpu.getAngleZ());
display.display(); // display data
timer = millis();
}
}
The mpu6050 working great and i can measure pitch , roll and yaw value with no problem
But it shows the angles according to the gavity
I want it shows the zero angles at startup. So, regardless of the initial orientation of the MPU6050, the angles are zero. Moving it updates the angles relative to the initial orientation not gravity orientation
How to show the initial angles at startup zero then update the angles relative to the initial angles regardless the gravity orientation?
Means if i started it while i am holding it with 90° on the floor, the initial degree show is zero not 90°
Record the (x, y, z) components of the gravity vector on startup (R0) and calculate the tilt angle from vertical using the vector dot product of that with subsequent measurements (R).
If you normalize both vectors so |R| = |R0| = 1, then
cos(tilt_angle) = R dot R0
Calculating Euler angles with respect to X and Y is more complicated.
i tried this on the x angle, it compiled and uploaded successfully but not working gives 0 only
/* Get tilt angles on X and Y, and rotation angle on Z
* Angles are given in degrees, displays on SSD1306 OLED
*
* License: MIT
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050_light.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
MPU6050 mpu(Wire);
unsigned long timer = 0;
int initialReading;
int getAngleX;
void setup() {
Serial.begin(115200); // Ensure serial monitor set to this value also
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) // Address 0x3C for most of these displays, if doesn't work try 0x3D
{
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
initialReading = getAngleX;
}
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.clearDisplay();
Wire.begin();
mpu.begin();
display.println(F("Calculating gyro offset, do not move MPU6050"));
display.display();
mpu.calcGyroOffsets(); // This does the calibration
display.setTextSize(2);
}
void loop() {
int reading = getAngleX;
int relative = reading - initialReading;
mpu.update();
if((millis()-timer)>10) // print data every 10ms
{
display.clearDisplay(); // clear screen
display.setCursor(0,0);
display.print("P : ");
display.println(relative);
display.print("R : ");
display.println((int)mpu.getAngleY());
display.print("Y : ");
display.print((int)mpu.getAngleZ());
display.display(); // display data
timer = millis();
}
}
This is the simplest approach to measure pitch and roll values using the MPU-6050 (or other accelerometer):
// minimal MPU-6050 tilt and roll (sjr). Works with MPU-9250 too.
// works perfectly with GY-521, pitch and roll signs agree with arrows on sensor module 7/2019
//
// Tested with 3.3V eBay Pro Mini with no external pullups on I2C bus (worked with internal pullups)
// Add 4.7K pullup resistors to 3.3V if required. A4 = SDA, A5 = SCL
#include<Wire.h>
const int MPU_addr1 = 0x68;
float xa, ya, za, roll, pitch;
void setup() {
Wire.begin(); //begin the wire communication
Wire.beginTransmission(MPU_addr1); //begin, send the slave adress (in this case 68)
Wire.write(0x6B); //make the reset (place a 0 into the 6B register)
Wire.write(0);
Wire.endTransmission(true); //end the transmission
Serial.begin(9600);
}
void loop() {
Wire.beginTransmission(MPU_addr1);
Wire.write(0x3B); //send starting register address, accelerometer high byte
Wire.endTransmission(false); //restart for read
Wire.requestFrom(MPU_addr1, 6); //get six bytes accelerometer data
int t = Wire.read();
xa = (t << 8) | Wire.read();
t = Wire.read();
ya = (t << 8) | Wire.read();
t = Wire.read();
za = (t << 8) | Wire.read();
// formula from https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing
roll = atan2(ya , za) * 180.0 / PI;
pitch = atan2(-xa , sqrt(ya * ya + za * za)) * 180.0 / PI; //account for roll already applied
Serial.print("roll = ");
Serial.print(roll,1);
Serial.print(", pitch = ");
Serial.println(pitch,1);
delay(400);
}
i am a beginner in c++, all my previous working with python so there are some confusion for me
/* Get tilt angles on X and Y, and rotation angle on Z
* Angles are given in degrees, displays on SSD1306 OLED
*
* License: MIT
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050_light.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
MPU6050 mpu(Wire);
unsigned long timer = 0;
int initialReading;
void setup() {
Serial.begin(115200); // Ensure serial monitor set to this value also
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) // Address 0x3C for most of these displays, if doesn't work try 0x3D
{
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
initialReading = mpu.getAngleX();
}
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.clearDisplay();
Wire.begin();
mpu.begin();
display.println(F("Calculating gyro offset, do not move MPU6050"));
display.display();
mpu.calcGyroOffsets(); // This does the calibration
display.setTextSize(2);
}
void loop() {
int reading = mpu.getAngleX();
int relative = reading - initialReading;
mpu.update();
if((millis()-timer)>10) // print data every 10ms
{
display.clearDisplay(); // clear screen
display.setCursor(0,0);
display.print("P : ");
display.println((int)relative);
display.print("R : ");
display.println((int)mpu.getAngleY());
display.print("Y : ");
display.print((int)mpu.getAngleZ());
display.display(); // display data
timer = millis();
}
}
i edit it but now giving the value according to the gravity again
/* Get tilt angles on X and Y, and rotation angle on Z
* Angles are given in degrees, displays on SSD1306 OLED
*
* License: MIT
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050_light.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
MPU6050 mpu(Wire);
unsigned long timer = 0;
int initialReading;
void setup() {
Serial.begin(115200); // Ensure serial monitor set to this value also
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) // Address 0x3C for most of these displays, if doesn't work try 0x3D
{
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
initialReading = mpu.getAngleX();
}
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.clearDisplay();
Wire.begin();
mpu.begin();
display.println(F("Calculating gyro offset, do not move MPU6050"));
display.display();
mpu.calcGyroOffsets(); // This does the calibration
display.setTextSize(2);
}
void loop() {
int reading = mpu.getAngleX();
int relative = reading - initialReading;
mpu.update();
if((millis()-timer)>10) // print data every 10ms
{
display.clearDisplay(); // clear screen
display.setCursor(0,0);
display.print("P : ");
display.println(initialReading);
display.print("R : ");
display.println((int)mpu.getAngleY());
display.print("Y : ");
display.print((int)mpu.getAngleZ());
display.display(); // display data
timer = millis();
}
}
i did not mean you write me a code for free really, i am just learning by examples that is how iam able to learn new coding.
i really appropriate you are helping me
This is a poor way to proceed, especially when you lack very basic math skills.
There are plenty of good programming tutorials on line, starting with the basics. Study one or more of those systematically. And you should be consulting the language references, both for Arduino and C/C++, whenever you see a line of code that you don't understand.