Калибровочный акселерометр MPU6050
Недавно я получил MPU6050 и заметил, что данные акселерометра немного сбились, особенно по оси Z.
Я запускаю его на Teensy версии 4.0 с библиотекой MPU6050 Adafruit и базовым примером кода: https://github.com/adafruit/Adafruit_MPU6050/blob/master/examples/basic_readings/basic_readings.ino
Будучи стабильным на плоской поверхности (+Z вверх), он показывает ~8,5 м/с^2, а при переворачивании (-Z вверх) ~11,6 м/с^2:
+Z:
Acceleration X: -0.06, Y: 0.00, Z: 8.44 m/s^2
-Z:
Acceleration X: -0.01, Y: -0.07, Z: -11.57 m/s^2
Выравнивание других осей по вертикали дает мне:
+X:
Acceleration X: 10.16, Y: -0.16, Z: -0.03 m/s^2
-X:
Acceleration X: -9.27, Y: -0.10, Z: -0.18 m/s^2
+Y:
Acceleration X: 0.07, Y: 9.55, Z: -0.10 m/s^2
-Y:
Acceleration X: 0.04, Y: -9.93, Z: -0.05 m/s^2
Показания X и Y могут быть скорректированы довольно близко к 9,81 м/с^2 только со смещением, но, похоже, ось Z также потребует некоторого масштабирования.
Мой вопрос: существует ли стандартный метод его калибровки в коде?
@Koszuta, 👍2
3 ответа
Лучший ответ:
У меня была точно такая же проблема: при повороте датчика в разные стороны я измерял силу тяжести в диапазоне от 7 м/с^2 до 10,5 м/с^2. Я пришёл к тому же решению, которое описывает st2000. Я немного опоздал к обсуждению, но решил поделиться своим решением, чтобы помочь всем, кто столкнулся с той же проблемой.
Сначала я перевернул датчик на все 6 сторон, чтобы зафиксировать приблизительное максимальное и минимальное ускорение, которое я получил по каждой оси из-за силы тяжести (каждая ось должна показывать где-то от 16 000 до 17 000, если предположить, что чувствительность установлена на 2G).
Мои показания на тот момент были:
Minimum | Maximum
X | -15,700 | 17,000
Y | -16,650 | 16,250
Z | -16,600 | 16,800
Затем я вывел формулу линейной коррекции, которая брала бы необработанные показания акселерометра и выдавала ускорение в м/с². Сначала я рассчитал «смещение центра» каждой оси, просто усреднив минимальные и максимальные показания для каждой оси.
axis_min + axis_max
Center = ---------------------
2
Затем я масштабировал вывод в соответствии с его диапазоном так, чтобы при максимальном показании оси вывод был равен 9,8, а когда необработанные показания были около минимума, вывод был равен -9,8.
G = 9.80665 (Acceleration due to gravity)
Range = axis_max - axis_min
G
----------- 2 * G 2 * G
Scale = Range = ------- = ---------------------
------- Range axis_max - axis_min
2
Теперь, сложив все вместе, мы получаем следующее линейное уравнение для расчета ускорения по каждой оси:
2 * G z_min + z_max
A(x) = Scale * (x - Center) = --------------------- * (x - ---------------)
axis_max - axis_min 2
Функция в реальном коде выглядит так:
float axis_correction(float raw_reading, float axis_min, float axis_max, float grav_accel) {
return (float)(2.f * grav_accel * (raw_reading - (axis_min + axis_max) / 2.f)) / (axis_max - axis_min);
}
С этим я получаю стабильные 9,75–9,88 м/с². Полагаю, что с большей настройкой я смогу ещё уменьшить этот разброс, но это уже намного лучше показаний, которые я получал с помощью любой из доступных библиотек. Для справки, вот график показаний акселерометра.

На графике показаны обработанные показания. Красная линия — это суммарная величина ускорения, испытываемого датчиком. Фиолетовая линия — номинальное ускорение свободного падения. Остальные три линии — отдельные ускорения по каждой оси. Как видно, величина ускорения очень близка к номинальному ускорению свободного падения, равному 9,8 (за исключением пиков и колебаний, возникающих при переворачивании датчика).
Возможность надежного измерения силы тяжести с различных ориентаций была очень важна для моего конкретного приложения, и этот метод калибровки должен отлично подойти мне и, надеюсь, другим, столкнувшимся с той же проблемой!
Да, акселерометр можно откалибровать. Смещение для каждого из 3 акселерометров может быть найдено таким, чтобы абсолютные значения максимального и минимального значений любой заданной оси акселерометра были равны. Максимальное и минимальное значения можно найти, повернув акселерометр таким образом, чтобы каждая ось была направлена прямо к земле и прямо от нее. Как только каждая ось нормализуется, каждой оси требуется значение регулировки величины, чтобы максимальное значение всех осей было равно друг другу. Может быть удобно, чтобы произведение максимума любой заданной оси и значение регулировки величины осей составляло 9,8 (метров в секунду * секунду).
Да, библиотека Джеффа Роуберга выполняет калибровку за вас, когда вы включаете питание. Вам нужно будет убедиться, что модуль лежит ровно и неподвижно, а затем отправить символ по последовательному каналу, чтобы вызвать калибровку. Версия, основанная на библиотеке Джеффа, называемая Electronic Cats, может быть загружена непосредственно с помощью Arduino IDE.
Обратите внимание, что библиотека Джеффа немного ошеломляет/пугает новых пользователей. Если вы хотите узнать больше о том, как скрыть его сложность за простым и удобным интерфейсом, или о возможности сохранения результатов калибровки в постоянной памяти,чтобы вам не приходилось выполнять калибровку каждый раз при включении питания, или просто хотите узнать больше об этой теме в целом, пожалуйста, обратитесь к следующему учебнику:
https://youtu.be/k5i-vE5rZR0
- Как подключить вывод INT MPU 6050?
- Как очистить буфер FIFO на MPU6050?
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- MPU6050 не работает
- Как найти индекс максимального значения в массиве?
- Понимание того, почему следует избегать «String» и альтернативных решений
- Как подключить MPU9250 к NodeMCU с помощью SPI или I2C Slave?
- Вложенный цикл
Не могли бы вы поделиться статьей или ссылкой, чтобы мы могли посмотреть. Я понимаю, о чем вы говорите, но понятия не имею, как на самом деле это сделать., @Zhelyazko Grudov
Немного сложно найти подходящую статью. Это [NIST article](https://www.nist.gov/programs-projects/dynamic-mechanical-metrology-acceleration-force-and-acoustics/3-axis-accelerometer) выходит за рамки, предполагая, что 3 акселерометра могут даже не быть ортогональными. И другие статьи пропускают калибровку акселерометра (честно говоря, акселерометры обычно хороши из коробки для большинства приложений Arduino). Попробуйте это [Adafruit article](https://learn.adafruit.com/adafruit-analog-accelerometer-breakouts/calibration-and-programming) это похоже на то, что вам нужно., @st2000
Спасибо за ваш комментарий, @Zhelyazko Grudov