Урок 11. Подключение гироскопа GY-521 MPU-6050 к Arduio.
Модуль Gy-521 выполнен на базе микросхемы MPU6050, это 3-осевой гироскоп и акселерометр. Данную модель можно использовать для определения положения в пространстве.
В данном уроке нам понадобится:
Для реализации проекта нам необходимо установить библиотеки:
В данном уроке рассмотрим библиотеку, которая позволяет преобразовать показания координат X и Y.
Подключение модуля производится следующим образом.
Gy-521 (mpu6050) | Arduino (Uno) |
---|---|
VCC | 3.3 V |
GND | GND |
SCL | A5 |
SDA | A4 |
Для питания модуля необходимо использовать строго 3.3V! Для этого можно использовать преобразователь напряжения на 3.3V.
Пришло время записать следующий скетч в нашу Arduino:
Данный пример пересчитывает координату X и Y и выводит в консоль (Монитор последовательного порта)
Когда X и Y равны 180, значит гироскоп находится в горизонтальной плоскости.
Учебное пособие по акселерометру и гироскопу MPU6050. Подключение к Ардуино
MPU6050 имеет 3-осевой акселерометр и 3-осевой гироскоп, интегрированные в один чип. Гироскоп измеряет скорость вращения или скорость изменения углового положения во времени по осям X, Y и Z. Для измерения используется технология MEMS и эффект Кориолиса.
Выходные данные гироскопа измеряются в градусах в секунду, поэтому для получения углового положения нам просто нужно интегрировать угловую скорость.
С другой стороны, акселерометр MPU6050 измеряет ускорение. Вкратце, он может измерять гравитационное ускорение по трем осям, и используя некоторую тригонометрию, мы можем вычислить угол, под которым расположен датчик. Итак, если мы объединим данные акселерометра и гироскопа, мы сможем получить очень точную информацию об ориентации датчика в пространстве.
MPU6050 также называют устройством слежения за движением по шести осям или устройством с 6 степенями свободы (шесть степеней свободы) из-за его 6 выходов, или 3 выхода акселерометра и 3 выхода гироскопа.
Ардуино и MPU6050
Давайте посмотрим, как мы можем подключить и прочитать данные с датчика MPU6050 с помощью Ардуино. Для связи с Ардуино мы используем протокол I2C, поэтому нам нужны всего два провода для подключения по линии данных и два провода для питания.
Скетч MPU6050 Ардуино
Ниже приведем полный код, а после разъясним его поподробнее:
Описание кода: Итак, сначала нам нужно подключить библиотеку Wire.h, которая используется для I2C связи, и определить некоторые переменные, необходимые для хранения данных.
В разделе setup() нам нужно инициализировать библиотеку Wire.h и сбросить датчик через регистр управления . Для этого нам нужно взглянуть в datasheet, где мы можем увидеть адрес регистра:
Также, если мы хотим, мы можем выбрать полный диапазон для акселерометра и гироскопа, используя их регистры конфигурации. В этом примере мы будем использовать диапазон по умолчанию + — 2g для акселерометра и диапазон 250 градусов/с для гироскопа, поэтому оставим эту часть кода закомментированной:
В разделе loop() мы начинаем с чтения данных акселерометра. Данные для каждой оси хранятся в двух байтах или регистрах, и мы можем видеть адреса этих регистров в datasheet датчика:
Чтобы прочитать их все, мы начинаем с первого регистра и с помощью функции RequiestFrom() запрашиваем чтение всех 6 регистров для осей X, Y и Z. Затем мы читаем данные из каждого регистра, и, поскольку выходные данные состроят из старшего и младшего байта, мы соответствующим образом объединяем их, чтобы получить правильные значения:
Чтобы получить выходные значения от -1g до + 1g, подходящие для расчета углов, мы делим выходной сигнал с предварительно выбранной чувствительностью.
Наконец, используя две формулы, мы вычисляем углы крена и тангажа на основе данных акселерометра:
Далее тем же методом получаем данные гироскопа:
Мы считываем шесть регистров гироскопа, соответствующим образом объединяем их данные и делим их на предварительно выбранную чувствительность, чтобы получить результат в градусах в секунду:
Здесь вы можете заметить, что выходные значения корректируются на величину ошибок (объясним далее). Поскольку выходные данные выражаются в градусах в секунду, то нам нужно умножить их на время, чтобы получить только градусы. Значение времени фиксируется перед каждой итерацией чтения с помощью функции millis().
Наконец, мы объединяем данные акселерометра и гироскопа с помощью дополнительного фильтра. Здесь мы берем 96% данных гироскопа, потому что они очень точны и не подвержены внешним воздействиям.
Обратной стороной гироскопа является то, что он дрейфует или вносит ошибку в выходной сигнал с течением времени. Поэтому в долгосрочной перспективе мы используем данные акселерометра, в данном случае 4%, что достаточно для устранения ошибки дрейфа гироскопа.
Однако, поскольку мы не можем рассчитать рыскание по данным акселерометра, мы не можем реализовать для него дополнительный фильтр.
Прежде чем мы взглянем на результаты, объясним, как получить значения коррекции ошибок. Для вычисления этих ошибок мы можем вызвать пользовательскую функцию calculate_IMU_error(), когда датчик находится в неподвижном положении.
Здесь мы делаем 200 измерений для всех выходов, суммируем их и делим на 200. Поскольку мы удерживаем датчик в горизонтальном неподвижном положении, ожидаемые выходные значения должны быть 0. Таким образом, с помощью этого расчета мы можем получить среднюю ошибку датчика.
Мы просто печатаем значения на последовательном мониторе, и, узнав их, мы можем реализовать их в коде, как показано ранее, как для расчета крена, так и для тангажа, а также для трех выходов гироскопа.
Работа с Arduino и MPU6050
MPU6050 представляет собой 3-х осевой гироскоп и 3-х же осевой акселерометр в одном корпусе. Сразу поясню, что это и для чего:
- Гироскоп измеряет угловую скорость вращения вокруг оси, условно в градусах/секунду. Если датчик лежит на столе – по всем трём осям будет значение около нуля. Для нахождения текущего угла по скорости нужно интегрировать эту скорость. Гироскоп может чуть привирать, поэтому ориентироваться на него для расчёта текущего угла не получится даже при идеальной калибровке.
- Акселерометр измеряет ускорение вдоль оси, условно в метрах/секунду/секунду. Если датчик лежит на столе или движется с постоянной скоростью – на оси будет спроецирован вектор силы тяжести. Если датчик движется с ускорением – вдобавок к ускорению свободного падения получим составляющие вектора ускорения. Если датчик находится в свободном падении (в том числе на орбите планеты) – величины ускорений по всем осям будут равны 0. Зная проекции вектора силы тяжести можно с высокой точностью определить угол наклона датчика относительно него (привет, школьная математика). Если датчик движется – однозначно определить направление вектора силы тяжести не получится, соответственно угол тоже.
Модуль стоит в районе 150 рублей на нашем любимом AliExpress (ссылка, ссылка), а также входит в Arduino набор GyverKIT.
Итак, по отдельности акселерометр и гироскоп не могут обеспечить точное измерение угла, но вместе – ещё как могут! Об этом мы поговорим ниже. А начнём с подключения и базового общения с датчиком.
Подключение
Датчик подключается на шину i2c (SDA -> A4, SCL -> A5, GND -> GND). На плате стоит стабилизатор, позволяющий питаться от пина 5V (VCC -> 5V).
На модуле выведен пин AD0. Если он никуда не подключен (или подключен к GND) – адрес датчика на шине i2c будет 0x68, если подключен к питанию (VCC) – адрес будет 0x69. Таким образом без дополнительных микросхем можно подключить два датчика на шину с разными адресами.
Получение сырых данных
Библиотека MPU6050 от i2cdev
Расшифровка сырых данных
По каждой оси и параметру датчик выдаёт 16-битное знаковое значение ( -32768.. 32767 ). При стандартных настройках (как в примерах выше) это значение отражает:
- Ускорение в диапазоне -2.. 2 g (9.82 м/с/с).
- Угловую скорость в диапазоне -250.. 250 градусов/секунду.
Таким образом, для перевода сырых данных в величины СИ (если это нужно) можно сделать по каждой оси:
- Ускорение в м/с/с при чувствительности 2: float accX_f = accX / 32768 * 2
- Угловая скорость в град/с при чувствительности 250: float gyrX_f = gyrX / 32768 * 250
Думаю закономерность понятна.
Настройка чувствительности
Датчик позволяет настроить чувствительность по каждому параметру, в библиотеке i2cdev это делается так:
- setFullScaleAccelRange(MPU6050_ACCEL_FS_2); – диапазон -2.. 2 g
- setFullScaleAccelRange(MPU6050_ACCEL_FS_4); – диапазон -4.. 4 g
- setFullScaleAccelRange(MPU6050_ACCEL_FS_8); – диапазон -8.. 8 g
- setFullScaleAccelRange(MPU6050_ACCEL_FS_16); – диапазон -16.. 16 g
- setFullScaleGyroRange(MPU6050_GYRO_FS_250); – диапазон -250.. 250 град/с
- setFullScaleGyroRange(MPU6050_GYRO_FS_500); – диапазон -500.. 500 град/с
- setFullScaleGyroRange(MPU6050_GYRO_FS_1000); – диапазон -1000.. 1000 град/с
- setFullScaleGyroRange(MPU6050_GYRO_FS_2000); – диапазон -2000.. 2000 град/с
Перевести сырые данные можно таким же способом, как в предыдущем пункте, но с учётом нового диапазона.
Калибровка оффсетов
Для достижения максимальной точности измерений нужно откалибровать акселерометр и гироскоп. Калибровка акселерометра позволяет выставить “ноль” для вектора силы тяжести, а калибровка гироскопа уменьшает его “дрифт”, то есть статическое отклонение в режиме покоя. Идеально откалиброванный и лежащий горизонтально датчик должен показывать ускорение
16384 по оси Z и нули по всем остальным осям ускорения и угловой скорости. Но это фантастика =)
Максимально правильно использовать калибровку в проекте нужно так: калибровка по запросу (кнопка, меню, и т.д.), затем запись калибровочных значений в EEPROM. При запуске – чтение и настройка оффсетов из. Рассмотрим несколько примеров калибровки, первый – из библиотеки. Калибрует долго, но максимально точно. При малых вибрациях и движениях датчика в процессе калибровки (даже от громкого звука) калибровка может не закончиться. Второй вариант – мой упрощённый алгоритм калибровки, калибрует быстро, без возможности зависнуть при тряске, но даёт менее точный результат. Я делюсь примерами, в свой проект их нужно будет переносить вручную и аккуратно =)
Алгоритмы калибровки
16384 по оси Z и нули по всем остальным осям ускорения и угловой скорости. Но это фантастика =) Максимально правильно использовать калибровку в проекте нужно так: калибровка по запросу (кнопка, меню, и т.д.), затем запись калибровочных значений в EEPROM. При запуске – чтение и настройка оффсетов. Да, можно замерить значения по всем 6 осям в покое, сохранить их в переменные, а затем вычитать из свежих прочитанных в процессе работы. Такой способ работает для каких-то базовых операций с датчиком (определение перегрузок, тряски, наличия вращения, и т.д.). Для использования MPU6050 с целью максимально точного определения углов поворота платы такой вариант к сожалению не подходит: калибровать нужно рекурсивно. Рассмотрим несколько примеров калибровки, первый – из библиотеки. Калибрует долго, но максимально точно. При малых вибрациях и движениях датчика в процессе калибровки (даже от громкого звука) калибровка может не закончиться. Второй вариант – мой упрощённый алгоритм калибровки, калибрует быстро, без возможности зависнуть при тряске, но даёт менее точный результат. Я делюсь примерами, в свой проект их нужно будет переносить вручную и аккуратно =)
Подключение гироскопа и акселерометра MPU6050 к ESP32
Датчик MPU6050 состоит из акселерометра и гироскопа, объединенных в составе одного чипа. Он содержит 16-битный аналого-цифровой преобразователь (АЦП) на каждый канал. Таким образом, он одновременно может считывать показания по всем осям x, y и z. Для взаимодействия с платами Arduino или другими микроконтроллерами модуль использует интерфейс I2C. Модуль MPU-6050 находит широкое применение в дронах, роботах, датчиках движения и т.д.
В данной статье мы рассмотрим подключение гироскопа и акселерометра MPU6050 к модулю ESP32 и будем выводить считываемые с него значения на веб-сервер. Ранее на нашем сайте мы рассматривали подключение гироскопа MPU6050 к платам Arduino и Raspberry Pi. Также у нас на сайте вы можете посмотреть все проекты с использованием модуля MPU6050.
Необходимые компоненты
- ESP32 NodeMCU (купить на AliExpress).
- Модуль акселерометра и гироскопа MPU6050 (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Гироскопический датчик (гироскоп) MPU-6050
MPU-6050 представляет собой 8-пиновый 6-осевой гироскоп и акселерометр на едином чипе. По умолчанию данный модуль работает по интерфейсу I2C, но можно задействовать и интерфейс SPI. В нашем проекте мы будем использовать интерфейс (режим) I2C и в этом режиме нам понадобятся контакты SDA и SCL модуля.
Распиновка MPU-6050:
Vcc – контакт для подачи питающего напряжения постоянного тока;
GND – земля модуля;
SDA – это контакт используется для передачи данных между модулем mpu6050 и микроконтроллером;
SCL – вход синхронизации;
XDA – линия передачи данных (опциональная) по протоколу I2C для конфигурирования и считывания данных с внешних датчиков (не используется в нашем проекте);
XCL – вход синхронизации протокола I2C для конфигурирования и считывания данных с внешних датчиков (не используется в нашем проекте);
ADO – I2C Slave Address LSB (не используется в нашем проекте);
INT – контакт прерывания для индикации готовности данных.
Схема проекта
Схема подключения гироскопа MPU6050 к модулю ESP32 представлена на следующем рисунке.
Модуль MPU6050 взаимодействует с ESP32 по интерфейсу I2C, поэтому нам необходимо всего два провода для его подключения. Контакты SCL и SDA модуля MPU6050 мы подключим к контактам D22 и D21 модуля ESP32, а контакты VCC и GND модуля MPU6050 подсоединим к контактам 3.3V и GND модуля ESP32.
Объяснение программы для модуля ESP32
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Первым делом в программе мы подключим используемые библиотеки. Библиотека Wire.h позволяет взаимодействовать с I2C/TWI устройствами, а библиотека WiFi.h позволяет модулю ESP32 подключаться к сетям Wi-Fi.