Как подключить цифровой компас HMC5883L к Arduino
Рассмотрим подключение модуля GY-273 с трёхосевым цифровым компасом HMC5883L фирмы Honeywell. Эта микросхема может использоваться для магнитометрических измерений, в навигации, если не требуется большая точность измерений (с погрешностью 1…2° и возможностью калибровки). Устройство подключается по интерфейсу I2C.
Нам понадобится:
- Arduino UNO или иная совместимая плата;
- модуль GY-273 с цифровым датчиком магнитного поля HMC5883L;
- соединительные провода (рекомендую вот такой набор);
- макетная плата (breadboard);
- персональный компьютер со средой разработки Arduino IDE.
1Описание цифрового компаса HMC5883L и модуля GY-273
Цифровой компас HMC5883L – это миниатюрная микросхема, выполненная на одном кристалле, дешёвая и неприхотливая, она быстро заслужила признание у радиолюбителей. Часто её продают в составе готового модуля со всей необходимой обвязкой, например GY-273.
Вот основные технические характеристики магнитного датчика:
- 3-осевой магниточувствительный датчик;
- 12-разрядный АЦП с разрешением 2 мГс (миллигаусс);
- встроенная самопроверка;
- низкое рабочее напряжение и малое потребление;
- цифровой интерфейс I2C;
- высокая скорость опроса – до 160 раз в секунду (время одного измерения примерно 6 мс);
- точность определения направления 1…2°;
- может применяться в сильных магнитных полях (до ±8 Гаусс).
2Подключение цифрового компаса HMC5883L к Arduino
Схема подключения магнитного датчика HMC5883L к Arduino приведена на рисунке. Она очень компактная и простая: двухпроводной интерфейс IIC тем и хорош, что требует малого количества соединений.
Можно воспользоваться макетной платой. Должно получиться примерно так, как на фотографии. У меня тут ещё к шинам SCL и SDA подключён логический анализатор, чтобы контролировать информационный обмен.
3Скетч для Arduino, считывающий идентификационные регистры HMC5883L
Как же осуществляется обмен с магнитным датчиком HMC5883L? Откроем паспорт на датчик HMC5883L и узнаем, что адрес устройства 0x1E, а в наличии имеются следующие регистры:
Давайте в качестве первого знакомства попробуем прочитать идентификационный регистры 10 (0xA), 11 (0xB) и 12 (0xC) устройства.
#include <Wire.h> // подключим стандартную библиотеку I2C #define addr 0x1E // I2C адрес цифрового компаса HMC5883L void setup() { Serial.begin(9600); // инициализация последовательного порта Wire.begin(); // инициализация I2C } void loop() { Wire.beginTransmission(addr); // начинаем связь с устройством по адресу 0x1E Wire.write(0x0A); // регистр, с которого мы начнём запрашивать данные Wire.endTransmission(); Wire.requestFrom(addr, 3, true); // запрашиваем 3 байта у ведомого while( Wire.available() ) { char a = Wire.read(); // считываем байт из регистра 0xA; устройство само переходит к следующему регистру char b = Wire.read(); // считываем байт из регистра 0xB char c = Wire.read(); // считываем байт из регистра 0xС // Выводим считанное в последовательный порт: Serial.print("A = "); Serial.println(a, HEX); Serial.print("B = "); Serial.println(b, HEX); Serial.print("C = "); Serial.println(c, HEX); Serial.println(); } delay(100); }
Открыв монитор последовательного порта мы увидим:
A = 48 B = 34 C = 33
Сигнал, полученный с помощью логического анализатора, будет следующим:
Что это значит? Первый байт – I2C адрес, с которым мы (ведущее устройство, Arduino) устанавливаем связь (старшие 7 бит 0x1E), и режим записи (младший бит – 0x0); получается число 0x3C. Второй байт – число 0xA, которое мы записали по адресу 0x1E и бит подтверждения от датчика HMC5883L, которое является ведомым. Это номер регистра, с которого мы начнём считывать данные. На этом первая транзакция закончилась. Начинается следующая. Третий байт – это запрос чтения у ведомого (старшие 7 бит – адрес 0x1E, 8-ой бит – операция чтения 0x1; получается число 0x3D). Последние 3 три байта с значениями 0x48, 0x34 и 0x33 – это ответ ведомого устройства HMC5883L из регистров 0xA, 0xB и 0xC, соответственно.
Перемещение по регистрам цифрового компаса HMC5883L при непрерывном считывании осуществляется автоматически. Т.е. каждый раз указывать регистр не обязательно (но и не запрещено). Например, если мы вместо 0xA записали бы 0x3 и 10 раз считали, то получили бы значения в 10-ти регистрах, начиная с 3-го по 12-ый.
А что это за три числа – 0x48, 0x34, 0x33? Снова воспользовавшись паспортом на цифровой компас HMC5883L, мы увидим, что это значения по умолчанию для трёх идентификационных регистров:
4Скетч для Arduino, считывающий показания цифрового компаса HMC5883L
А теперь давайте рассмотрим типичную измерительную задачу: снимем показания магнитной индукции по трём осям. Этот пример описан в паспорте на устройство. Мы лишь переведём его на язык, понятный Arduino. Итак, скетч.
#include <Wire.h> // подключаем I2C библиотеку #define addr 0x1E // I2C 7-битный адрес датчика HMC5883 void setup() { Serial.begin(9600); // инициализация последовательного порта Wire.begin(); // инициализация I2C // Задаём режим работы датчика HMC5883: Wire.beginTransmission(addr); Wire.write(0x00); // выбираем регистр управления CRA (00) Wire.write(0x70); // записываем в него 0x70 [усреднение по 8 точкам, 15 Гц, нормальные измерения] Wire.write(0xA0); // записываем в регистр CRB (01) 0xA0 [чувствительность = 5] Wire.write(0x00); // записываем в регистр Mode (02) 0x00 [бесконечный режим измерения] Wire.endTransmission(); } void loop() { Wire.beginTransmission(addr); Wire.write(0x03); // переходим к регистру 0x03 Wire.endTransmission(); Wire.requestFrom(addr, 6); // запрашиваем 6 байтов while( Wire.available() ) { int h = Wire.read(); // старший байт значения по оси X int l = Wire.read(); // младший байт значения по оси X int x = word(h, l); // объединяем в двухбайтовое число int y = Wire.read(); // старший байт значения по оси Y y = y << 8; // сдвигаем влево на 8 битов y = y | Wire.read(); // объединяем с младшим байтом по OR int z = Wire.read() << 8; // читаем байт и сдвигаем влево на 8 битов z |= Wire.read(); // сокращённый синтаксис операции OR Serial.print("X = "); Serial.println(x, DEC); Serial.print("Y = "); Serial.println(y, DEC); Serial.print("Z = "); Serial.println(z, DEC); Serial.println(); } delay(100); }
Здесь показаны разные варианты получения двухбайтового числа из двух отдельных байтов. Вот как мы это сделали: по отдельности считали старший байт и младший байт, а затем воспользовались оператором word, который объединил два байта в двухбайтовое число («слово»). Можно поступить так: считать старший байт, сдвинуть его на 8 разрядов влево, считать младший байт, а затем объединить их по OR (ИЛИ). В последнем случае приводится просто более короткий синтаксис предыдущего варианта. Выбирайте тот, который вам более удобен и понятен.
Рассмотрим временную диаграмму информационного обмена:
Первые 5 байтов до небольшой паузы – это то, что мы описали в секции void setup():
- выбор адреса ведомого устройства и режима записи;
- выбор первого регистра управления Control Register A (CRA) с адресом 0x00 (согласно вышеприведённой таблице);
- запись в первый регистр управления CRA числа 0x70 – усреднение по 8 точкам, 15 Гц, нормальные измерения (подробности см. в паспорте); HMC5883L переводит указатель к следующему регистру – Control Register B (CRB);
- запись в регистр CRB числа 0xA0, что соответствует установке чувствительности 5; HMC5883L переводит указатель к следующему регистру – Mode Register, регистр выбора режима;
- записываем в регистр режима число 0x00 – бесконечный режим измерения.
- первый байт из 7-ми – выбор адреса ведомого устройства и режима чтения;
- следующие два – чтение двух байтов показаний с канала оси X;
- следующие два – оси Y;
- следующие два – оси Z.
Далее идёт небольшая пауза примерно в 20 мкс, и передаются ещё два байта – это выбор адреса ведомого в режиме записи и запись адреса регистра – 0x03 – с которого мы будем начинать каждый цикл считывания данных, определённый нами в void loop(). Это первый регистр данных, как видно из таблицы выше.
Последние 7 байтов означают следующее:
В итоге, в мониторе порта мы видим показания магнитного датчика по трём осям:
Если поворачивать датчик в пространстве, видно, как меняются показания.
Думаю, что калибровка и настройка цифрового компаса – тема для отдельной статьи.
Поблагодарить автора:
Поделиться
Похожие материалы (по тегу)
4 комментарии
-
Сергей 20.01.2019 17:00 Комментировать
Отлично, познавательно написано.
Но есть уточнение: в программе перепутаны оси Z и Y. В даташите написано что за X идет регистр Z, и последний Y. -
игорь 01.03.2019 12:37 Комментировать
радиокружок ищет помощь в написании программы для автопилота(катера) на базе HMC5883L .