В мире современных технологий сенсоры и датчики играют важную роль в создании устройств, способных воспринимать и анализировать окружающую среду. Одним из таких датчиков является компас-магнитометр GY-273, который позволяет измерять магнитное поле в трех измерительных осях. В данной статье мы рассмотрим, как подключить GY-273 к плате Arduino UNO и использовать его для получения ориентации в пространстве.
Модуль GY-273 – это 3-х осевой компас-магнитометр, основанный на чипсете HMC5883L.
- 3-х осевой измеритель магнитного поля: Он способен измерять магнитное поле в трех измерительных осях (X, Y, Z).
- Высокая точность измерений: GY-273 обеспечивает точные измерения магнитного поля с разрешением 1 мГаусс.
- Интерфейс I2C: Для подключения к микроконтроллеру используется стандартный интерфейс I2C, что делает его совместимым с большинством плат Arduino.
- Диапазон рабочих напряжений: Модуль может работать в диапазоне напряжений от 3.3V до 5V.
Arduino UNO – это одна из наиболее популярных платформ для прототипирования и разработки электронных устройств. Её характеристики включают:
- Микроконтроллер ATmega328P: Arduino UNO оснащена микроконтроллером ATmega328P, который обеспечивает достаточно вычислительных мощностей для управления различными устройствами и сенсорами.
- Цифровые и аналоговые входы/выходы: Плата предоставляет множество цифровых и аналоговых входов/выходов, что делает её универсальным инструментом для подключения различных датчиков и управления актуаторами.
- Интерфейсы связи: Arduino UNO поддерживает интерфейсы связи, такие как UART, I2C и SPI, что упрощает взаимодействие с другими устройствами.
- Простота программирования: Arduino IDE предоставляет удобную среду для написания и загрузки программ на плату.
Схема подключения
Для подключения модуля GY-273 к плате Arduino UNO, мы будем использовать интерфейс I2C. Вот схема подключения:
GY-273 | Arduino UNO |
---|---|
VCC | 5V |
GND | GND |
SDA | A4 (SDA) |
SCL | A5 (SCL) |
DRDY | Не подключен |
- Пин VCC подключается к выводу 5V на Arduino UNO.
- Пин GND подключается к земле (GND) Arduino UNO.
- Пин SDA (Serial Data) модуля GY-273 подключается к выводу A4 (SDA) на Arduino UNO.
- Пин SCL (Serial Clock) модуля GY-273 подключается к выводу A5 (SCL) на Arduino UNO.
- DRDY используется для прерываний. В данном примере мы оставляем его неподключенным.
Библиотеки
Для работы с модулем GY-273 на Arduino UNO, необходимо установить соответствующие библиотеки. В данном случае, мы будем использовать библиотеку “HMC5883L” для работы с чипсетом HMC5883L. Вы можете установить эту библиотеку следующим образом:
- Откройте Arduino IDE.
- Перейдите в меню “Скетч” (Sketch) -> “Подключить библиотеку” (Include Library) -> “Управление библиотеками” (Manage Libraries).
- В поисковой строке введите “HMC5883L” и установите библиотеку.
Пример кода
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
#include <Wire.h> #include <HMC5883L.h> // Создаем объект для работы с датчиком компаса HMC5883L compass; // Переменная для хранения ошибок, которые могут возникнуть при работе с компасом int error = 0; MagnetometerScaled valueOffset; // Переменная для хранения смещений void setup() { Serial.begin(115200); Wire.begin(); Serial.println("Инициализация HMC5883L"); Serial.println("Установка диапазона +/- 1.3 Гаусса"); error = compass.setScale(1.3); // Установка диапазона измерения компаса if (error != 0) { Serial.println(compass.getErrorText(error)); } Serial.println("Установка режима измерения в непрерывный."); error = compass.setMeasurementMode(MEASUREMENT_CONTINUOUS); // Установка режима измерения "непрерывный" if (error != 0) { Serial.println(compass.getErrorText(error)); } compassCalibrate(); // Запуск процедуры калибровки } // Процедура калибровки компаса void compassCalibrate(void) { Serial.println("Калибровка компаса"); MagnetometerScaled valueMax = { 0, 0, 0 }; MagnetometerScaled valueMin = { 0, 0, 0 }; Serial.println("Вращайте компас"); int xcount = 0; int ycount = 0; int zcount = 0; boolean xZero = false; boolean yZero = false; boolean zZero = false; MagnetometerScaled value; while (xcount < 3 || ycount < 3 || zcount < 3) { value = compass.readScaledAxis(); if ((fabs(value.XAxis) > 600) || (fabs(value.YAxis) > 600) || (fabs(value.ZAxis) > 600)) { continue; } if (valueMin.XAxis > value.XAxis) { valueMin.XAxis = value.XAxis; } else if (valueMax.XAxis < value.XAxis) { valueMax.XAxis = value.XAxis; } if (valueMin.YAxis > value.YAxis) { valueMin.YAxis = value.YAxis; } else if (valueMax.YAxis < value.YAxis) { valueMax.YAxis = value.YAxis; } if (valueMin.ZAxis > value.ZAxis) { valueMin.ZAxis = value.ZAxis; } else if (valueMax.ZAxis < value.ZAxis) { valueMax.ZAxis = value.ZAxis; } if (xZero) { if (fabs(value.XAxis) > 50) { xZero = false; xcount++; } } else { if (fabs(value.XAxis) < 40) { xZero = true; } } if (yZero) { if (fabs(value.YAxis) > 50) { yZero = false; ycount++; } } else { if (fabs(value.YAxis) < 40) { yZero = true; } } if (zZero) { if (fabs(value.ZAxis) > 50) { zZero = false; zcount++; } } else { if (fabs(value.ZAxis) < 40) { zZero = true; } } delay(30); } valueOffset.XAxis = (valueMax.XAxis + valueMin.XAxis) / 2; valueOffset.YAxis = (valueMax.YAxis + valueMin.YAxis) / 2; valueOffset.ZAxis = (valueMax.ZAxis + valueMin.ZAxis) / 2; Serial.print("Максимум: "); Serial.print(valueMax.XAxis); Serial.print(valueMax.YAxis); Serial.println(valueMax.ZAxis); Serial.print("Минимум: "); Serial.print(valueMin.XAxis); Serial.print(valueMin.YAxis); Serial.println(valueMin.ZAxis); Serial.print("Смещение: "); Serial.print(valueOffset.XAxis); Serial.print(valueOffset.YAxis); Serial.println(valueOffset.ZAxis); } void loop() { // Получение необработанных данных с компаса (нескалированных) MagnetometerRaw raw = compass.readRawAxis(); // Получение данных с компаса, откалиброванных и приведенных к установленному диапазону MagnetometerScaled scaled = compass.readScaledAxis(); scaled.XAxis -= valueOffset.XAxis; scaled.YAxis -= valueOffset.YAxis; scaled.ZAxis -= valueOffset.ZAxis; int MilliGauss_OnThe_XAxis = scaled.XAxis; // Расчет угла направления, когда компас находится в горизонтальном положении, затем коррекция для знаков осей float yxHeading = atan2(scaled.YAxis, scaled.XAxis); float zxHeading = atan2(scaled.ZAxis, scaled.XAxis); float heading = yxHeading; // После определения угла направления необходимо добавить "Угол деклинации", который представляет собой "ошибку" магнитного поля в вашем местоположении. // Вы можете найти угол деклинации на сайте: http://magnetic-declination.com/ // (+) для положительного угла и (-) для отрицательного. // Например, для местоположения в Москве, угол деклинации составляет +11°59'. // Формула для преобразования: (градусы + (минуты / 60.0)) / (180 / M_PI); float declinationAngle = (11 + (59.0 / 60.0)) / (180 / M_PI); heading += declinationAngle; if (heading < 0) { heading += 2 * PI; } if (heading > 2 * PI) { heading -= 2 * PI; } // Перевод из радиан в градусы float headingDegrees = heading * 180 / M_PI; float yxHeadingDegrees = yxHeading * 180 / M_PI; float zxHeadingDegrees = zxHeading * 180 / M_PI; // Вывод данных через последовательный порт Serial.print(scaled.XAxis); Serial.print(scaled.YAxis); Serial.println(scaled.ZAxis); Serial.print("arctan y/x: "); Serial.print(yxHeadingDegrees); Serial.print("arctan z/x: "); Serial.print(zxHeadingDegrees); delay(1000); } |
Калибровка датчика
Калибровка компаса важна для получения точных данных о магнитном поле. Для калибровки GY-273 компаса, вы можете выполнить следующие шаги:
- Разместите модуль GY-273 в месте, где нет металлических предметов и магнитных искажений.
- Запустите код, как описано выше, и получите начальное значение направления.
- Поворачивайте медленно модуль вокруг всех трех осей, чтобы получить максимальное покрытие всего диапазона магнитных полей.
- После завершения калибровки, полученные данные будут более точными.