Как сделать электронный компас на датчике MPU-9250 и Arduino

Содержание

Разобьём всю задачу на более мелкие подзадачи. Так сказать, проведём декомпозицию. И по шагам опишем весь процесс создания электронного компаса. Для проекта нам понадобятся:

  • многофункциональный датчик MPU-9250; ; для управления индикатором;
  • 7 резисторов по 220 Ом (рекомендую набор резисторов с номиналами от 10 Ом до 1 МОм); ; или иная совместимая плата;
  • соединительные провода (например, вот такой набор); ;
  • персональный компьютер со средой разработки Arduino IDE.

1 Подключение датчика MPU-9250к Arduino

Датчик MPU-9250 это по сути несколько датчиков, расположенных на одном чипе. Так, он реализует функции 3-осевого гироскопа, 3-осевого акселерометра и 3-осевого магнитометра. В данном проекте мы будем использовать только магнитометр. Остальные датчики можно отключить в целях уменьшения потребляемого тока, т.к. будем делать портативное устройство, питающееся от батареи Крона.

Внешний вид модуля с датчиком MPU-9250 Внешний вид модуля с датчиком MPU-9250

Модуль имеет 10 выводов. Вот их назначение:

Вывод Назначение вывода модуля с MPU-9250 (MPU-9255)
VCC Внешнее питание 3.3 В.
GND Общий.
SCL Линия тактовых импульсов I2C и SPI.
SDA Линия данных для I2C или SPI.
EDA Линия данных при подключении внешних датчиков по шине I2C.
ECL Линия тактов при подключении внешних датчиков по шине I2C.
AD0 Для выставления адреса I2C в режиме I2C. В режиме SPI это линия данных от датчика.
INT Линия прерываний. Срабатывание настраивается при конфигурировании датчика MPU-9250.
NCS В режиме SPI линия выбора ведомого (chip select). В режиме I2C не соединяется ни с чем.
FSYNC Зависит от конфигурации.

Прежде чем подключать датчик MPU-9250 к Arduino, проверим его работоспособность с помощью моей любимой платы с микросхемой FT2232H. Для самого простого теста прочитаем содержимое регистра датчика, в котором содержится постоянное значение. Таким регистром может служить, например, регистр, в котором хранится идентификатор магнитометра, равный 0x48. Подключаться будем по интерфейсу I2C (для сокращения числа проводников). Как и большинство датчиков, MPU-9250 является ведомым на I2C шине. Схема подключения предельно проста: питание +3.3 В подаётся на вывод VCC, земля GND, тактовая частота приходит на вывод SCL с ножки ADBUS0 микросхемы FT2232, линия данных SDA подключается одновременно к выводам ADBUS1 и ADBUS2 микросхемы FT2232.

Подключение датчика MPU-9250 по I2C в качестве ведомого к микросхеме FT2232H Подключение датчика MPU-9250 по I2C в качестве ведомого к микросхеме FT2232H

Теперь, когда всё подключено, запускаем в режиме I2C программу SPI via FTDI, многократно описанную нами ранее. Оставляем настройки по умолчанию и сканируем шину I2C. Мы увидим, что программа обнаружила на шине одно устройство по адресу 0x68. Если прочитать из него 127 байтов (именно столько регистров имеет датчик MPU9250, техническое описание можно скачать в приложении к статье), то увидим следующее:

Чтение всех регистров датчика MPU-9250 по I2C с помощью FT2232 Чтение всех регистров датчика MPU-9250 по I2C с помощью FT2232

Здесь нет показаний магнитометра. Магнитометр (он называется AK8963) это отдельное устройство на кристалле, которое не активно при подаче питания на датчик MPU-9250. Его нужно активировать явно. Для этого необходимо в регистр под номером 0x37 (INT_PIN_CFG) записать значение 0x02. Для этого в программе в поле записи укажем команду "37 02", как на рисунке, и нажмём кнопку Записать. Полное описание регистра приводится далее.

Включение магнитометра датчика MPU-9250 через регистр I2C_SLV0_ADDR Включение магнитометра датчика MPU-9250 через регистр I2C_SLV0_ADDR

Карта регистров магнитометра AK8963 представляет собой довольно короткую таблицу, состоящую всего из 13-ти байтов:

Карта регистров магнитометра MPU-9250 Карта регистров магнитометра MPU-9250 Чтение регистров магнитометра MPU-9250 по I2C Чтение регистров магнитометра MPU-9250 по I2C

Как видно, по адресу 0x00 размещается постоянный Device ID, который должен быть равен 0x48. В нашем случае так и есть. Это хороший признак. Значит, магнитометр как минимум отвечает осмысленные данные, а мы можем их читать.

Схема подключений датчика MPU-9250 к Arduino остаётся предельно простой:

Вывод датчика MPU-9250 Вывод Arduino
SCL A5
SDA A4
VCC +3.3V
GND GND

Для того чтобы использовать датчик MPU-9250 в режиме магнитометра, следует придерживаться такой последовательности действий:

  • настроить регистр управления питанием PWR_MGMT_1 по адресу 0x6B; Структура регистра PWR_MGMT_1 датчика MPU-9255 Структура регистра PWR_MGMT_1 датчика MPU-9255
  • настроить пользовательский регистр контроля USER_CTRL по адресу 0x6A чтобы отключить мастер шины I2C (не будем его использовать); Структура регистра USER_CTRL датчика MPU-9255 Структура регистра USER_CTRL датчика MPU-9255
  • настроить регистр конфигурации прерываний INT_PIN_CFG по адресу 0x37 чтобы включить магнитометр; Структура регистра INT_PIN_CFG датчика MPU-9255 Структура регистра INT_PIN_CFG датчика MPU-9255
  • настроить регистр управления магнитометра CNTL1 по адресу 0x0A на непрерывное проведение измерений. Структура регистра CNTL1 магнитометра AK8963 Структура регистра CNTL1 магнитометра AK8963

Реализуем это в следующем коде.

Скетч для чтения показаний датчика MPU-9255 (разворачивается)

Теперь остаётся перевести показания индукции магнитного поля в азимут. Для этого воспользуемся следующей формулой:

Будем двигаться к следующей задаче.

2 Подключение 7-сегментного светодиодногоиндикатора к Arduino

В качестве индикатора для вывода показаний компаса будем использовать семисегментный индикатор 3361AS-1. Он построен по принципу индикатора с общим катодом.

Светодиодный индикатор с общим катодом это тип индикатора, состоящий из нескольких светодиодов в одном корпусе, у которых общая земля, а питание на каждый светодиод подаётся отдельно.

Напомню, что 7-сегментным индикатор называется из-за того, что он состоит из 7-ми светодиодов, которые расположены в форме цифры "8". Зажигая определённые сегменты, можно изображать разные цифры. Это похоже на цифры индекса на почтовом конверте: закрашивая определённые участки, мы пишем разные индексы. Зачастую дополнительно к 7-ми сегментам, индикатор содержит десятичную точку. Также индикатор может иметь несколько цифр разрядов. Сегменты индикатора обозначаются латинскими буквами от A до G, как на рисунке.

Обозначение сегментов индикатора латинскими буквами Обозначение сегментов индикатора латинскими буквами

Воспользуемся популярным способом управления 7-сегментным индикатором с помощью драйвера CD4511. Это микросхема двоично-десятичного преобразователя, который переводит двоичный код числа в напряжение на соответствующих цифре сегментах индикатора. Такой преобразователь использует всего 4 ножки Arduino. Например, если необходимо отобразить на индикаторе десятичное число "7", следует выставить на входе преобразователя двоичное "0111". Микросхема CD4511 выполняется в разных типах корпусов. Назначение выводов в исполнении с 16-тью ножками, такое:

Выводы двоично-десятичного преобразователя CD4511

Отечественными аналогами данного преобразователя являются микросхемы серий ИД1ИД7.

При подключении двоичного декодера будем руководствоваться следующей таблицей:

Вывод CD4511 Назначение Примечание
A0. A3 Входы двоичного преобразователя Соответствуют разрядам двоичного числа.
a. g Выходы на сегменты индикатора Подключаются через токоограничительные резисторы к соответствующим сегментам светодиодного индикатора.
Lamp Test# Тест индикатора (включает все сегменты) Подключим к питанию, не использовать его.
Blanking# Очистка индикатора (отключает все сегменты) Подключим к питанию, чтобы не использовать его.
Latch Enabled# Выход активен Будет подключен к земле, чтобы выход был всегда активен.
VDD Питание микросхемы и индикатора От 3 до 15 В.
GND Земля Общая у CD4511, Arduino, 7-сегментного индикатора.

Индикатор 3361AS не имеет токоограничительных резисторов, поэтому необходимо озаботиться этим самому, подключая индикатор. При напряжении питания 5 В сопротивление на каждый сегмент должно быть около 200 Ом.

Желательно также подключить керамический конденсатор ёмкостью примерно 1 мкФ между землёй и питанием микросхемы CD4511.

Нам нужно одновременно управлять тремя разрядами десятичного числа, используя только один преобразователь CD4511. Но чисто физически это невозможно. Однако можно добиться иллюзии постоянного свечения всех разрядов светодиодного индикатора. Для этого придётся быстро переключаться между разрядами, постоянно обновляя показание каждого разряда. Мы будем поочерёдно активировать каждый из разрядов индикатора 3361AS, выставлять на нём с помощью двоичного преобразователя CD4511 нужную цифру, а затем переключаться на следующий разряд.

Для человеческого глаза такое переключение между разрядами будет незаметно, но если результат снять на видео, то можно увидеть, как мерцают разряды чисел при переключении между разрядами, и даже мерцание отдельных светодиодов.

Скетч для управления трёхразрядным 7-сегментным индикатором (разворачивается) Управление трёхразрядным семисегментным индикатором с помощью преобразователя CD4511 и Arduino Управление трёхразрядным семисегментным индикатором с помощью преобразователя CD4511 и Arduino

Итак, теперь мы умеем выводить трёхзначные числа на 7-сегментный индикатор, что нам понадобится для отображения азимута.

3 Подключение динамика / пьезоизлучателяк Arduino

Для оповещения об отклонении от азимута, как было решено, будем использовать звуковой пьезоизлучатель. Мы уже обсуждали в отдельной статье, как подключить пьезоизлучатель к Arduino. Поэтому останавливаться подробно здесь не будем. Напомню ключевые моменты.

Схема подключения излучателя к Arduino очень простая: объединяем земли, а в цепь питания ставим резистор сопротивлением около 100 Ом (для защиты порта Ardunio).

Схема подключения пьезоизлучателя к Arduino Схема подключения пьезоизлучателя к Arduino

Для Arduino есть специальные функции tone() и noTone(), которые используются для извлечения звука заданной частоты:

Здесь piezoPin номер вывода Arduino, к которой подключён звуковой извещатель. Давайте изменим в предыдущем скетче функцию loop() таким образом (изменения выделены жирным):

И конечно же, не забудем объявить в начале скетча piezoPin и задать ему режим работы OUTPUT. Теперь каждую минуту излучатель будет подавать звуковой сигнал продолжительностью 500 мс и частотой 1000 Гц.

4 Собираем всё вместе:компас на Arduino

Схема нашего устройства будет такой (нарисована в DipTrace Schematic):

Схема электронного компаса на MPU-9255 и Arduino Схема электронного компаса на MPU-9255 и Arduino

Здесь ARD1 это Arduino Nano, CD4511 драйвер управления 7-сегментным дисплеем 3361AS, MPU-9255 собственно, сам модуль с магнитным датчиком, SW1 кнопка для запуска и останова отслеживания азимута, BUZ звуковой извещатель, а PWR клемма для подачи внешнего питания от батареи Крона на устройство.

Монтаж компаса будем производить на печатной плате, которую разведём в программе DipTrace PCB Layout.

Печатная плата для электронного компаса на Arduino Печатная плата для электронного компаса на Arduino

Закажем печатную плату здесь. На этом предприятии делают всё быстро и качественно. Например, изготовление данной печатной платы заняло около суток от момента заказа до отправки. Единственный минус придётся долго ждать доставки из Китая (2-4 недели).

Печатная плата для электронного компаса на MPU-9255 и Arduino Печатная плата для электронного компаса на MPU-9255 и Arduino

Распаяем элементы на плате.

Пайка радиоэлементов на плате электронного компаса MPU-9250 Пайка радиоэлементов на плате электронного компаса MPU-9250

После распайки компонентов плата электронного компаса будет выглядеть так:

Печатная плата для электронного компаса с распаянными элементами Печатная плата для электронного компаса с распаянными элементами

Останется только придумать какой-то корпус для платы с компасом.

Сборка платы с датчиком MPU-9250 в корпус Сборка платы с датчиком MPU-9250 в корпус

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

Электронный компас в процессе отладки Электронный компас в процессе отладки

Во-вторых, изначальный скетч определения азимута выводит довольно приблизительные и нестабильные измерения. Поэтому в части работы компаса всё было переделано. Я взял за основу скетч, представленный в этой статье. Он отличается тем, что используются показания акселерометра для коррекции наклона датчика, а также вводятся дополнительные коррекции, связанные с индивидуальными особенностями датчика (в частности, чувствительность ASAX, ASAY, ASAZ). Для нормальной работы этого скетча необходимо сделать следующее.

  1. Определить магнитное наклонение географического места, в котором вы находитесь. Сделать это можно, например, на сайте magnetic-declination.com. Значение магнитного наклонения необходимо присвоить переменной Declination скетча.
  2. Скорректировать остаточный угол наклона акселерометра MPU-9255. Для этого следует положить датчик на ровную горизонтальную поверхность и добиться того, чтобы в выводе монитора последовательного порта значения accel_pitch и accel_roll были максимально близкими к нулю. Это достигается в несколько итераций, последовательными приближениями. Начните с нулевых значений.
  3. Ввести калибровочные коэффициенты. Для этого необходимо задать Record_data = true . Скомпилировать и загрузить в плату скетч. Медленно вращать компас во всех направлениях, пока в мониторе порта не появятся значения коэффициентов. Скопировать из монитора порта эти значения в соответствующие поля в скетче (они там обозначены). Вернуть Record_data = false , скомпилировать и загрузить скетч в Arduino с новыми коэффициентами.

Для всего описанного ниже переменная DEBUG в скетче должна быть true. Более подробные пояснения приводятся в самом скетче.

От того, насколько качественно вы сделаете предварительную работу, будет сильно зависеть работа и стабильность показаний компаса.

Скетч для магнитного компаса на датчике MPU-9250/MPU-9255 (разворачивается)

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

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


Источник: soltau.ru