Ардуино: акселерометр MPU6050

Акселерометр — это прибор, позволяющий измерять ускорение тела под действием внешних сил. Подробно об устройстве этого датчика мы уже рассказывали на одном из уроков: Акселерометр: что это такое и как им определять наклон тела

На этот раз мы перейдем от теории к практике: подключим датчик к Ардуино, и напишем пару программ для работы с ним. Подключать будем модуль MPU6050 от RobotClass.

Акселерометр и гироскоп MPU6050 от RobotClass - ROC

В основе этого модуля лежит микросхема MPU6050, в которой размещаются сразу два датчика: акселерометр и гироскоп. На плате уже имеется вся необходимая обвязка, а также преобразователь напряжения.

Характеристики модуля MPU6050 ROC:

  • напряжение питания: от 3,5 до 6 В;
  • потребляемый ток: 500 мкА;
  • ток в режиме пониженного потребления: 10 мкА при 1,25 Гц, 20 мкА при 5 Гц, 60 мкА при 20 Гц, 110 мкА при 40 Гц;
  • диапазон: ± 2, 4, 8, 16g;
  • разрядность АЦП: 16;
  • интерфейс: I2C (до 400 кГц).

На плате имеется 8 контактов:

  • VCC — положительный контакт питания;
  • GND — земля;
  • SDA — линия данных I2C;
  • SCL — линия синхроимпульсов I2C;
  • INT — настраиваемое прерывание;
  • AD0 — I2C адрес; по-умолчанию AD0 подтянут к земле, поэтому адрес устройства — 0x68; если соединить AD0 к контактом питания, то адрес изменится на 0x69;
  • XCL, XDA — дополнительный I2C интерфейс для подключения внешнего магнитометра.

1. Подключение MPU6050 к Ардуино

Соединим контакты датчика с Ардуино Уно согласно стандартной схеме для интерфейса I2C:

MPU6050 ROC GND VCC SDA SCL
Ардуино Уно GND +5V A4 A5

Принципиальная схема

Схема подключения MPU6050 к Ардуино

Внешний вид макета

Схема подключения MPU6050 к Ардуино

2. Программа для получения сырых данных с акселерометра MPU6050

Составим программу, которая будет каждые 20 миллисекунд получать данные из MPU6050 и выводить их в последовательный порт.

#include "I2Cdev.h"
#include "MPU6050.h"

#define T_OUT 20

MPU6050 accel;

unsigned long int t_next;

void setup() {
    Serial.begin(9600);
    accel.initialize();
    Serial.println(accel.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
}

void loop() {
    long int t = millis();
    if( t_next < t ){
        int16_t ax_raw, ay_raw, az_raw, gx_raw, gy_raw, gz_raw;

        t_next = t + T_OUT;
        accel.getMotion6(&ax_raw, &ay_raw, &az_raw, &gx_raw, &gy_raw, &gz_raw);
 
        Serial.println(ay_raw); // вывод в порт проекции ускорения на ось Y
    }
}

Для работы программы потребуются библиотеки: MPU6050 и I2Cdev, ссылки на которые можно найти в конце урока.

Загружаем программу на Ардуино и открываем окно графика. Поворачиваем датчик вокруг оси X на 90 градусов в одну сторону, потом на 90 в другую. Получится примерно такая картина.

Сырые данные с акселерометра MPU6050

На графике хорошо видно, что при наклоне оси Y вертикально, акселерометр выдает значения близкие к 4000 тысячам. Откуда берется это число?

3. Точность измерения ускорения в MPU6050

Дело в том, что датчик MPU6050 позволяет настраивать точность измерений. Можно выбрать один из четырех классов точности: ±2G, 4G, 8G и 16G, где 1G — это одна земная гравитация.  Используемая нами библиотека по-умолчанию настраивает датчик на диапазон ±8G (прим. по ссылке внизу статьи библиотека по-умолчанию устанавливает ±2G).

С другой стороны, MPU6050 имеет 16 разрядный АЦП. 2 в степени 16 даст нам число 65 536. Поскольку датчик может измерять и отрицательное и положительное ускорение, то он будет выдавать нам числа от -32768 до +32768.

Сложив эти два факта вместе получаем, что при таких настройках 1G будет равен числу 4096 (ну а -1G равен числу -4096). Это вполне совпадает с наблюдаемыми на графике значениями!

Следующий шаг — преобразование этих странных чисел в привычные нам углы, измеряемые в градусах.

4. Программа для вычисления угла наклона акселерометра MPU6050

Добавим в предыдущую программу вычисление угла поворота датчика вокруг оси X:

#include "I2Cdev.h"
#include "MPU6050.h"

#define TO_DEG 57.29577951308232087679815481410517033f
#define T_OUT 20

MPU6050 accel;

float angle_ax;
long int t_next;

float clamp(float v, float minv, float maxv){
    if( v>maxv )
        return maxv;
    else if( v<minv )
        return minv;
    return v;
}

void setup() {
    Serial.begin(9600);
    accel.initialize(); // первичная настройка датчика
    Serial.println(accel.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
}

void loop() {
    long int t = millis();
    if( t_next < t ){
        int16_t ax_raw, ay_raw, az_raw, gx_raw, gy_raw, gz_raw;
        float ay,gx;

        t_next = t + T_OUT;
        accel.getMotion6(&ax_raw, &ay_raw, &az_raw, &gx_raw, &gy_raw, &gz_raw);
 
        // сырые данные акселерометра нужно преобразовать в единицы гравитации
        // при базовых настройках 1G = 4096
        ay = ay_raw / 4096.0;
        // на случай, если на акселерометр действуют посторонние силы, которые могут
        // увеличить ускорение датчика свыше 1G, установим границы от -1G до +1G  
        ay = clamp(ay, -1.0, 1.0);

        // функция acos возвращает угол в радианах, так что преобразуем
        // его в градусы при помощи коэффициента TO_DEG
        if( ay >= 0){
            angle_ax = 90 - TO_DEG*acos(ay);
        } else {
            angle_ax = TO_DEG*acos(-ay) - 90;
        }
 
        Serial.println(angle_ax); // вывод в порт угла поворота вокруг оси X
    }
}

Загружаем программу в Ардуино и снова пробуем вращать датчик. Теперь на графике отображается угол наклона в градусах!

График угла наклона, полученного с помощью акселерометра MPU6050

Ну вот, мы получили уже что-то пригодное для дальнейшего использования. Видно, что датчик поворачивался сначала на 30 с лишним градусов в одну сторону, потом примерно на 60 в другую. Работает!

Заключение

На этом уроке мы получили с датчика MPU6050 сначала сырые данные, а потом и угол его наклона в градусах. Это большое достижение. Но впереди еще немного математики и еще более крутые результаты! Будем делать комплементарный фильтр, который позволит работать с датчиком даже в условиях вибрации и тряски.

Полезные ссылки

0

Изменено:

Ардуино: акселерометр MPU6050: 5 комментариев

  1. Подробная статья, чувствуется что автор хорошо владеет материалом.
    А не доводилось ли автору использовать MPU-6050 для вычисления траектории? Если такой опыт имеется, то прошу поделиться. Спасибо!

    0

  2. Всё хорошо, но автору нужно быть корректнее. Если что-то объясняешь, то не должно быть ошибок. Иначе начинающий, попробовав приведённые примеры и не получив положительного результата, может вообще забить на тему.
    Загрузив первый пример, тут же получаешь ошибку компиляции. А проблема в ошибке: Объявляется MPU6050 accel;, а дальше применяется accelgyro (должно быть одинаково). Мелочь, конечно, но начинающего может ввести в ступор. Далее объясняется, откуда взялось «4000 тысячам», а фактически значения около 16000. Фразу «открываем окно графика» тоже не сразу понять. Оказывается, в версии 1.8.5 IDE Arduino появилось «Плоттер по последовательному соединению». Дальше пока не разбирался, но хотелось бы начать въежать в тему, а не ребусы разгадывать.

    0

    • Владимир, спасибо за замечания! Код исправили. Насчёт 4000 вместо 16000, то это особенность той версии библиотеки, с которой запускалась программа. В текущей версии действительно стоит другой диапазон — ±2G, поэтому и числа у вас ±16000.
      А плоттер хорошая штука, рекомендую всегда иметь под рукой свежую версию IDE, благо она свободно распространяемая!

      0

  3. Подскажите, где в программе обозначено, что подключаться надо к А4 и А5?

    0

    • Эти пины явно не указываются, так как библиотека I2cdev использует по-умолчанию аппаратный i2c на выбранном типе контроллера. A4 и A5 — это как раз аппаратный i2c на atmega328.

      0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.