An IMU (Inertial Measurement Unit) is a component able to measure accelerations and angular speed it's subjected to, on defined axis (ofter 3 - Ox, Oy and Oz). Indeed, IMUs often have an accelerometer and a gyroscop, two different units we'll get angles from by doing some calculations.
There are several ways to obtain the angle between the IMU and horizontal axis.
We'll first see ways to obtain angles from raw data, and then we'll talk about filters (complementary filter).
The IMU we'll use in this project is named MPU6050, its a widely used IMU among Arduino hobbyists as it's pretty cheap and does a great job.
It has both an accelerometer and a gyroscope but also a magnetometer. We'll not treat that part of the IMU in this project.
It has 8 pins but we'll only use 4 of them : VCC (5 volts), GND, SCL and SLA (i2c communication pin).
Calculations and angle determinationI'll show you different ways to print and use data coming from the MPU6050.
Raw values
You can of course get raw values, directly sent by the IMU to Arduino. This will give you pretty unusable values as the accelerometer isn't converting raw data into something usable. Basically the accelerometer measures sensitivity - how forces are moving an element inside of the sensor through side membrane - and transfer what he captures without doing any transformation. Consequently we can't really use this data to determine an angle without processing it.
Angles from accelerations
By simply using tangent, we can determine angle between the accelerometer x axis and horizontal axis.
That's basically why we're using atan2 in the Arduino code to extract angles from opposite and adjacent side (ax and ay). Note : we need the angle between g and az, that's why in this case, atan = ax/ay. Here is the function set up to print angles calculated from accelerations :
void angleMeasurementAcceleration(){
angleA1= atan2((double)ax,(double)az )*180/PI;
angleA2= atan2((double)ay,(double)az )*180/PI;
Serial.print("Anglex :");
Serial.println(angleA2);
Serial.print("\t");
Serial.print("Angley :");
Serial.println(angleA1);
Serial.print("\t");
}
Angles from gyroscop
We can also extract code using gyroscop. The gyroscop gives us angular speed. By adding angular speed to the previously (gyroscop) calculated angle, we can obtain the angle updated every time we loop the code. Product by 0, 01 is due to tempo (10ms of delay between each loop, each measurement) and division by 131 is given on library MPU6050.
void angleMeasurementGyroscope(){
angleG1 = angleG1+float(gy)*0.01/131;
angleG2 = angleG2+float(gx)*0.01/131;
Serial.print("Anglex :");
Serial.println(angleG2);
Serial.print("\t");
Serial.print("Angley :");
Serial.println(angleG1);
Serial.print("\t");
}
Troubles incoming
If you try both methods, you'll notice something :
- Accelerations method is really sensitive and cannot be used for an accurate angle calculation
- Gyroscop method is pretty slow. More than that, angle value is increasing with time, even without turning the MPU6050
We need another way to get angles : a complementary filter.
FiltersA complementary filter will clean the value by mixing both gyroscop and acceleration values. Indeed we do have some clean stabilized values coming from the gyroscop but also sensitive values by accelerometer.
k1 and k2 have to be equal to 1, or our value will decrease slowly. Because the gyroscop gives us really stable but derivating values, its constant k1 will be high (around 0, 9) while the accelerometer one will be around 0, 1. Applied to code :
void complementaryFilter(){
angleC1 = 0.9*(angleC1+float(gy)*0.01/131) + 0.1*atan2((double)ax,(double)az)*180/PI;
angleC2 = 0.9*(angleC2+float(gx)*0.01/131) + 0.1*atan2((double)ay,(double)az)*180/PI;
Serial.print("Filtered anglex :");
Serial.println(angleC2);
Serial.print("\t");
Serial.print("Filtered angley :");
Serial.println(angleC1);
Serial.print("\t");
}
ConnectionsI opened a Tipeee to gather some funds for projects, I'll post informations and news about incoming devices.
A big thank to people who'll support me on Tipeee ;D
- My main source for this project, a tutorial I've followed a few years ago to create my drone/plane (Gilles Thebault) : accéléromètre et gyroscope MPU6050 - /dev/tbo (free.fr)
- Fusion de capteurs pour accéléromètres et gyroscopes | DigiKey
Comments
Please log in or sign up to comment.