Bússola digital usando Arduíno e magnetômetro HMC5883L

Como fazer uma bússola usando Arduíno e magnetômetro HMC5883L, passo a passo do começo ao fim do projeto com diagrama de circuito e a programação usada.

Bússola Digital usando Arduino e Magnetômetro HMC5883L

Cérebro humano é construído de camada complexa de estruturas que nos ajuda a ser uma espécie dominante na terra. Por exemplo, o córtex entorrinal em seu cérebro pode lhe dar senso de direção, ajudando-o a navegar facilmente através de lugares com os quais você não está familiarizado. Mas, ao contrário de nós, robôs e veículos não-tripulados precisam de algo para obter esse senso de direção, de modo que possam manobrar de forma autônoma em novos terrenos e paisagens. Diferentes robôs usam diferentes tipos de sensores para realizar isso, mas o mais comumente usado é um magnetômetro, que poderia informar ao robô em qual direção geo-gráfica ele está indo atualmente. Isso não só ajudará o robô a saber a direção, mas também a se alternar em uma direção pré-definida.

Como o sensor poderia indicar o norte, sul, leste e oeste, nós humanos também poderíamos usá-lo quando necessário. Então, neste artigo vamos tentar entender como funciona o sensor Magnetômetro e como fazer interface com um microcontrolador como o Arduino. Aqui vamos construir uma bússola digital legal que nos ajudará a encontrar as direções, acendendo um LED apontando para a direção norte. Para que eu possa carregá-la na próxima vez que eu sair na mata e desejar que eu me perca apenas para usar essa bússola para encontrar meu caminho de volta para casa. Vamos começar.

Materiais necessários

O que é um magnetômetro e como funciona?

Antes de mergulharmos no circuito, vamos entender um pouco sobre magnetômetro e como eles funcionam. Como o nome sugere, o termo Magneto não se refere àquele mutante louco em marvel que podia controlar metais apenas tocando piano no ar. Ohh! Mas eu gosto desse cara, ele é legal.

Magnetômetro é na verdade um equipamento que pode sentir os pólos magnéticos da Terra e apontar a direção de acordo com isso. Nós todos sabemos que a Terra é enorme pedaço de ímã esférico com pólo norte e pólo sul. E há campo magnético por causa disso. Um magnetômetro detecta esse campo magnético e, com base na direção do campo magnético, pode detectar a direção que estamos indo.

Como funciona o módulo do sensor HMC5883L

O HMC5883L, é um sensor de magnetômetro, faz a mesma coisa. Ele tem o HMC5883L IC que é da Honeywell. Este IC tem 3 materiais magneto resistivos dentro dos quais estão dispostos nos eixos x, y e z. A quantidade de corrente que flui através desses materiais é sensível ao campo magnético da Terra. Então, medindo a mudança na corrente que flui através desses materiais, podemos detectar a mudança no campo magnético da Terra. Uma vez que a mudança é absorvida pelo campo magnético, os valores podem ser enviados para qualquer controlador incorporado, como um microcontrolador ou processador, através do protocolo I2C.

Como o sensor funciona detectando o campo magnético, os valores de saída serão muito afetados se um metal for colocado nas proximidades. Esse comportamento pode ser aproveitado para usar esses sensores como detectores de metal também. Deve-se tomar cuidado para não aproximar os ímãs deste sensor, pois o forte campo magnético de um imã pode acionar valores falsos no sensor.

Diferença entre HMC5883L e QMC5883L

Existe uma confusão comum envolvendo esses sensores para muitos iniciantes. Isso ocorre porque alguns fornecedores (na verdade, a maioria) vendem os sensores QMC5883L em vez do HMC5883L original da Honeywell. É principalmente porque o QMC5883L é muito mais barato que o módulo HMC5883L. A parte triste é que o funcionamento desses dois sensores é um pouco diferente e o mesmo código não pode ser usado para ambos. Isso ocorre porque o endereço I2C de ambos os sensores não é o mesmo. O código fornecido neste tutorial funcionará apenas para o QMC5883L, o módulo do sensor comumente disponível.

Para saber qual modelo de sensor você está tendo, basta olhar de perto para o próprio IC para ler o que está escrito nele. Se está escrito algo como L883 então é o HMC58836L e se está escrito algo como DA5883 então é o IC QMC5883L. Ambos os módulos são mostrados na imagem abaixo para facilitar a compreensão.

Diagrama de circuito

O circuito para esta Bússola Digital baseada no Arduino é bastante simples, nós simplesmente temos que conectar o sensor HMC5883L com o Arduino e conectar 8 LEDs aos pinos GPIO do Arduino Pro mini. O diagrama de circuito completo é mostrado abaixo.

O módulo Sensor possui 5 pinos, dos quais o DRDY (Data Ready) não é usado em nosso projeto, já que estamos operando o sensor em modo contínuo. O Vcc e o pino terra são usados para alimentação da módulo 5V da placa Arduino. O SCL e o SDA são as linhas de barramento de comunicação I2C conectadas aos pinos A4 e A5 I2C do Arduino Pro mini, respectivamente. Como o próprio módulo tem um resistor de alta resistência nas linhas, não há necessidade de adicioná-lo externamente.

Para uma indicação, o uso de 8 LEDs todos os contatos ao GPIO do Arduino através de um resistor limitador de corrente de 470 Ohms. O circuito é alimentado por uma bateria de 9V através do cano Jack. Este 9V é fornecido com o pino Vin do Arduino, onde é regulado para 5V usando o regulador de bordo no Arduino. Este 5V é usado para alimentar o sensor e também o Arduino.

Fabricando os PCBs para a bússola digital

A ideia do circuito é posicionar os 8 LEDs de forma circular, de modo que cada Led marque todas as 8 direções: Norte, Nordeste, Leste, Sudeste, Sul, Sudoeste, Oeste e Noroeste, respectivamente. Por isso, não é fácil organizá-los ordenadamente em uma placa de ensaio ou mesmo em uma placa perfeita para esse assunto. Desenvolver uma PCB para este circuito fará com que pareça mais limpo e fácil de usar. Então eu abri meu software de design de PCB e coloquei os LEDs e o resistor em um padrão circular limpo e conectei os trilhos para formar as conexões. Meu design parecia algo como este abaixo quando concluído. Você também pode baixar o arquivo no link fornecido.

Eu o projetei para ser uma placa duble layer já que eu quero que o Arduino esteja no lado inferior da minha PCB para que ele não estrague a aparência em cima da minha PCB. Se você está se preocupando que você tem que pagar alto por uma PCB de duble layer.

Montagem do PCB

Solde os componente seguindo o diagrama e tendo como parâmetro as imagens abaixo.

Programando o Arduino

Agora que nosso hardware está pronto, vamos examinar o programa que precisa ser enviado para a nossa placa Arduino. O objetivo do código é ler os dados do sensor do magnetômetro QMC5883L e convertê-lo em grau (0 a 360). Uma vez que sabemos o grau, temos que ligar o LED apontando para uma direção específica. A direção que usei neste programa é norte. Portanto, independentemente de onde você esteja, haverá apenas um LED brilhando em sua placa e a direção do LED indicará a direção NORTE. Uma vez mais tarde, calcular a outra direção é uma direção conhecida.

O código completo para este Projeto de Bússola Digital pode ser encontrado no final desta página. Você pode enviá-lo diretamente em sua placa depois de incluir a biblioteca e você está pronto para ir. Mas, se você quiser saber mais sobre o que realmente está acontecendo no código, leia mais adiante.

Como dito anteriormente, estamos usando o QMC5883L IC, para nos comunicarmos com o IC, precisamos saber o endereço I2C de seus registradores, que pode ser encontrado em sua folha de dados. Mas, para nossa sorte, tudo isso já está pronto e é empacotado como uma biblioteca por um cara chamado keepworking no Github. Então tudo que você precisa fazer é simplesmente baixar a biblioteca para QMC5883L clicando no link para obter um arquivo ZIP. Este arquivo ZIP pode então ser adicionado ao seu Arduino IDE seguindo a biblioteca Sketch -> Include Library -> Add .ZIP.

Depois que a Biblioteca for adicionada, poderemos prosseguir com nosso programa. Começamos o programa incluindo os arquivos de biblioteca necessários, conforme mostrado abaixo. A biblioteca de cabos é usada para ativar a comunicação I2C e o MechaQMC5883 é o que acabamos de adicionar ao Arduino. Esta biblioteca contém todas as informações sobre como conversar com o sensor EMC5883L.

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

Na próxima linha, criamos um nome de objeto para o sensor que estamos usando. Eu usei o nome qmc mas pode ser o que você quiser.

MechaQMC5883 qmc; //Create an object name for the snsor, I have named it as qmc

Em seguida, entramos nas declarações de variáveis globais. Aqui, uma vez que temos 8 Led como saídas, é difícil fazer referência a cada um através do nome do pino, portanto, estamos usando a opção de matriz para nos referirmos a todos os LEDs. O nome da matriz é ledPins e a variável led_count é o número de led que temos. Começa com 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

Dentro da função de configuração void, nós inicializamos a comunicação I2C, a comunicação serial e o sensor também. Então nós declaramos todos os pinos LED como pinos de saída. Como usamos uma matriz, é fácil fazer referência a todos os pinos usando um loop for e navegando pelo loop for, conforme mostrado abaixo.

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
  }
}

No loop principal, que é infinito, temos que obter os valores de x, yez do sensor e calcular o grau em que o sensor está atualmente. Para ler os valores de x, y e z use a seguinte linha.

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

As fórmulas para calcular o cabeçalho em grau são mostradas abaixo. Como não vamos girar a bússola ao longo do eixo z, não levamos esse valor em consideração. Essas fórmulas podem ser usadas somente se a superfície plana do IC estiver voltada para cima, como em nossa configuração. Uma vez que o cabeçalho é calculado, o valor estará no intervalo de -180 a 180, o qual temos que converter para 0 a 360, como encontraríamos em todas as bússolas digitais.

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;

O passo final é acender o LED apontando na direção NORTE. Para fazer isso, temos séries de declarações de condições, onde verificamos em qual faixa o grau está atualmente e ativamos o LED de acordo com isso. O código é mostrado abaixo.

//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);
  }

A lógica por trás dos valores do código pode ser entendida observando a tabela abaixo. Basicamente, calculamos a direção que estamos enfrentando e prevemos a direção norte e o brilho do respectivo LED.

Direção

Grau correspondente a Direção

Intervalo para essa direção

NORTE

0° / 360°

>338° or < 22°

NORDESTE

45°

22° to 68°

LESTE

90°

68° to 113°

SUDESTE

135°

113° to 158°

SUL

180°

158° to 203°

SUDOESTE

225°

203° to 248°

OESTE

170°

248° to 293°

NOROESTE

315°

293° to 338°

A parte final do programa é definir a rapidez com que o resultado deve ser atualizado. Eu criei um atraso de 500 milissegundos e, em seguida, fiz todo o LED para desligar para começar de novo, formando o primeiro dentro do loop vazio. Mas se você precisar de atualizações mais rápidas, você pode reduzir o atraso ainda mais.

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);
  }

Testando a bússola digital

Como usamos o Arduíno pro mini, precisamos de um programador externo, como uma placa FTDI, para fazer o upload do programa. Uma vez que o programa é carregado, você deve notar um LED está brilhando na placa, a direção em que o LED está brilhando será a direção NORTE.

Você pode então brincar com a placa girando-a e verificar se o LED ainda aponta para a direção norte. Depois disso, você pode usar uma bateria de 9V a qualquer momento para energizar a configuração e verificar a direção que está enfrentando. O funcionamento completo da bússola digital pode ser encontrado no vídeo abaixo. Você pode notar que os valores ficarão errados quando houver uma peça de metal pesado perto da sua placa ou mesmo se você girar a placa ao longo do eixo Z. Existem maneiras de superar esse problema e isso é para outro tutorial.

/*
 * Program for Arduino Digital Compass using QMC5883
 * Project by: Aswinth Raj
 * Dated: 1-11-2018
 * Website: www.circuitdigest.com
 * 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 

//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);
  }
}


Fonte: CircuitDigest


 

[su_posts posts_per_page=”4″ taxonomy=”post_tag” tax_term=”30″ offset=”1″ order=”desc” ignore_sticky_posts=”yes”]

Sair da versão mobile