Статьи » Разработки
Добавить статью

Светодиодный компас на Arduino

2021-01-21 в 21:50 (последнее изменение 2023-11-09 в 11:16)

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

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

Необходимые материалы

Что такое магнитометр и как он работает?
Прежде чем мы углубимся в схему, давайте немного разберемся с магнитометрами и их работой. Магнитометр на самом деле представляет собой часть оборудования, которое может определять магнитные полюса Земли и определять направление в соответствии с ними. Все мы знаем, что Земля - ​​это огромный кусок сферического магнита с Северным и Южным полюсами. И из-за этого возникает магнитное поле. Магнитометр определяет это магнитное поле и на основании этого определяет направление, в котором мы смотрим.

Как работает модуль датчика QMC5883L
Датчик магнитометра QMC5883L делает то же самое. На нем установлена ​​микросхема HMC5883L от Honeywell. Эта микросхема имеет внутри 3 магниторезистивных материала, расположенных по осям x, y и z. Величина тока, протекающего через эти материалы, чувствительна к магнитному полю Земли. Итак, измеряя изменение тока, протекающего через эти материалы, мы можем обнаружить изменение магнитного поля Земли. Как только изменение магнитного поля будет определено, значения могут быть отправлены на любой встроенный контроллер, такой как микроконтроллер или процессор, по протоколу I2C.

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

Разница между HMC5883L и QMC5883L
Между датчиками HMC5883L и QMC5883L часто возникает путаница. Это связано с тем, что некоторые поставщики (на самом деле большинство) продают датчики QMC5883L вместо оригинального HMC5883L от Honeywell. В основном это связано с тем, что QMC5883L намного дешевле модуля HMC5883L. Однако работа этих двух датчиков несколько отличается, и один и тот же код нельзя использовать для обоих. Это связано с тем, что адреса I2C обоих датчиков не совпадают. Код, приведенный в этом руководстве, будет работать только с QMC5883L.

Чтобы узнать, какая у вас модель датчика, вам просто нужно внимательно посмотреть на саму микросхему и прочитать, что на ней написано. Если написано что-то вроде L883, то это HMC58836L, а если написано что-то вроде DA5883, то это IC QMC5883L. Оба модуля показаны на рисунке ниже.

Схема цифрового компаса
Схема цифрового компаса на основе Arduino довольно проста, нужно просто связать датчик QMC5883 с Arduino и подключить 8 светодиодов к контактам GPIO Arduino Pro mini.

Модуль датчика имеет 5 контактов, из которых DRDY (Data Ready) не используется в нашем проекте, поскольку мы работаем с датчиком в постоянном режиме. Вывод Vcc и заземления используется для питания модуля напряжением 5 В от платы Arduino. SCL и SDA - это линии шины связи I2C, которые подключены к контактам A4 и A5 I2C Arduino Pro mini соответственно. Поскольку в самом модуле есть резистор с высоким сопротивлением на линиях, нет необходимости добавлять их извне.
Чтобы указать направление, мы использовали 8 светодиодов, все из которых подключены к контактам GPIO Arduino через токоограничивающий резистор на 470 Ом. Схема питается от кроны 9В через цилиндрический разъем. 9 В подаются непосредственно на вывод Vin Arduino, где регулируется до 5 В с помощью встроенного регулятора Arduino. Эти 5 В затем используются для питания датчика и Arduino.

Изготовление печатных плат для цифрового компаса
Идея схемы состоит в том, чтобы разместить 8 светодиодов по кругу так, чтобы каждый светодиод указывал на все 8 направлений, а именно на север, северо-восток, восток, юго-восток, юг, юго-запад, запад и северо-запад соответственно. Не так то и легко разместить их аккуратно на макете или на перфорированной плате. Поэтому разработка печатной платы сделает ее более аккуратной и простой в использовании. Для этого можно использовать программу для проектирования печатных плат Dip Trace, расположить светодиоды и резистор аккуратным по окружности и соединить дорожки, чтобы сформировать соединения. После завершения, дизайн выглядит примерно так, как показано ниже. Вы можете скачать файл Gerber по приведенной ниже ссылке.

dip trace

Скачать файл Gerber для печатной платы цифрового компаса

Она разработана в виде двухсторонней платы. Arduino размещается на нижней стороне печатной платы.

Зайдите на сайт https://www.pcbway.ru/, зарегистрируйтесь, если вы впервые. Затем на вкладке "Моментальный расчет стоимости платы" введите размеры вашей печатной платы, количество слоев и количество требуемых печатных плат. Размер моей печатной платы 8 см × 8 см, поэтому вкладка выглядит так, как показано ниже.

В большинстве случаев значений по умолчанию будет достаточно. Единственное, что я обычно меняю, это толщина платы. Ставлю 1,2 мм. Так мне кажется лучше выглядит. Еще маску делаю синего цвета. Но тут уже как нравится.
Как видите, время сборки составляет всего 2-3 дня, а для нашей платы это всего лишь 5 долларов. Затем вы выбираете предпочтительный способ доставки в зависимости от ваших требований.

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

Сборка печатной платы
После того, как плата была заказана, она пришла в течение короткого времени, маркированная, в хорошо упакованной коробке. Качество печатной платы как всегда было потрясающим.

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

Ниже представлены некоторые фотографии платы после пайки.

Программирование Arduino
Теперь, когда наше устройство готово, давайте посмотрим на программу, которую нужно загрузить в нашу плату Arduino. Цель кода - считывать данные с датчика магнитометра QMC5883L и преобразовывать их в градусы (от 0 до 360). Как только мы узнаем градус, мы должны включить светодиод, указывающий определенное направление. Направление, которое я использовал в этой программе, - север. Таким образом, независимо от того, где вы находитесь, на вашей плате будет гореть только один светодиод, а направление светодиода будет указывать на СЕВЕР. 

Полный код проекта «Цифровой компас» можно найти в конце статьи. Вы можете напрямую загрузить его на свою плату после включения библиотеки, и она готова к работе. Но если вы хотите узнать подробнее о самом коде, читайте дальше.

Мы используем микросхему QMC5883, для связи с ней нам необходимо знать адрес I2C ее регистров, который можно найти в таблице данных. Но, к счастью для нас, все это уже сделано и упаковано в виде библиотеки парнем по имени keepworking на Github. Поэтому все, что вам нужно сделать, это просто загрузить библиотеку для QMC5883, щелкнув ссылку, чтобы получить ZIP-файл. Затем этот ZIP-файл можно добавить в вашу Arduino IDE, выполнив Sketch -> Include Library -> Add .ZIP library.
После добавления библиотеки мы можем продолжить нашу программу. Начинаем с включения необходимых файлов библиотеки, как показано ниже. Библиотека "wire.h" используется для включения связи I2C, а MechaHMC5883L - это та, которую мы только что добавили в Arduino. Эта библиотека содержит всю информацию о том, как работать с датчиком QMC5883L.

Библиотека MechaQMC5883 - скачать

Код
#include <Wire.h> //Wire Librarey for I2C communication
#include <MechaQMC5883.h> //QMC5883 Librarey is added since mine is QMC5883 and not HMC5883

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

Код
MechaQMC5883 qmc; //Create an object name for the sensor, I have named it as qmc

Далее переходим к объявлениям глобальных переменных. Здесь, поскольку у нас есть 8 светодиодов в качестве выходов, трудно ссылаться на каждый через имя контакта, поэтому мы используем параметр массива для ссылки на все светодиоды. Имя массива - ledPins, а переменная led_count - это количество светодиодов, которые у нас есть. Начинается с 0.

Код
int ledPins[] = {2,3,4,5,6,7,8,9}; //Array of output pin to which the LED is connected to
char led_count = 7; //Total number of LED pins

Внутри функции настройки void мы также инициализируем связь I2C, последовательную связь и датчик. Затем мы объявляем все выводы светодиодов как выходные выводы. Поскольку мы использовали массив, легко ссылаться на все контакты, используя цикл for и перемещаясь по циклу for, как показано ниже.

Код
void setup() {
  Wire.begin(); //Begin I2C communication
  Serial.begin(9600); //Begin Serial Communication
  qmc.init(); //Initialise the QMC5883 Sensor</p>  <p>  for (int thisPin=0; thisPin <= led_count; thisPin++){ //Navigate through all the pins in array
    pinMode(ledPins[thisPin],OUTPUT); //Declare them as output
  }
}

В цикле main, мы должны получить значения x, y и z от датчика и вычислить градус, на которой датчик указывает в данный момент. Чтобы прочитать значения x, y и z, используйте следующую строку

Код
int x,y,z;
qmc.read(&x,&y,&z); //Get the values of X,Y and Z from sensor

Формулы для расчета курса в градусах показаны ниже. Поскольку мы не собираемся вращать компас по оси z, можно не принимать это значение во внимание. Эта формула может использоваться только в том случае, если плоская поверхность ИС обращена вверх, как в нашей установке. После расчета курса значение будет в диапазоне от -180 до 180, которое мы должны преобразовать в 0 - 360, как и во всех цифровых компасах.

Код
int heading=atan2(x, y)/0.0174532925; //Calculate the degree using X and Y parameters with this formulae
 //Convert result into 0 to 360
  if(heading < 0)
  heading+=360;
  heading = 360-heading;

Последний шаг - зажечь светодиод, указывающий в СЕВЕРНОМ направлении. Для этого у нас есть серия операторов if, в которых мы проверяем, в каком диапазоне сейчас находится градус, и в соответствии с этим включаем светодиод. Код показан ниже

Код
//Based on the value of heading print the result for debugging and glow the respective LED.
  if (heading > 338 || heading < 22)
  {
    Serial.println("NORTH");
    digitalWrite(ledPins[0],HIGH);
  }
 
Код
  if (heading > 22 && heading < 68)
  {
    Serial.println("NORTH-EAST");
    digitalWrite(ledPins[7],HIGH);
  }
    if (heading > 68 && heading < 113)
  {
    Serial.println("EAST");
    digitalWrite(ledPins[6],HIGH);
  }
     if (heading > 113 && heading < 158)
  {
    Serial.println("SOUTH-EAST");
    digitalWrite(ledPins[5],HIGH);
  }
  if (heading > 158 && heading < 203)
  {
    Serial.println("SOUTH");
    digitalWrite(ledPins[4],HIGH);
  }
  if (heading > 203 && heading < 248)
  {
    Serial.println("SOTUH-WEST");
    digitalWrite(ledPins[3],HIGH);
  }
  if (heading > 248 && heading < 293)
  {
    Serial.println("WEST");
    digitalWrite(ledPins[2],HIGH);
  }
  if (heading > 293 && heading < 338)
  {
    Serial.println("NORTH-WEST");
    digitalWrite(ledPins[1],HIGH);
  }

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

Направление Градус, соответствующий направлению Диапазон для этого направления
СЕВЕР 0 ° / 360 ° > 338 ° или <22 °
СЕВЕРО-ВОСТОК 45 ° От 22 ° до 68 °
ВОСТОК 90 ° От 68 ° до 113 °
ЮГО-ВОСТОК 135 ° 113 ° до 158 °
ЮГ 180 ° От 158 ° до 203 °
ЮГО-ЗАПАД 225 ° От 203 ° до 248 °
ЗАПАД 170 ° 248 ° до 293 °
СЕВЕРО-ЗАПАД 315 ° От 293 ° до 338 °

Последняя часть программы - установить, как быстро должен обновляться результат. Мы сделали задержку на 500 миллисекунд, а затем заставили все светодиоды выключиться, чтобы снова начать работу с первого внутри пустого цикла. Но если вам нужны более быстрые обновления, вы можете уменьшить задержку.

Код
 delay(500); // update position of LED for every alf seconds
//Turn off the all the LED
    for (int thisPin=0; thisPin <= led_count; thisPin++){
     digitalWrite(ledPins[thisPin],LOW);
  }

Тестирование цифрового компаса
Поскольку мы использовали Arduino pro mini, нам нужен внешний программатор, такой как FTDI, для загрузки программы. После загрузки программы вы должны увидеть, что на плате светится один светодиод, он то и указывает на север.

Можно поворочать плату и проверить, указывает ли по-прежнему светодиод на север. После этого вы можете в любое время использовать батарею 9 В для питания кмопаса и проверки направления, в котором смотрите. 

Надеемся, вам понравилось это руководство и вы узнали из него что-то полезное.

А еще у меня остались несколько штук таких плат. Кому нужны, обращайтесь.

Код
/*
 * Program for Arduino Digital Compass using QMC5883
 * Project by: Aswinth Raj
 * Dated: 1-11-2018
 * Lib. from https://github.com/keepworking/Mecha_QMC5883L
 * WARNING: This code works only for QMC5883 Sensor which is commonly being sold as HMC5883 read article to find the actual name of the sensor you have.
 */
#include <Wire.h> //Wire Librarey for I2C communication 
#include <MechaQMC5883.h> //QMC5883 Librarey is added since mine is QMC583 and not HMC5883
MechaQMC5883 qmc; //Create an object name for the snsor, I have named it as qmc
int ledPins[] = {2,3,4,5,6,7,8,9}; //Array of output pin to which the LED is connected to
char led_count = 7; //Total number of LED pins
void setup() {
  Wire.begin(); //Begin I2C communication 
  Serial.begin(9600); //Begin Serial Communication 
  qmc.init(); //Initialise the QMC5883 Sensor 
  for (int thisPin=0; thisPin <= led_count; thisPin++){ //Navigate through all the pins in array 
    pinMode(ledPins[thisPin],OUTPUT); //Declare them as output 
  }
}
void loop() { //Infinite Loop
  int x,y,z;
  qmc.read(&x,&y,&z); //Get the values of X,Y and Z from sensor 
  
  int heading=atan2(x, y)/0.0174532925; //Calculate the degree using X and Y parameters with this formulae 
 //Convert result into 0 to 360
  if(heading < 0) 
  heading+=360;
  heading = 360-heading;
  
  Serial.println(heading); //Print the value of heading in degree for debugging </p>  <p>//Based on the value of heading print the result for debugging and glow the respective LED.
  if (heading > 338 || heading < 22)
  {
    Serial.println("NORTH");
    digitalWrite(ledPins[0],HIGH);
  }
  if (heading > 22 && heading < 68)
  {
    Serial.println("NORTH-EAST");
    digitalWrite(ledPins[7],HIGH);
  }
  if (heading > 68 && heading < 113)
  {
    Serial.println("EAST");
    digitalWrite(ledPins[6],HIGH);
  }
  if (heading > 113 && heading < 158)
  {
    Serial.println("SOUTH-EAST");
    digitalWrite(ledPins[5],HIGH);
  }
  if (heading > 158 && heading < 203)
  {
    Serial.println("SOUTH");
    digitalWrite(ledPins[4],HIGH);
  }
  if (heading > 203 && heading < 248)
  {
    Serial.println("SOTUH-WEST");
    digitalWrite(ledPins[3],HIGH);
  }
  if (heading > 248 && heading < 293)
  {
    Serial.println("WEST");
    digitalWrite(ledPins[2],HIGH);
  }
  if (heading > 293 && heading < 338)
  {
    Serial.println("NORTH-WEST");
    digitalWrite(ledPins[1],HIGH);
  }
  delay(500); // update position of LED for every alf seconds 
//Turn off the all the LED 
    for (int thisPin=0; thisPin <= led_count; thisPin++){
     digitalWrite(ledPins[thisPin],LOW);
  }
}

Не пропустите обновления! Подписывайтесь на нашу группу Вконтакте.
Так же у нас есть Telegram канал.
Вам понравился наш материал? Поделитесь с коллегами!

Просмотров: 6276. Оценка статьи: 5.0 из 5. Уже оценило 1 читатель

Об авторе - Администратор

More by Администратор

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]