Гироскоп-акселерометр MPU-6050: обзор и подключение
Что это за модуль
MPU-6050 — первый массовый IMU-чип, который объединил в одном корпусе трёхосевой гироскоп и трёхосевой акселерометр плюс цифровой термометр. Чип делает InvenSense (теперь TDK), документ PS-MPU-6000A-00, ревизия 3.4. На китайских платах типа GY-521 к чипу добавляют стабилизатор на 3,3 В и подтяжки I2C, поэтому модуль спокойно подключается и к 5-вольтовой Arduino, и к ESP32.
Зачем нужен именно этот модуль новичку: если вы хотите, чтобы устройство понимало, что его наклонили, перевернули, трясут или двигают — это он. Робот, который держит равновесие, дрон-квадрокоптер, сигнализация «кто-то тронул посылку», счётчик шагов — всё это делается на MPU-6050. Плюс внутри есть DMP — аппаратный сопроцессор «Digital Motion Processor», который сам считает фьюжн гироскопа и акселерометра и выдаёт готовый кватернион, не нагружая ваш Arduino вычислениями.
Что датчик реально меряет
Важно понять физику до покупки. Гироскоп меряет угловую скорость в градусах в секунду — то есть «вращаюсь со скоростью 90 °/с». Он НЕ показывает угол напрямую: чтобы получить угол, показания нужно интегрировать по времени, и из-за дрейфа нуля угол за минуты уползает. Акселерометр меряет ускорение, включая статическое g — по нему виден наклон относительно земли (в покое 1g проецируется на ось). Классический фьюжн: акселерометр даёт долгосрочную опору «где низ», гироскоп — быструю краткосрочную динамику.
Характеристики из паспорта производителя
Все числа ниже — из Product Specification InvenSense, ревизия 3.4 (2013), разделы 6.1–6.3. Паспорт формально даёт диапазон питания чипа 2,375–3,46 В; на плате GY-521 стоит LDO, от которого питается чип — но I2C-интерфейс на модуле живёт от 3,3 В, поэтому напрямую к 5-вольтовым Arduino UNO его подключают через уже имеющиеся подтяжки на плате к 3,3 В (модуль совместим, но лить 5 В на пины SDA/SCL без подтяжек к 5 В — неправильная практика).
| Параметр | Значение | Источник |
|---|---|---|
| Диапазон питания чипа (VDD) | 2,375–3,46 В (номинал 3,3 В) | раздел 6.3 |
| Ток потребления (гиро+акселерометр, без DMP) | 3,8 мА тип. | раздел 6.3 |
| Ток с включённым DMP | 3,9 мА тип. | раздел 6.3 |
| Диапазон шкалы гироскопа (FS_SEL) | ±250 / ±500 / ±1000 / ±2000 °/с | раздел 6.1 |
| Разрядность АЦП гироскопа | 16 бит | раздел 6.1 |
| Чувствительность гироскопа, FS_SEL=0 | 131 LSB/(°/с) | раздел 6.1 |
| Допуск чувствительности | ±3 % | раздел 6.1 |
| Допуск смещения нуля гироскопа (ZRO), 25 °C | ±20 °/с | раздел 6.1 |
| Вариация ZRO по температуре (−40…+85 °C) | ±20 °/с | раздел 6.1 |
| Гироскоп, суммарный RMS-шум, DLPF 100 Гц | 0,05 °/с-rms | раздел 6.1 |
| Диапазон шкалы акселерометра (AFS_SEL) | ±2 / ±4 / ±8 / ±16 g | раздел 6.2 |
| Чувствительность акселерометра, AFS_SEL=0 | 16 384 LSB/g | раздел 6.2 |
| Допуск нулевого уровня (zero-g), оси X и Y | ±50 мг | раздел 6.2 |
| Допуск нулевого уровня, ось Z | ±80 мг | раздел 6.2 |
| Частота выборки гироскопа | 3,9…8000 Гц (программируемая) | раздел 6.1 |
| Частота выборки акселерометра | 4…1000 Гц | раздел 6.2 |
| Полоса низкочастотного фильтра (DLPF) | 5…256 Гц (гиро), 5…260 Гц (акселерометр) | разделы 6.1, 6.2 |
| Термометр: диапазон | −40…+85 °C | раздел 6.3 |
| Термометр: линейность | ±1 °C | раздел 6.3 |
| Интерфейс | I2C (до 400 кГц), адрес 0x68 или 0x69 | раздел 6.3 |
Встроенный термометр — это температура самого кристалла, не окружающего воздуха. Использовать его вместо DS18B20 нельзя: погрешность ±1 °C плюс самонагрев чипа делают его пригодным только для температурной компенсации самого датчика. Если нужен точный датчик температуры — смотрите обзор DS18B20 на этом сайте.
Подключение к Arduino и ESP32
Модуль общается по I2C, адрес по умолчанию 0x68. Если пин AD0 платы GY-521 посадить на высокий уровень, адрес станет 0x69 — так к одной шине подключают два MPU-6050. На Arduino UNO работают аппаратные пины A4 (SDA) и A5 (SCL); на ESP32 удобно взять 21 (SDA) и 22 (SCL).
Схема Arduino UNO:
- VCC модуля → 5 В (плата должна подавать питающий LDO, у GY-521 обычно разрешено и 3,3 В — смотрите маркировку LDO);
- GND → GND;
- SCL модуля → A5;
- SDA модуля → A4;
- INT, AD0 — не подключены (INT можно завести на D2, если хотите пробуждение по прерыванию от motion-детектора).
Схема ESP32: VCC → 3V3, GND → GND, SDA → GPIO21, SCL → GPIO22.
Рабочий код
Вариант без библиотек через raw Wire — читаем регистры 0x3B…0x47 напрямую, чтобы понять, что происходит физически:
#include <Wire.h>
const uint8_t MPU = 0x68;
// делители для перевода "сырых" значений в физические величины.
// Числа взяты из datasheet InvenSense: 131 LSB/(°/с) для гиро при FS_SEL=0,
// 16384 LSB/g для акселерометра при AFS_SEL=0, 340 LSB/°C для термометра.
void setup() {
Serial.begin(115200);
Wire.begin(); // ESP32: Wire.begin(21, 22);
Wire.beginTransmission(MPU);
Wire.write(0x6B); // PWR_MGMT_1
Wire.write(0x00); // выводим чип из сна
Wire.endTransmission(true);
}
void loop() {
Wire.beginTransmission(MPU);
Wire.write(0x3B); // ACCEL_XOUT_H — начинаем читать с него
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14); // 14 байт: 6 аксель + 2 темп + 6 гиро
int16_t ax = (Wire.read() << 8) | Wire.read();
int16_t ay = (Wire.read() << 8) | Wire.read();
int16_t az = (Wire.read() << 8) | Wire.read();
int16_t tt = (Wire.read() << 8) | Wire.read();
int16_t gx = (Wire.read() << 8) | Wire.read();
int16_t gy = (Wire.read() << 8) | Wire.read();
int16_t gz = (Wire.read() << 8) | Wire.read();
float ax_g = ax / 16384.0; // в "g"
float gz_dps = gz / 131.0; // в градусах в секунду
float t = tt / 340.0 + 36.53; // даташит-формула
Serial.print("ax="); Serial.print(ax_g, 3);
Serial.print(" g az="); Serial.print(az / 16384.0, 3);
Serial.print(" gz="); Serial.print(gz_dps, 2);
Serial.print(" °/s t="); Serial.println(t, 1);
delay(300);
}
Если нужен не сырой поток, а готовый угол наклона — берите библиотеку Adafruit MPU6050 или «MPU6050» Джеффа Роуберга, она сама выставит DMP и отдаст yaw/pitch/roll из кватерниона.
Частые ошибки
- Калибруют только один раз в setup(). Паспорт даёт допуск нуля гироскопа ±20 °/с, и это число реально заметно. Перед интегрированием нужно считать среднее показаний за пару секунд при неподвижном модуле и вычитать его каждый раз — иначе интеграл уплывает.
- Забывают, что гироскоп меряет скорость, а не угол. Пришёл новичок, посмотрел на gx в «градусах в секунду», ожидая там «наклон в градусах», и не понял, почему «датчик врёт». Нужна интеграция или библиотека с DMP.
- Питают не через встроенный LDO. Чип внутри — 3,3-вольтовый (паспорт 2,375–3,46 В). Если на китайской карте есть LDO, а вы случайно убрали её способность снизить питание — чип сгорит. Перед подключением к 5 В проверьте, есть ли на плате стабилизатор.
- Акселерометр «прыгает» вместе с самим датчиком. При движении модуля на нём видно не только g, но и инерционные ускорения. Если пытаться по акселерометру мерять угол в момент тряски — ответ будет дребезгом. Это нормально, нужен фильтр или фьюжн с гиро.
- На ESP32 пины 21/22 используют с чужой подтяжкой на 5 В. ESP32 — чип 3,3-вольтовый, пин SDA/SCL не любит вольты выше 3,3 В. На модулях GY-521 подтяжки уже идут на VCC модуля (как правило 3,3 В), поэтому просто не подключайте VCC модуля к 5 В на ESP32.
- Кладут библиотеку Wire.begin() после Serial.begin() в нестандартном порядке и получают «device not found» на 0x68 — это частая дезинформация у новичков с i2c_scanner. Если сканер не видит 0x68, первым делом проверьте питание (LED на модуле) и пины: UNO — A4/A5, ESP32 — 21/22, а не «D3/D4» из чужого скетча.
Итог
MPU-6050 — модуль «на все руки» для движения: дешёвый (плата на Ali копеечная), с DMP внутри, отлично работает связкой с Arduino и ESP32. Для множества проектов «реагируй на наклон/толчок/встряску» это лучший первый выбор. Хотите ориентироваться в соседних датчиках — смотрите также обзор датчика температуры DS18B20 и обзор ёмкостного датчика влажности почвы v1.2.
Информация собрана из открытых источников и паспортов производителей и не является истиной в последней инстанции. Характеристики, распиновку и совместимость проверяйте по документации конкретной партии модуля перед покупкой и подключением.