MPU-6050, почему данные по тангажу, рысканию и крену не согласуются (значение продолжает увеличиваться/уменьшаться, когда оно стабильно)?
Недавно я купил MPU 6050, который планирую использовать с дроном. Однако сейчас я сталкиваюсь с некоторыми трудностями, потому что MPU не дает мне стабильных результатов.
Результаты (тангаж, крен, рыскание), которые я получаю, не соответствуют друг другу. Если я, например, держу фишку стабильно на столе, значение продолжает увеличиваться/уменьшаться, даже если к ней не прикасаются/не перемещают.
Кажется, я также получаю разные результаты, если перезапускаю его, даже если использую его под теми же углами.
Что-то не так с моим кодом или мне нужно сделать что-то еще, чтобы решить эту проблему?
Ценю любую помощь, которую я могу получить! :)
Вот мой текущий код:
#include <Servo.h>
#include <Wire.h>
int gyro_x, gyro_y, gyro_z;
long acc_x, acc_y, acc_z, acc_total_vector;
int temperature;
long gyro_x_cal, gyro_y_cal, gyro_z_cal;
long loop_timer;
int lcd_loop_counter;
float angle_pitch, angle_roll;
int angle_pitch_buffer, angle_roll_buffer;
boolean set_gyro_angles;
float angle_roll_acc, angle_pitch_acc;
float angle_pitch_output, angle_roll_output;
void setup() {
Wire.begin();
Serial.begin(9600);
setup_mpu_6050_registers();
for (int cal_int = 0; cal_int < 2000 ; cal_int ++){
read_mpu_6050_data();
gyro_x_cal += gyro_x;
gyro_y_cal += gyro_y;
gyro_z_cal += gyro_z;
delay(3);
}
gyro_x_cal /= 2000;
gyro_y_cal /= 2000;
gyro_z_cal /= 2000;
loop_timer = micros();
}
void loop(){
read_mpu_6050_data();
gyro_x -= gyro_x_cal;
gyro_y -= gyro_y_cal;
gyro_z -= gyro_z_cal;
angle_pitch += gyro_x * 0.0000611;
angle_roll += gyro_y * 0.0000611;
angle_pitch += angle_roll * sin(gyro_z * 0.000001066);
angle_roll -= angle_pitch * sin(gyro_z * 0.000001066);
acc_total_vector = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z));
angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296;
angle_roll_acc = asin((float)acc_x/acc_total_vector)* -57.296;
angle_pitch_acc -= 0.0;
angle_roll_acc -= 0.0;
if(set_gyro_angles){
angle_pitch = angle_pitch * 0.9996 + angle_pitch_acc * 0.0004;
angle_roll = angle_roll * 0.9996 + angle_roll_acc * 0.0004;
}
else{
angle_pitch = angle_pitch_acc;
angle_roll = angle_roll_acc;
set_gyro_angles = true;
}
Serial.println(angle_pitch_output);
Serial.println(angle_roll_output);
while(micros() - loop_timer < 4000);
loop_timer = micros();
}
void read_mpu_6050_data(){
Wire.beginTransmission(0x68);
Wire.write(0x3B);
Wire.endTransmission();
Wire.requestFrom(0x68,14);
while(Wire.available() < 14);
acc_x = Wire.read()<<8|Wire.read();
acc_y = Wire.read()<<8|Wire.read();
acc_z = Wire.read()<<8|Wire.read();
temperature = Wire.read()<<8|Wire.read();
gyro_x = Wire.read()<<8|Wire.read();
gyro_y = Wire.read()<<8|Wire.read();
gyro_z = Wire.read()<<8|Wire.read();
}
void setup_mpu_6050_registers(){
Wire.beginTransmission(0x68);
Wire.write(0x6B);
Wire.write(0x00);
Wire.endTransmission();
Wire.beginTransmission(0x68);
Wire.write(0x1C);
Wire.write(0x10);
Wire.endTransmission();
Wire.beginTransmission(0x68);
Wire.write(0x1B);
Wire.write(0x08);
Wire.endTransmission();
}
@Martman, 👍1
Обсуждение0
Смотрите также:
- Как использовать SPI на Arduino?
- Библиотека DHT.h не импортируется
- Светодиоды: разница между общим анодом и общим катодом
- Как повторить кусок кода
- Почему эта программа на C++ не может прочитать Serial.write() моего arduino?
- Как изменить переменную при нажатии кнопки, подключенной к контакту 2
- Отображение двоичных данных на светодиодах
- Корпус кнопки и переключателя
Вы собрали фрагменты кода, найденные в Интернете? Можете ли вы сказать, где вы их нашли? Это запутанная смесь разных стилей программирования и формул, использование библиотеки Wire, смешение int, long и float также сбивает с толку. MPU-9250 имеет магнитометр для рыскания. Существует ряд хороших библиотек для объединения датчиков с фильтрами для датчиков 6DOF или 9DOF. MPU-6050 и MPU-9250 также могут использовать внутреннюю прошивку dmp. Вы можете начать с веб-сайта Sparkfun.com и поискать MPU-9250., @Jot
Я не использую mpu-9250, я использую mpu-6050. И да, когда дело доходит до кода, я находил его повсюду и тоже собирал что-то свое, что делает его немного хаотичным!, @Martman
MPU-6050 устарел, и модули на Ebay могут иметь неправильный конденсатор, что делает его еще более шумным. Можете дать ссылку на эти формулы? Без ссылки у меня много сомнений. Глядя на код, я даже сомневаюсь в задержке в 4 мс. Ваш цикл, вероятно, больше замедляется из-за полного выходного буфера Serial, чем из-за micros(). Я настоятельно рекомендую использовать библиотеку, и вы можете подумать о покупке MPU-9250. Возможно, вы используете 5V Arduino без переключателя уровня I2C?, @Jot
Я купил его на ebay, так что, возможно, качество не очень :( Думаю, у моего arduino есть I2C. Как вы думаете, может ли этот пример работать хорошо? https://github.com/jarzebski/Arduino-MPU6050/blob/master/MPU6050_gyro_pitch_roll_yaw/MPU6050_gyro_pitch_roll_yaw.ino, @Martman
Я вижу некоторые проблемы: неправильное использование библиотеки Wire (endTransmission после requestFrom, цикл while после requestFrom); отсутствие слияния датчиков; сдвиг 8-битной переменной 8 раз влево. Этот тестирует новые формулы. Я думаю, что результаты немного шумные. Удалите вызовы дисплея: https://github.com/kriswiner/MPU-6050/blob/master/MPU6050IMU.ino. Это работает: http://forum.arduino.cc/index.php?topic=58048.0. чаще всего используется: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050, но были некоторые жалобы на то, что он не использует настоящий фильтр Калмана., @Jot