GY-85 – SENSOR IMU – ITG3205 + ADXL345 + HMC5883L

Neste tutorial aprenderemos sobre o Sensor de Movimento de Cabeça GY-85. Este, no que lhe concerne, é muito utilizado em controles em jogos de videogame. Visualizaremos como este pequeno componente funciona e desenvolveremos uma aplicação para ele.

kit robotica educacional com Arduino ESP ou Microbit

O  que é o Sensor IMU — GY-85?

O sensor IMU é utilizado como dito anteriormente para projetos vestíveis(wearables) para movimentação. Contudo, ele utiliza 3 sensores em uma mesma placa: acelerômetro, giroscópio e magnetômetro. 

– Funcionamento

Primeiramente, o sensor de movimento IMU(Inertial Measurement Unit) possui 9 eixos acoplados a ele, sendo estes: 3 eixos acelerômetros, 3 eixos giroscópio e 3 eixos campo magnético. Com estes eixos é possível detectar qualquer tipo de movimento que efetuar com o sensor. Os sensores utilizam da força da gravidade, de seus polos e das direções X, Y e Z para realizar as suas funcionalidades, cada um para determinar algo distinto. Com a gravidade da terra e com os eixos X, Y e Z destes sensores é possivel saber o posicionamento espacial, a aceleração, a direção e o sentido daquele que utiliza o sensor como por exemplo um smartphone.

– Campo Magnético 

Graças a um efeito de dínamo a terra possui um campo magnético e como consequencia nos podemos usar ele em nossas tecnologias. Como sabemos o núcleo líquido de ferro que se movimenta cria correntes elétricas no interior da terra, enquanto a rotação da Terra em seu próprio eixo faz com que essas correntes gerem um campo magnético gigante, o qual nos orientou por muito tempo com o auxilio da bussola e nos orienta até hoje em direção ao futuro, nos ajudando no desenvolvimento das tecnologias.

Imagem do campo magnético da terra

O fato dos campos magnéticos irem do polo sul até o polo norte faz com que a terra seje considerada um imã. O sensor IMU utiliza do campo magnético, da força gravitacional e dos circuitos integrados para identificar seu posicionamento espacial, aceleração, intensidade, distancia e sentido .

– Sensores acoplados:

As funções dessa placa são controladas por 3 Circuitos integrados, cada um com sua função específica:

  • ITG3205 (3-Axis Angular Rate Sensor) – Giroscópio 3 eixos
  • ADXL345 (3-Axis Digital Accelerometer) – Acelerômetro 3 eixos
  • HMC5883L (3-Axis Digital Compass) – Bússola digital / Magnetômetro 3 eixos

– Os terminais deste sensor que serão utilizados são:

  • VCC_IN(+) – Tensão de entrada, entre 3,3 a 5 volts
  • GND(-) – O pino de O V do módulo, que é conectado ao GND do Arduino ou fonte
  • SCL – I2C Serial Clock
  • SDA – I2C Serial Data

Módulo do sensor IMU

 

Mãos à obra — Configurando um sensor IMU

Componentes Necessários

– Montando o projeto:

Mostraremos como utilizar cada sensor ligando-o ao Arduino Uno. Sobretudo, como todos eles utilizam o mesmo barramento I2C, teremos apenas um circuito para todos os programas exemplos. A principio, para a montagem do circuito conectemos o sensor na protoboard. O VCC do sensor é conectado no 5v do arduino, logo após conectaremos o GND do sensor ao GND do arduino. Além disso, o pino SCL do sensor é conectado ao pino A5 do arduino e o pino SDA é conectado ao pino A4 do arduino como mostra o diagrama abaixo:

Diagrama de montagem do sensor IMU

– Biblioteca Wire.h:

Neste tutorial utilizaremos a biblioteca Wire.h responsável por conter as funções necessárias para gerenciar a comunicação entre os dispositivos através do protocolo I2C. Ademais, caso não entenda nada de biblioteca ou como prosseguir, veja o tutorial COMO INSTALAR UMA BIBLIOTECA NO ARDUINO IDE” no portal vida de silício.

– Programando o Arduino:

Agora vamos conectar o arduino no computador e abrir a IDE arduino.  Escreva o programa abaixo na IDE e compile o programa para o seu arduino.

Antes de carregar o programa, você precisa selecionar qual porta você deseja usar para fazer o carregamento do seu programa no Arduino (upload). Dentro do Arduino IDE, clique no menu Ferramentas (tools) e abra o submenu Porta(Port). Clique na porta que seu Arduino está conectado, tal como COM3 ou COM4. Geralmente aparece o nome da placa Arduino : “COM3 (Arduino/Genuino Uno)”.
A primeira coisa que você notará é que ao alimentar o sensor não há nenhuma indicação de que ele está ligado. A placa não possui nenhum led , logo utilizaremos um programa chamado I2C Scanner (http://playground.arduino.cc/Main/I2cScanner) para efetuar um rastreamento no barramento I2C e garantir que o sensor esteja adequadamente ligado ao Arduino. Carregue o I2C Scanner:

#include <Wire.h>
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}
void loop()
{
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000);           // wait 5 seconds for next scan
}

Se as conexões estiverem corretas, ao abrir o serial monitor teremos a seguinte tela, mostrando os endereços dos dispositivos detectados:

O I2C Scanner é um programa que serve não apenas para este módulo, mas também para qualquer outro dispositivo I2C conectado ao barramento. Além disso, Tenha este programa sempre à mão para descobrir o endereço do dispositivo ou simplesmente para verificar se ele está se comunicando com o Arduino.

Imagem do circuito do sensor IMU

– Acelerômetro 3 eixos(ADXL345)

Já sabendo o endereço do circuito integrado ADXL345 podemos proseguir. Este circuito é um acelerômetro muito utilizado nos telefones celulares, pois é através do acelerômetro que o seu celular detecta a posição do aparelho e permite que você passe horas jogando sem apertar nenhum botão, apenas movimentando o aparelho. Utilize o programa abaixo para testar o ADXL345 (datasheet), cujo endereço I2C é 0x53:

#include <Wire.h>
#define Register_ID 0
#define Register_2D 0x2D
#define Register_X0 0x32
#define Register_X1 0x33
#define Register_Y0 0x34
#define Register_Y1 0x35
#define Register_Z0 0x36
#define Register_Z1 0x37
// Endereco I2C do sensor : 83 em decimal ou 0x53
int ADXAddress = 0x53;  // the default 7-bit slave address
int reading = 0;
int val=0;
int X0,X1,X_out;
int Y0,Y1,Y_out;
int Z1,Z0,Z_out;
double Xg,Yg,Zg;
void setup()
{
  Wire.begin();                
  Serial.begin(9600);    
  delay(100);
  // enable to measute g data
  Wire.beginTransmission(ADXAddress);
  Wire.write(Register_2D);
  Wire.write(8);                //measuring enable
  Wire.endTransmission();     // stop transmitting
}
void loop()
{
  //--------------X
  Wire.beginTransmission(ADXAddress); // transmit to device
  Wire.write(Register_X0);
  Wire.write(Register_X1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress,2); 
  if(Wire.available()<=2)   
  {
    X0 = Wire.read();
    X1 = Wire.read(); 
    X1=X1<<8;
    X_out=X0+X1;   
  }
  //------------------Y
  Wire.beginTransmission(ADXAddress); // transmit to device
  Wire.write(Register_Y0);
  Wire.write(Register_Y1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress,2); 
  if(Wire.available()<=2)   
  {
    Y0 = Wire.read();
    Y1 = Wire.read(); 
    Y1=Y1<<8;
    Y_out=Y0+Y1;
  }
  //------------------Z
  Wire.beginTransmission(ADXAddress); // transmit to device
  Wire.write(Register_Z0);
  Wire.write(Register_Z1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress,2); 
  if(Wire.available()<=2)   
  {
    Z0 = Wire.read();
    Z1 = Wire.read(); 
    Z1=Z1<<8;
    Z_out=Z0+Z1;
  }
  //
  Xg=X_out/256.0;
  Yg=Y_out/256.0;
  Zg=Z_out/256.0;
  Serial.print("X= ");
  Serial.print(Xg);
  Serial.print("       ");
  Serial.print("Y= ");
  Serial.print(Yg);
  Serial.print("       ");
  Serial.print("Z= ");
  Serial.print(Zg);
  Serial.println("  ");
  delay(200);
}

Movimente o sensor e observe a variação dos eixos X, Y e Z  de acordo com a força gravitacional que incide sobre o circuito integrado no serial monitor:

Imagem do serial monitor para o acelerômetro

– Bússola digital(HMC5883L)

O circuito integrado HMC5883L (datasheet) é um instrumento usado para medir a intensidade, direção e sentido de campos magnéticos e possui 3 eixos. É com ele que montamos uma bússola com o Arduino, utilizando como base o programa abaixo, que mostra os valores correspondentes aos eixos X, Y e Z. O endereço I2C do sensor é 0x1E, o qual já achamos anteriormente:

#include <Wire.h>
// Define o endereco do HMC5883L - 0x1E ou 30 em decimal
#define address 0x1E 
void setup()
{
  Serial.begin(9600);
  Wire.begin();
  
  // Inicializa o HMC5883L
  Wire.beginTransmission(address);
  // Seleciona o modo
  Wire.write(0x02); 
  // Modo de medicao continuo
  Wire.write(0x00); 
  Wire.endTransmission();
}
void loop()
{
  int x,y,z; //triple axis data
  
  // Indica ao HMC5883L para iniciar a leitura
  Wire.beginTransmission(address);
  Wire.write(0x03); //select register 3, X MSB register
  Wire.endTransmission();
 
  // Le os dados de cada eixo, 2 registradores por eixo
  Wire.requestFrom(address, 6);
  if(6<=Wire.available())
  {
    x = Wire.read()<<8; //X msb
    x |= Wire.read(); //X lsb
    z = Wire.read()<<8; //Z msb
    z |= Wire.read(); //Z lsb
    y = Wire.read()<<8; //Y msb
    y |= Wire.read(); //Y lsb
  }
  
  // Imprime os vaores no serial monitor
  Serial.print("x: ");
  Serial.print(x);
  Serial.print("  y: ");
  Serial.print(y);
  Serial.print("  z: ");
  Serial.println(z);
  
  delay(250);
}

Da mesma forma que no exemplo anteriores, os valores são mostrados no serial monitor de acordo com o campo magnetico que incide sobre o circuito integrado:

Imagem do serial monitor para a Bússola digital

Entendendo a fundo:

Software

– Definições e variáveis utilizadas no projeto do sensor de movimento de cabeça

A instrução #include<> serve para incluir bibliotecas no algoritmo.

#include <Wire.h>

– Função Setup – Definindo pinos do nosso sensor de movimento de cabeça

 A função setup é aquela que ira rodar apenas uma vez quando nosso programa for iniciado. Ela é do tipo void, ou seja, não tem retorno e também não tem parâmetros de entrada. A função  Serial.begin inicia a comunicação serial e define uma velocidade para ela para que possamos visualizar o funcionamento do sensor no serial monitor da IDE arduino. A função Serial.println escreve no serial monitor o texto “I2C Scanner” .

Serial.begin(9600);
Serial.println("\nI2C Scanner");

– Função Loop – Leitura do nosso sensor de movimento de cabeça e Estruturas de decisão

A função loop ao contrário da setup roda tudo que estiver dentro dela varias vezes em um loop constante até que seja reiniciado ou parado o programa. Precipuamente, declaramos uma variavel do tipo int e logo depois do “Serial.println” atribuimos o valor 0 a ela. Também declaramos as veriaveis do tipo byte “error” e “address”.

void loop(){ 
 byte error, address;  
 int nDevices;   
 Serial.println("Scanning...");   
 nDevices = 0;

Não obstante, a estrutura de repetição for será executada enquanto a variavel declarada anteriormente “address” for menor que 127. Ela inicializa com o valor 1 e a cada ciclo adiciona- se +1.

for(address = 1; address < 127; address++ ){

Similarmente, estrutura de de decisão if será executada caso a condição entre parenteses for verdadeida. No primeiro if caso a variave “error” fo igual a zero a linha de código “Serial.print(“I2C device found at address 0x”);” será executada.

if (error == 0){       
  Serial.print("I2C device found at address 0x");

Logo depois, caso a variavel “address” for menor que 16 as linhas de código dentro dos colchetes será executada. Irá imprimir o texto “0” e logo após o endereço dos circuitos integrados. Tambem irá imprimir no serial monitor o texto ” !” e  vai adicionar +1 a variavel nDevices com o comando “nDevices++”.

if (address<16) {        
  Serial.print("0");        
  Serial.print(address,HEX);        
  Serial.println("  !");        
  nDevices++;  
   }

Caso a estutura if com a condição “error == 0” não for verdadeira iremos direto para a estrutura else if. Se for verdadeira, ou seja, a variavel error for igual a quatro a linha “Serial.print(“Unknow error at address 0x”);” será executada e impressa no serial monitor.

 else if (error==4){    
   Serial.print("Unknow error at address 0x");

Igualmente a estura if, se a variavel “address” for menor que 16 será executado as linhas de código abaixo, imprimindo no serial monitor o texto zero e o endereço dos circuitos integrados.

if (address<16)  {        
  Serial.print("0");       
  Serial.println(address,HEX);    
 }

Agora, caso a variavel “address” for maior que 16, então as estruturas anteriores com a condição “address<16” não serão executadas e a variavel “nDevices” permanecerá com o valor 0. Sendo assim, a estrutura if a seguir será verdadeira e a estrutura “Serial.println(“No I2C devices found\n”);” será executada. Em contrapartida, se a variavel “address” for menor que 16 de fato, a estrutura else que será executada.

       
    
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
    delay(5000);           // wait 5 seconds for next scan
}

 

Hardware

– ITG3205

O sensor giroscópio de 3 eixos acoplado ao sensor IMU permite entender o posicionamento espacial através da força de gravidade. sendo assim, quando um objeto está em movimento, os sensores de eixo do giroscópio conseguem informar exatamente para qual direção o produto está se movendo. Uma de suas aplicações é em aparelhos smartphones onde detecta quando você gira o aparelho detectando a velocidade angular do aparelho e se está apontado para cima ou para baixo. O que podemos tirar disto é que ele é muito empregado em sistema que necessitam interpretar os movimentos do utilizador.

– ADXL345

O sensor acelerômetro de 3 eixos acoplado ao sensor IMU mede a aceleração através da força de gravidade a que o sensor está sujeito em cada um dos três eixos. Ele mede a inclinação e o movimento. Sendo assim, consegue detectar o movimento de rotação e gestos tais como balançar ou agitar um objeto do qual ele faz parte.

O gráfico (a) representa uma situação onde o acelerômetro se encontra em repouso, pousado numa superfície plana, os valores comunicados pelos sensores serão x= 0, y=0 e z=-1. Já o gráfico (b) representa a rotação do eixo X para baixo, os valores comunicados pelo sensor serão x=1, y=0 e z=0. O grafico (c) representa a rotação do eixo Y, os valores comunicados pelo sensor serão x=0, y=1 e z=0.

– HMC5883L

Sensor magnetômetro de 3 eixos é acoplado ao sensor IMU.  Sendo assim, ele funciona como uma bússola digital e identifica a intensidade, direção e sentido de campos magnéticos . Com o arduino é usado para literalmente nos dar um norte.

Considerações finais:

Neste tutorial mostramos como funciona e como utilizar o sensor de movimento IMU. Esperamos que você continue nos acompanhando e sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.