MPU6050/DMP Прерывистый плохой вывод данных?
У меня есть модуль DFRobots MPU6050, подключенный к SCL/SDA/Pin 2 на плате Mega 2560, используя библиотеки I2Cdev/MPU6050_6Axis_MotionApps Джеффа Роуберга. У меня есть 2,2 K съемников на модуле MPU6050, привязанный к +5V, как показано на следующем фото.
Я использовал модифицированную версию кода из примера Джеффа, чтобы получить значения заголовков из MPU6050, как показано ниже
bool GetIMUHeadingDeg() //08/28/18 chg to bool return
{
//Цель: Инкапсулировать все необходимое для получения значения рыскания
//Входы:
// global_yawval = переменная float, определенная в глобальной области
// fifocount = переменная uint8_t, определенная в глобальной области
// packetsize = переменная uint8_t, определенная в глобальной области
// mpuIntStatus = переменная uint8_t, определенная в глобальной области
// whilecount = длинная переменная, определенная в глобальной области
// resetcount = переменная int, определенная в глобальной области
//Выходы:
// global_yawval заполняется последним значением рыскания от датчика
// true = успех, false = неудача
//Примечания:
// 08/13/18 теперь возвращает global_yawval в вызывающую рутину
// 08/28/18 chg return to bool so can return success/failure
// если программирование не удалось, не пытайтесь ничего сделать
//if (!dmpReady) return;
//if (!dmpReady) false;
bool result = false; //added 01/16/19 to supress warnings
// ждите прерывания MPU или дополнительных пакетов, доступных
while (!mpuInterrupt && fifoCount < DMPpacketSize)
{
whilecount++;
delay(10);
delay(10);
if (mpuInterrupt)
{
fifoCount = mpu.getFIFOCount();
mySerial.printf("%ld\t%d\n", whilecount, fifoCount);
whilecount = 0;
break;
}
}
// сбросить флаг прерывания и получить байт INT_STATUS
mpuIntStatus = mpu.getIntStatus();
mpuInterrupt = false;
// get current FIFO count
fifoCount = mpu.getFIFOCount();
// проверьте наличие переполнения (этого никогда не должно произойти, если только наш код не слишком неэффективен)
if ((mpuIntStatus & 0x10) || fifoCount == 1024)//0x10 is mask for MPU6050_INTERRUPT_FIFO_OFLOW_BIT
{
// reset so we can continue cleanly
mpu.resetFIFO();
Serial.println(F("FIFO overflow!"));
result = false; //added 01/16/19 to supress warnings
// в противном случае проверьте наличие готового прерывания DMP data ready (это должно происходить часто)
}
else if (mpuIntStatus & 0x02)//0x02 is mask for MPU6050_INTERRUPT_DMP_INT_BIT
{
// wait for correct available data length, should be a VERY short wait
while (fifoCount < DMPpacketSize)
{
fifoCount = mpu.getFIFOCount();
//mySerial.printf("fifo count = %d\n", fifoCount);
}
//07/08/18 added to watch for non-modulo FIFO counts
if (fifoCount == 0 || fifoCount % DMPpacketSize != 0)
{
mpu.resetFIFO();
FIFO_resetcount++;
}
else
{
//07/07/18 modified to read all outstanding packets
// read a packet from FIFO
while (fifoCount >= DMPpacketSize)
{
//mySerial.printf("fifo count = %d\n", fifoCount);
mpu.getFIFOBytes(fifoBuffer, DMPpacketSize);
fifoCount -= DMPpacketSize;
}
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
global_yawval = ypr[0] * 180 / M_PI;
result = true; //added 01/16/19 to supress warnings
}
////DEBUG!!
// mySerial.printf("yawdeg = %4.2f\n", global_yawval);
// mySerial.printf("time = %ld\tyawdeg = %6.2f\n", millis(), global_yawval);
////DEBUG!!
}
return result; //added 01/16/19 to surpress warnings
}
Я заметил случайные неверные точки данных в вычисленных значениях курса, извлеченных из MPU6050, как показано на прилагаемом графике. Есть идеи, что я могу с этим поделать? Является ли обнаружение/удаление плохих значений ожидаемой проблемой при работе с продуктами IMU, такими как MPU6050?
В качестве эксперимента я исключил все точки, для которых скорость вращения была нереально высока, в результате чего на графике ниже появилась линия "Adj Hdg" (серая линия). Это (в основном) работает, за исключением одного случая, когда было два плохих значения подряд.
ТИА,
Фрэнк
@user3765883, 👍1
1 ответ
Похоже, что основным драйвером в "шуме" данных была скорость передачи данных FIFO, установленная с помощью константы MPU6050_DMP_FIFO_RATE_DIVISOR в MPU6050_6Axis_MotionApps20.h. Я изменил частоту со 100 Гц (0x01) на 20 Гц (0x09) и получил следующий почти полностью бесшумный график в тех же условиях, что и раньше. Обратите внимание на вертикальную шкалу - всего 6 градусов, и одна "экскурсия" - это изменение только на 4 градуса. Я также построил среднее беговое значение в 3 балла, что еще больше сокращает экскурсию до менее чем 2 град.
Поэтому, если вы ищете данные о чистом рыскании (заголовок) из MPU6050 DMP, подумайте об изменении скорости FIFO.
Фрэнк
- Как очистить буфер FIFO на MPU6050?
- Почему MPU6050 DMP не инициализируется, но я могу получить необработанные значения ускорения от MPU6050
- Взаимодействие MPU6050 с Arduino через S-функцию Simulink
- Проводка для Arduino Mega и нескольких MPU 6050/Gy 521
- Почему значение регистра чтения и записи гироскопа MPU6050 равно 0x08 для полной шкалы 500 градусов в секунду?
- Проблема прерывания библиотеки MPU6050 Arduino Jeff Rowberg
- Проблема с библиотекой MPU6050
- Arduino Mega и ошибочные значения гироскопа