компас на ардуино с компенсацией наклона
Цифровой компас на основе Arduino и магнитометра HMC5883L
Мозг помогает человеку достаточно хорошо ориентироваться в окружающем пространстве. К сожалению, у роботов человеческого мозга нет, поэтому им нужно каким-либо другим образом «чувствовать» свое направление движения чтобы они могли автономно передвигаться по новой для них местности. Для преодоления этой проблемы роботы используют множество разнообразных датчиков, однако чаще всего для этой цели используется магнитометр, который может информировать робота в каком направлении он передвигается (или развернут лицом). Это помогает роботу не только чувствовать направление движения, но и давать ему команды для поворота на заранее определенный угол или в определенном направлении.
В этой статье мы рассмотрим как работает магнитометр и как его подключить к плате Arduino. На основе магнитометра и платы Arduino мы спроектируем цифровой компас, на котором горящий светодиод будет указывать направление на север. Схему компаса мы распаяли на печатной плате, изготовленной в компании PCBGOGO.
Необходимые компоненты
Что такое магнитометр и как он работает
Надеемся, что слово магнитометр не ассоциируется у вас с мутантом по имени «Магнето» из популярной киноэпопеи «Люди Х» – но он там был реально крут, не правда ли? ))
На самом деле магнитометр представляет собой устройство, которое может ощущать («чувствовать») магнитные полюса Земли и указывать направление к ним. Все мы знаем что Земля представляет собой огромный сферический магнит с северным и южным полюсами. Естественно, этот огромный магнит создает магнитное поле. Магнитометр улавливает (ощущает) это магнитное поле и на основании направления этого магнитного поля он может определять направление (в котором мы смотрим или развернуты лицом).
Как работает датчик (магнитометр) HMC5883L
Датчик (магнитометр) HMC5883L содержит в своем составе микросхему HMC5883L от компании Honeywell. Эта микросхема содержит внутри себя 3 магниторезистивных материала, которые упорядочены (ориентированы) по осям x, y и z. Количество тока, протекающего через эти материалы, чувствительно к магнитному полю Земли. То есть, измеряя изменения в токе, протекающем через эти материалы, мы можем обнаруживать изменения в магнитном поле Земли. В дальнейшем эти изменения можно передать любому микроконтроллеру (например, плате Arduino) по протоколу I2C.
Поскольку показания данного датчика основаны на величине магнитного поля, то на них в значительной степени будут влиять расположенные рядом металлические предметы. Поэтому иногда данные датчики используются в детекторах металла. Но если вы будете использовать магнитометр в составе компаса следите чтобы рядом с ним не было крупных металлических предметов, иначе показания компаса будут неправильными – надеюсь, все помнят фильм про пятнадцатилетнего капитана и как его обманули с показаниями компаса.
Разница между HMC5883L и QMC5883L
Некоторые поставщики радиодеталей продают датчики QMC5883L (они изготавливаются той же самой компанией Honeywell) вместо HMC5883L поскольку QMC5883L стоят дешевле. Печальная новость здесь состоит в том, что работа этих двух датчиков немного отличается и один и тот же программный код не будет работать с обоими этими датчиками. Поэтому и адрес в протоколе I2C у них будет различный. Код программы, приведенный в нашей статье, будет работать только с QMC5883L – он более дешевый и его проще достать.
Чтобы узнать какая модель датчика у вас, HMC5883L или QMC5883L, посмотрите поближе что на нем написано. Если на нем написано что то вроде L883, то это HMC58836L, а если написано что то вроде DA5883, то это QMC5883L. Внешний вид обоих этих модулей показан на следующем рисунке.
Работа схемы
Схема цифрового компаса на основе платы Arduino и магнитометра HMC5883L представлена на следующем рисунке.
Как видите, схема достаточно проста. Нам просто необходимо подключить датчик HMC5883L к плате Arduino и соединить 8 светодиодов с контактами платы Arduino Pro mini.
Магнитометр HMC5883L имеет 5 контактов. Его контакт DRDY (Data Ready) мы не будем использовать поскольку в нашем проекте датчик будет работать в непрерывном режиме. Контакты Vcc и ground (земля) датчика используются для питания модуля от платы Arduino. Контакты SCL и SDA используются для связи по протоколу I2C и подключены к контактам A4 и A5 (которые также являются контактами для связи по протоколу I2C) платы Arduino Pro mini. Поскольку контакты датчика имеют внутренние подтягивающие резисторы, то нет необходимости добавлять в схему внешние подтягивающие резисторы.
Для индикации направления в проекте мы используем 8 светодиодов, подключенных к контактам платы Arduino с помощью ограничивающих ток резисторов сопротивлением 470 Ом. Схема запитывается от батарейки 9V через переходник типа barrel Jack – на фотографиях хорошо видно что он из себя представляет. Эти 9V попадают на контакт Vin платы Arduino, затем с помощью встроенного регулятора платы Arduino это напряжение понижается до 5V, которое и используется для питания нашей схемы.
Изготовление печатной платы для цифрового компаса
Когда дизайн печатной платы готов можно приступать к ее изготовлению. Для этого необходимо выполнить следующую последовательность шагов.
Шаг 1. Перейдите по адресу https://www.pcbgogo.com/?code=t, зарегистрируйтесь там если это ваше первое посещение. Затем на вкладке PCB Prototype введите размеры вашей печатной платы, число ее слоев и какое количество печатных плат вам необходимо. Мы использовали размер печатной платы 80mm×80mm.
Шаг 3. Загрузите в сервис свои Gerber файлы и оплатите заказ. После загрузки сервис PCBGOGO проверяет ваши Gerber файлы на корректность.
Разумеется, мы не настаиваем, чтобы вы заказывали печатную плату именно в PCBGOGO, вы можете заказать ее у любого производителя печатных плат, с которым вы привыкли работать.
Сборка печатной платы
Нам платы пришли в отличном состоянии, их внешний вид вы можете посмотреть на следующих рисунках.
Нам понадобилось около 10 минут чтобы припаять к плате необходимые компоненты, после этого мы получили следующий вид нашей платы:
Объяснение программы для Arduino
Основная цель работы программы – считать данные с магнитометра QMC5883L и преобразовать их в градусы (от 0 до 360). А когда мы будем знать градусы мы легко сможем определить светодиод, который нужно зажечь чтобы указать нужное направление. Мы в нашем проекте будем указывать направление на север – вы можете изменить это по своему желанию, внеся изменения в код программы. То есть горящий светодиод у нас будет указывать направление на север.
Полный код программы приведен в конце статьи, здесь же мы рассмотрим его основные фрагменты.
После добавления библиотеки мы можем приступать к написанию программы. Первым делом нам в программе необходимо подключить используемые библиотеки – библиотека wire используется для осуществления связи по протоколу I2C, а MechaQMC5883 – для работы с магнитометром (ее мы только что добавили в Arduino IDE).
Микросхема HMC5883L представляет собой 3-х осевой цифровой компас, работающий по шине I 2 C. В качестве сенсоров используется три магниторезистивных датчика. Разработчик: компания Honeywell. Даташит PDF. Напряжение питания составляет 2.2-3.6В. Чувствительность датчика составляет 5 миллигаусс.
Датчик может использоваться в мобильных телефонах, планшетах, навигационном оборудовании и прочей потребительской электронике, но для радиолюбителей он может быть интересен тем, что цифровой компас может очень пригодится при конструировании роботов и радиоуправляемых моделей. В данном уроке мы рассмотрим подключение HMC5883L к Arduino. Т.к. датчик работает по шине I 2 C, то схема подключения предельно проста:
Т.к. сам чип компаса очень маленький 3×3 мм (16-ти выводной LPCC корпус), то некоторые фирмы выпускают платы с удобными выводами для подключения и распаянными подтягивающими резисторами. Именно такую плату мы и будем использовать в качестве примера.
Вывод SDA чипа подключаем к выводу SDA платы Arduino (обычно Analog IN 4), а вывод SCL чипа соответственно к выводу SCL платы Arduino (обычно Analog IN 5). На Arduino Mega это 20 и 21 пины. И не забываем питание 3.3В и общий GND.
На сайте bildr существует готовая библиотека для работы с датчиком. Ею мы и воспользуемся (немного подправив ошибку при проверке диапазона scale). Папку HMC5883L поместите в ваш каталог Libraries. Код работы с датчиком:
Чувствительность датчика задается функцией SetScale() и может быть выбрана только из следующих значений: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1. Более подробно читайте даташит.
После загрузки скетча в контроллер Arduino и запуске утилиты мониторинга порта, вы должны увидеть поступающие данные с датчика:
Компас на ардуино с компенсацией наклона
Поэтому было принято решение сделать чисто электронный вариант на более подходящем магнитометре без подвижных элементов конструкции. Конечно, можно было бы купить готовый модуль компенсированного компаса типа CMPS10 или GY-953, но мне интереснее сделать самому. Магнитометр HMC5883L при испытаниях на прорисовку окружности показал себя практически идеально. Оставленный на сутки в работе вектор на экране не сместился ни на один пиксел. Прогрев промышленным феном до 70. 80 градусов Цельсия тоже показал отличный результат, смещение оказалось едва заметным.
Люди, которые делали компас по данному скетчу, заметили, что компенсация работает не по всем сторонам равномерно. Я это тоже заметил. Дело в том, что Korneliusz Jarzebski калибрует магнитометр только по осям X и Y, в то время как компенсационная формула содержит кроме магнитных компонет X,Y ещё и компоненту Z. Эта компонента так же имеет случайное смещение от нуля, и чем больше смещение тем больше врёт компас.
Поэтому кроме калибровки по X,Y я ввел калибровку по компоненте Z.
Калибровка компаса в моей программе :
Демонстрация работы компаса.
Формат данных на выходе UART компаса.
Про магнитное склонение.
На LCD экран самого компаса выводится азимут с учетом магнитного склонения Санкт-Петербурга. На UART поступают данные без учета магнитного склонения (в автопилоте происходит коррекция).
Монтажная схема компаса в формате pdf c разметочной сеткой и без неё.
Как сделать электронный компас на датчике MPU-9250 и Arduino
Разобьём всю задачу на более мелкие подзадачи. Так сказать, проведём декомпозицию. И по шагам опишем весь процесс создания электронного компаса. Для проекта нам понадобятся:
1 Подключение датчика MPU-9250к Arduino
Датчик MPU-9250 – это по сути несколько датчиков, расположенных на одном чипе. Так, он реализует функции 3-осевого гироскопа, 3-осевого акселерометра и 3-осевого магнитометра. В данном проекте мы будем использовать только магнитометр. Остальные датчики можно отключить в целях уменьшения потребляемого тока, т.к. будем делать портативное устройство, питающееся от батареи «Крона».
Внешний вид модуля с датчиком 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
Теперь, когда всё подключено, запускаем в режиме I2C программу SPI via FTDI, многократно описанную нами ранее. Оставляем настройки по умолчанию и сканируем шину I2C. Мы увидим, что программа обнаружила на шине одно устройство по адресу 0x68. Если прочитать из него 127 байтов (именно столько регистров имеет датчик MPU9250, техническое описание можно скачать в приложении к статье), то увидим следующее:
Чтение всех регистров датчика MPU-9250 по I2C с помощью FT2232
Здесь нет показаний магнитометра. Магнитометр (он называется AK8963) – это отдельное устройство на кристалле, которое не активно при подаче питания на датчик MPU-9250. Его нужно активировать явно. Для этого необходимо в регистр под номером 0x37 (INT_PIN_CFG) записать значение 0x02. Для этого в программе в поле записи укажем команду «37 02», как на рисунке, и нажмём кнопку «Записать». Полное описание регистра приводится далее.
Включение магнитометра датчика MPU-9250 через регистр I2C_SLV0_ADDR
Карта регистров магнитометра AK8963 представляет собой довольно короткую таблицу, состоящую всего из 13-ти байтов:
Карта регистров магнитометра MPU-9250
Чтение регистров магнитометра MPU-9250 по I2C
Как видно, по адресу 0x00 размещается постоянный Device ID, который должен быть равен 0x48. В нашем случае так и есть. Это хороший признак. Значит, магнитометр как минимум отвечает осмысленные данные, а мы можем их читать.
Схема подключений датчика MPU-9250 к Arduino остаётся предельно простой:
Вывод датчика MPU-9250 | Вывод Arduino |
---|---|
SCL | A5 |
SDA | A4 |
VCC | +3.3V |
GND | GND |
Для того чтобы использовать датчик MPU-9250 в режиме магнитометра, следует придерживаться такой последовательности действий:
Реализуем это в следующем коде.
Скетч для чтения показаний датчика 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
Итак, теперь мы умеем выводить трёхзначные числа на 7-сегментный индикатор, что нам понадобится для отображения азимута.
3 Подключение динамика / пьезоизлучателяк Arduino
Для оповещения об отклонении от азимута, как было решено, будем использовать звуковой пьезоизлучатель. Мы уже обсуждали в отдельной статье, как подключить пьезоизлучатель к Arduino. Поэтому останавливаться подробно здесь не будем. Напомню ключевые моменты.
Схема подключения излучателя к Arduino очень простая: объединяем земли, а в цепь питания ставим резистор сопротивлением около 100 Ом (для защиты порта Ardunio).
Схема подключения пьезоизлучателя к Arduino
Для Arduino есть специальные функции tone() и noTone(), которые используются для извлечения звука заданной частоты:
Здесь piezoPin – номер вывода Arduino, к которой подключён звуковой извещатель. Давайте изменим в предыдущем скетче функцию loop() таким образом (изменения выделены жирным):
И конечно же, не забудем объявить в начале скетча piezoPin и задать ему режим работы OUTPUT. Теперь каждую минуту излучатель будет подавать звуковой сигнал продолжительностью 500 мс и частотой 1000 Гц.
4 Собираем всё вместе:компас на Arduino
Схема нашего устройства будет такой (нарисована в DipTrace Schematic):
Схема электронного компаса на MPU-9255 и Arduino
Здесь ARD1 – это Arduino Nano, CD4511 – драйвер управления 7-сегментным дисплеем 3361AS, MPU-9255 – собственно, сам модуль с магнитным датчиком, SW1 – кнопка для запуска и останова отслеживания азимута, BUZ – звуковой извещатель, а PWR – клемма для подачи внешнего питания от батареи «Крона» на устройство.
Монтаж компаса будем производить на печатной плате, которую «разведём» в программе DipTrace PCB Layout.
Печатная плата для электронного компаса на Arduino
Закажем печатную плату здесь. На этом предприятии делают всё быстро и качественно. Например, изготовление данной печатной платы заняло около суток от момента заказа до отправки. Единственный минус – придётся долго ждать доставки из Китая (2-4 недели).
Печатная плата для электронного компаса на MPU-9255 и Arduino
Распаяем элементы на плате.
Пайка радиоэлементов на плате электронного компаса MPU-9250
После распайки компонентов плата электронного компаса будет выглядеть так:
Печатная плата для электронного компаса с распаянными элементами
Останется только придумать какой-то корпус для платы с компасом.
Сборка платы с датчиком MPU-9250 в корпус
В процессе экспериментов выяснились несколько деталей, которые потребовали доработки. Во-первых, динамик вносит искажения в показания компаса. Величина искажения зависит от типа динамика и его близости к датчику. Поэтому его желательно отнести подальше от датчика, а не размещать непосредственно на плате.
Электронный компас в процессе отладки
Во-вторых, изначальный скетч определения азимута выводит довольно приблизительные и нестабильные измерения. Поэтому в части работы компаса всё было переделано. Я взял за основу скетч, представленный в этой статье. Он отличается тем, что используются показания акселерометра для коррекции наклона датчика, а также вводятся дополнительные коррекции, связанные с индивидуальными особенностями датчика (в частности, чувствительность ASAX, ASAY, ASAZ). Для нормальной работы этого скетча необходимо сделать следующее.
Для всего описанного ниже переменная DEBUG в скетче должна быть true. Более подробные пояснения приводятся в самом скетче.
От того, насколько качественно вы сделаете предварительную работу, будет сильно зависеть работа и стабильность показаний компаса.
Скетч для магнитного компаса на датчике MPU-9250/MPU-9255 (разворачивается)