Skip to contentSkip to main navigation Skip to footer

Arduino и акселерометр MPU6050

Описание


MPU6050 – трёх осевой осевой датчик ускорения (акселерометр) и угловой скорости (гироскоп). Используется для получения информации о положении в пространстве, движении, также может быть использован как датчик вибрации и удара. Микросхема гораздо умнее, чем кажется на первый взгляд: там есть встроенный процессор, который можно программировать, но железка реально сложная. Продаётся в виде удобного модуля:

Характеристики датчика:

  • Питание: 2.3.. 3.5V
  • Диапазон ускорений: от ±2g до ±16g
  • Диапазон угловых скоростей: от ±250 град/с до ±2000 град/с
  • Интерфейс: I2C

На модуле выведены:

  • VCC и GND: питание 3.. 5V (на модуле стоит стабилизатор)
  • SDA и SCL: вывод шины I2C для связи с МК
  • XDA и XCL: позволяют подключать к модулю другие датчики (например, магнитометр)
  • AD0: выбор адреса. Никуда не подключен: 0x68, подтянут к VCC – 0x69
  • INT: пин прерывания готовности (поведение настраивается в программе)

Подключение


Дисплей подключается по шине I2C, выведенной на пины:

  • Arduino: SDA – A4, SCL – A5
  • Wemos: SDA – D2, SCL – D1

Библиотеки


С модулем можно работать напрямую, а можно при помощи библиотеки от i2cdev. Нужные компоненты от i2cdev идут в архиве к набору, также их можно скачать с github разработчика: качаем весь архив, из него достаём Arduino/I2Cdev и Arduino/MPU6050, кладём себе в папку с библиотеками.

Примеры


Очень много полезной информации и примеров по данному датчику есть в статье на моём основном сайте!

Получаем сырые значения по осям

Простой пример с получением и выводом ускорений и угловых скоростей в порт:

#include <I2Cdev.h>
#include <MPU6050.h>
MPU6050 mpu;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  mpu.initialize();
  // состояние соединения
  Serial.println(mpu.testConnection() ? "MPU6050 OK" : "MPU6050 FAIL");
  delay(1000);
}

void loop() {
  int16_t ax, ay, az;
  int16_t gx, gy, gz;
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  Serial.print(ax); Serial.print('\t');
  Serial.print(ay); Serial.print('\t');
  Serial.print(az); Serial.print('\t');
  Serial.print(gx); Serial.print('\t');
  Serial.print(gy); Serial.print('\t');
  Serial.println(gz);
  delay(5);
}
Получаем углы поворота

Более сложный пример, получаем отфильтрованные углы по трём осям:

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
MPU6050 mpu;

uint8_t fifoBuffer[45];         // буфер

void setup() {
  Serial.begin(115200);
  Wire.begin();
  //Wire.setClock(1000000UL);   // разгоняем шину на максимум

  // инициализация DMP
  mpu.initialize();
  mpu.dmpInitialize();
  mpu.setDMPEnabled(true);
}

void loop() {
  static uint32_t tmr;
  if (millis() - tmr >= 11) {  // таймер на 11 мс (период готовности значений)    
    if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) {
      // переменные для расчёта (ypr можно вынести в глобал)
      Quaternion q;
      VectorFloat gravity;
      float ypr[3];

      // расчёты
      mpu.dmpGetQuaternion(&q, fifoBuffer);
      mpu.dmpGetGravity(&gravity, &q);
      mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

      // выводим результат в радианах (-3.14, 3.14)
      Serial.print(ypr[0]); // вокруг оси Z
      Serial.print(',');
      Serial.print(ypr[1]); // вокруг оси Y
      Serial.print(',');
      Serial.print(ypr[2]); // вокруг оси X
      Serial.println();
      // для градусов можно использовать degrees()

      tmr = millis();   // сброс таймера
    }
  }
}

Домашнее задание


Полезный пример?

Подписаться
Уведомить о
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии