28 abril 2015

Acelerômetro e Giroscópio MPU6050

O módulo acelerômetro e giroscópio MPU6050 é um componente de alta precisão que conta também com um sensor de temperatura para leituras entre -40 e +85 °C. Controlado pelo CI MPU-6050 (datasheet), ele é um sensor de 6 eixos (6 DOF - Degrees of Freedom, ou 6 Graus de Liberdade), fornecendo 6 valores de saída, sendo 3 do acelerômetro e 3 do giroscópio. 

acelerometro e giroscopio mpu-6050

Esse CI tem um recurso chamado DMP (Digital Motion Processor), um acelerador de hardware que cuida da parte dos complexos cálculos do sensor. 

Por ser um sensor de baixo custo, preciso e econômico em termos de consumo de energia, é ideal para projetos envolvendo robôs e simuladores, além é claro das aplicações em dispositivos portáteis, como smartphones e tablets, projetos de realidade aumentada e monitoração de equipamentos, entre outras. 

Conexão do módulo MPU6050 ao Arduino

O módulo utiliza a comunicação via interface I2C, assim a conexão com o Arduino é bastante simplificada, utilizando apenas os pinos analógicos A4 (SDA) e A5 (SCL) e a alimentação, que pode variar entre 3 e 5V.

Pinos MPU-6050

Os pinos XDA e XCL podem ser utilizados para ligação de outros dispositivos I2C ao módulo. Por meio do pino AD0 você pode selecionar o endereço I2C: em nível baixo o endereço é 0x68, e em nível alto (3.3V), o endereço é 0x69

Neste artigo vou mostrar dois exemplos de utilização dos dados do MPU6050, conectado ao Arduino Uno:

Circuito MPU-6050 e Arduino Uno


Se possível, utilize fios e conectores macho/fêmea para ligação do módulo ao Arduino, já que os testes envolvem a movimentação da placa em várias direções.

MPU6050 - Leitura dos dados no Serial Monitor

Para efetuar a leitura dos dados "puros" do sensor, carregue o programa abaixo no Arduino:

 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
//Programa : Teste MPU-6050
//Alteracoes e adaptacoes : Arduino e Cia
//
//Baseado no programa original de JohnChi
 
//Carrega a biblioteca Wire
#include<Wire.h>
 
//Endereco I2C do MPU6050
const int MPU=0x68;  

//Variaveis para armazenar valores dos sensores
int AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B); 
   
  //Inicializa o MPU-6050
  Wire.write(0); 
  Wire.endTransmission(true);
    
}

void loop()
{
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  
  //Solicita os dados do sensor
  Wire.requestFrom(MPU,14,true);  
  
  //Armazena o valor dos sensores nas variaveis correspondentes
  AcX=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read(); //0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read(); //0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read(); //0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

   
  //Mostra os valores na serial
  Serial.print("Acel. X = "); Serial.print(AcX);
  Serial.print(" | Y = "); Serial.print(AcY);
  Serial.print(" | Z = "); Serial.print(AcZ);
  Serial.print(" | Gir. X = "); Serial.print(GyX);
  Serial.print(" | Y = "); Serial.print(GyY);
  Serial.print(" | Z = "); Serial.print(GyZ);
  Serial.print(" | Temp = "); Serial.println(Tmp/340.00+36.53);
    
  //Aguarda 300 ms e reinicia o processo
  delay(300);
}

Abra o serial monitor, onde serão apresentados os valores de X, Y e Z do acelerômetro e do giroscópio, além da temperatura :

Dados Acelerometro Giroscopio Temperatura


Integrando o MPU6050 com o Processing

Uma das aplicações mais interessantes para mostrar o funcionamento do MPU-6050 é a sua integração com o Processing. Com ele podemos efetuar a leitura do sensor conectado ao Arduino e apresentar esses dados de forma gráfica em uma janela na tela do computador.

(No tutorial Processing : mostre as informações do Arduino no seu computador você encontra informações sobre como instalar o Processing e os passos básicos para utilização do programa)

Um dos melhores exemplos que eu encontrei de utilização do MPU-6050 com o Processing foi no site Varesano.net. O programa desse site gera na tela um retângulo, que se movimenta conforme movimentamos o sensor:


Mais tarde achei uma evolução desse programa, que substitui o retângulo por uma representação do próprio módulo:


Para realizar esses testes com o seu módulo MPU6050, você vai precisar de dois programas:

  • MPU_6050_test.zip - Faça o download, descompacte e carregue o programa MPU_6050_test.pde no Arduino
  • FreeIMU_cube1.zip - Faça o download, descompacte e carregue o programa FreeIMU_cube1.pde no Processing

No programa FreeIMU_cube1.pde, altere a linha abaixo de acordo com a porta serial utilizada pelo seu Arduino:

final String serialPort = "/dev/tty.usbmodem1d11";

No caso da porta COM5, por exemplo, o código ficará assim:

final String serialPort = "COM5";

Após as alterações, acione o botão RUN, conforme destacado abaixo, para que seja aberta uma nova janela e o Processing comece a receber os dados do sensor ligado ao Arduino:

Utilize o teclado e pressione H para definir a posição de origem do sensor. Movimente o sensor em várias direções para que o movimento seja reproduzido na tela.

No vídeo abaixo você confere o teste do módulo com Arduino e Processing:



39 comentários:

  1. É normal demorar muito para carregar o MPU_6050_test.pde no Arduino?

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Ele só demora ou nem carrega ?

      Abraço!

      Excluir
  2. Você poderia me explicar que significa cada uma das linhas abaixo?
    Wire.write(0x6B)
    Wire.write(0x3B)
    AcX=Wire.read()<<8|Wire.read();
    e o porque de todas as variaveis são obtidas por meio do Wire.read()<<8|Wire.read() sendo que se é o mesmo comando para todos, não tem como espicificar de qual dado está falando, e se é o mesmo comando, porque reorna resultados diferentes

    ResponderExcluir
  3. Boa tarde!

    Nesse programa ele lê os dados "puros" do sensor. Para calibrar o sensor e, posteriormente, achar os ângulos dos eixos do sensor, como que eu faria?

    Abraço!

    ResponderExcluir
  4. queria ajuda pra criar um sistema que controle a velocidade de um andador de modo que o sensor lesse o aumento de velocidade e que envie um sinal para que os freios acionem em no maximo 10s e pare por completo, pensei em usar um aceleromentro-giroscopio porem nao sei como programar e nem que modelo de sensor capacitivo usar, poderiam me ajudar..
    entrem em contato comigo geh.galo@gmail.com

    ResponderExcluir
  5. Ficou apenas a tela carregada com as leituras paradas

    Yaw = 180
    Pitch = 0
    Roll = 180


    Q
    0.0
    0.0
    0.0
    0.0
    0
    0

    ResponderExcluir
    Respostas
    1. O meu aconteceu a mesma coisa que você Luiz, você conseguiu resolver o problema?

      Excluir
    2. pode ser a configuração de velocidade da porta COM.

      Excluir
  6. olá, alguém poderia me disser como converter os valores crus(valores grandes do acelerômetro e do giroscópio) em ângulos? pois vejo que os valores da temperatura foram convertidos, gostaria de converter os valores do acelerômetro em seus ângulos. Agradeço dede já!

    ResponderExcluir
  7. Quando aperto o play aparece a mensagem "please fix the size()line to continue, o que pode ser?

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Você está usando o mesmo código do post ou alterou algo?

      Abraço!

      Excluir
    2. eu idem... alguém resolveu?

      Excluir
    3. Arrumei, na função Void Setup () vc tem a chamada de função ize(VIEW_SIZE_X, VIEW_SIZE_Y, P3D); mude os valores de X e Y para algum valor inteiro, tipo:
      size(600, 400, P3D);

      Excluir
    4. em todo o código, onde tem, troque VIEW_SIZE_X por 800 e VIEW_SIZE_Y por 600 e comente a linha q declara essas variáveis.

      Excluir
    5. void setup()
      {
      size(800, 600, P3D);
      textureMode(NORMAL);
      fill(255);
      stroke(color(44,48,32));

      Excluir
  8. Como eu ligo dois MPU-6050 no arduino

    ResponderExcluir
    Respostas
    1. Bom dia!

      Você pode ligar os dois no mesmo barramento I2C (pinos SCL e SDA). O que você precisa é que eles estejam com endereços diferentes, ou seja. um deles com o pino AD0 em estado alto (1), e o outro com o pino AD0 em estado baixo (0).

      Abraço!

      Excluir
  9. A tela do meu Processing também ficou congelada apenas a tela carregada com as leituras paradas, sera que é a parte do OpenGL?

    Yaw = 180
    Pitch = 0
    Roll = 180


    Q
    0.0
    0.0
    0.0
    0.0
    0
    0

    ResponderExcluir
    Respostas
    1. pode ser a velocidade de configuração da porta COM.

      Excluir
  10. Boa tarde, sou novo com o uso dos arduinos.Não estou conseguindo fazer rodar na minha placa arduino MEGA 2560. Porque esse código não consigo usar no meu arduino MEGA 2560?

    Obrigado desde ja, abraços.

    ResponderExcluir
    Respostas
    1. Oi Thiago,

      No Mega2560 os pinos SDA e SCL são os pinos 20 e 21. Você fez essa alteração ?

      Abraço!

      Excluir
    2. Fiz sim, e tambem tive que conectar o pino VIO no 3,3v. O correto é conectar ele no 3,3v ou 5v?

      abraço

      Excluir
    3. Oi Thiago,

      Entendi... a alimentação vai de 3 à 5V, então vc pode ligar em qualquer um dos dois.. "dizem" que com 5V o sensor fica mais preciso.

      Por acaso você tem um Uno para testar e ver se o problema não é o módulo ?

      Abraço!

      Excluir
    4. Não possuo o Uno não, mas com o mega consegui nas configurações em que me falou.. Vou usar o pin VIO no 5v então. Obrigado, abraço

      Excluir
  11. se der erro na compilação do código do arduino envolvendo 'wire.send' ou 'wire.receive adicione as seguintes diretivas:

    #define send write
    #define receive read

    ResponderExcluir
  12. Você sabe se tem como medir um deslocamento de pequena escala (50cm)... Porque temos aceleração, gravidade, tempo... Só não sei como integrar essas grandezas físicas.

    ResponderExcluir
    Respostas
    1. deslocamento=(aceleração_no_eixo*intervalo_de_leitura_do_MPU^2)/2

      isso para cada eixo, é a msm equação do MUV que se aprende no ensino médio nas aulas de física.

      Excluir
  13. Respostas
    1. Oi Ellen,

      Para programar, eu uso a IDE do próprio Arduino, e para os desenhos, uso o Fritzing.

      Abraço!

      Excluir
  14. Olá!! Sou beeem iniciante, comecei hoje mesmo haha Então... Sensor conectado ao arduino, led de ambos acesos, porém, na hora de carregar, aparece a seguinte mensagem: "ser_open(): can't set com-state for "\\.\COM3"" alguém sabe?? =/

    ResponderExcluir
  15. Alguém sabe como usar os valores do sensor no Freepie ou Opentrack? Desejo fazer para headtracking...

    ResponderExcluir
  16. Mais uma vez, o Arduino e Cia trazendo informação de qualidade, show de bola :)

    ResponderExcluir
  17. Como pra usar os valores do sensor como o cursor do mouse? ;s

    ResponderExcluir
  18. Olá! Gostaria de saber como faz para passar esses valores para graus depois de já termos os valores dos offsets? Desde de já, obrigada.

    ResponderExcluir
  19. esta aparecendo esse erro: 'check_MPU' was not declared in this scope

    alguém sabe como corrijo?

    ResponderExcluir
  20. Olá, dá pra conectar no mesmo pino A0 e A1 um sensor de pressão (quase igual ao acelerometro) e um modulo de lcd usando o endereçamento?

    ResponderExcluir
    Respostas
    1. Oi Silvia!

      Você consegue ligar vários módulos I2C nos pinos A4 e A5... por exemplo um módulo sensor de pressão e um LCD I2C.

      Dê uma olhada no post abaixo, onde eu uso um display I2C e um módulo RTC DS1307 ao mesmo tempo:
      http://www.arduinoecia.com.br/2015/04/arduino-lcd-16x2-modulo-i2c-rtc-ds1307.html

      Abraço!

      Excluir