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, que estão no Github do Arduino e Cia:

  • 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:



66 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
    Respostas
    1. acelerômetro mede aceleração angular. O giroscópio informa a velocidade angular. Vc teria q fazer algumas contas para obter o ângulo!

      Excluir
  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
  21. É possível ligar mais de um giroscópio no Arduino? O que precisaria para fazer? Obrigado.

    ResponderExcluir
    Respostas
    1. Boa tarde Tiago,

      É possível sim. Os dois módulos devem ter endereço I2C diferentes. Dê uma olhada no post onde eu falo sobre a alteração do endereço usando o pino AD0.

      Abraço!

      Excluir
  22. Boa tarde, desculpe o meu desespero. Estou usando a mpu com o pic18f4550, e um lcd para exibir os valores de oscilação da mpu. Gostaria de saber se preciso calibrar a mpu e como fazer isso. Porque os dados estão oscilando muito mesmo com a pu parada.

    ResponderExcluir
    Respostas
    1. Boa tarde Carine,

      Com PIC não sei te falar como funciona, mas para Arduino temos alguns métodos para calibração. Dê uma olhada neste post, por favor, talvez te ajude: https://www.i2cdevlib.com/forums/topic/112-another-auto-offset-calibration-sketch/

      Abraço!

      Excluir
  23. Ola, tudo bem? Obrigado pelo tutorial!
    Fiz o teste e funcionou perfeitamente... resolvi montar um projeto, com uma placa de circuito integrado, e depois que gravei a placa, e soldei tudo, percebi que inverti o SCL e SDA... coloquei o SCL no A4 e o SDA no pino A5. No codigo tem algum lugar q eu possa mudar isso, pra que funcione do jeito q montei a placa? Não queria ter que gravar outra placa.
    Obrigado!

    ResponderExcluir
    Respostas
    1. Acho que você vai ter que gravar outra placa... :)

      Abraço!

      Excluir
  24. o meu não compila no arduino... fica travado na barra de compilando sketch, alguem sabe porque?

    ResponderExcluir
    Respostas
    1. Eliézer estava tendo o mesmo problema, "acho" que era o arquivo MPU6050_test.pde que vem o codigo para rodar no arduino mas abre no processing e quando vc leva o codigo para o arduino e não fecha o processing deve dá algum conflito quando carrega(pelo menos comigo funcionou assim).
      Outra dua dicas para rodar tudo certo é abrir o arquivo FreeIMU_cube1.pde no processing 2.2 e no codigo do arquivo .ino incluir essas duas linhas
      #define send write
      #define receive read
      Comecei estudar a pouco, e houveram algumas mudanças na v.3.3 no processing que não sei como atualizar este código para rodar lá.

      Excluir
  25. galera, concerta o código ai porque ta dando bronca na hora de gravar

    ResponderExcluir
  26. Hola buenas tarde como podría enviar los datos del sensor por bluetooth para verlos en una aplicación móvil

    ResponderExcluir
  27. Olá! O site verasano.net não está carregando e por isso não consigo baixar o MPU_6050_test.zip. Teria alguma outra forma de conseguir esse arquivo?

    Obrigada!
    Camila

    ResponderExcluir
    Respostas
    1. Boa noite, desculpe a demora. Não estava achando o arquivo, mas agora está disponível no Github do Arduino e Cia. O link está no post. :)

      Abraço e obrigado!

      Adilson

      Excluir
  28. Por favor, vc poderia ajeitar o link do MPU_6050_test.zip? Nao esta funcionando.

    Obrigado.

    ResponderExcluir
    Respostas
    1. Boa noite, desculpe a demora. Não estava achando o arquivo, mas agora está disponível no Github do Arduino e Cia. O link está no post. :)

      Abraço e obrigado!

      Adilson

      Excluir
  29. Respostas
    1. Boa noite Walter,

      Desculpe a demora. Os arquivos estão disponíveis no github do Arduino e Cia. Links no post, ok? :)

      Abraço!

      Adilson

      Excluir
  30. deu erro no processing:

    OpenGL error 1280 at bot beginDraw(): invalid enumerant

    ResponderExcluir
  31. Olá, alguem teria esse arquivo para download "MPU_6050_test.pde"? o link da página não carrega mais

    ResponderExcluir
    Respostas
    1. Boa noite, desculpe a demora. Não estava achando o arquivo, mas agora está disponível no Github do Arduino e Cia. O link está no post. :)

      Abraço e obrigado!

      Adilson

      Excluir
  32. Bom dia. Também estou precisando baixar o arquivo "MPU_6050_test.pde" ou "MPU_6050_test.zip" e o link não existe mais. Alguém poderia passar um link ou me enviar, por favor?

    ResponderExcluir
    Respostas
    1. Boa noite Mauro,

      Desculpe a demora. Os arquivos estão disponíveis no github do Arduino e Cia. Links no post, ok? :)

      Abraço!

      Adilson

      Excluir
    2. Bom dia Edson,
      Desculpe-me a demora em responder, consegui, obrigado.

      Você sabe se tem como converter esta comunicação em WIFI?
      Tenho um Arduino UNO R3 Wifi e não estou conseguindo.

      Obrigado.

      Excluir
    3. Bom dia.

      Desculpe-me, é Adilson.

      Obrigado.

      Excluir
  33. Boa tarde, sou novo nesse negócio de Arduíno, estou utilizando para meu TCC, e utilizei a programação disponível aqui no site, gostaria de saber como faço pra saber a unidade de medida que o sensor está disponibilizando no giroscópio e eixos do acelerômetro, pois tem valores bem altos.
    Também estou como uma dúvida de como registrar as medições em tempo real no excel.

    ResponderExcluir
  34. Olá, quando vou carregar o MPU6050 test no arduino fica aparecendo isso Arduino: 1.6.8 (Windows 10), Placa:"Arduino/Genuino Uno"

    C:\Users\Daniel\Documents\Arduino\MPU6050_test\MPU6050_test.pde: In function 'void dmp_init()':

    MPU6050_test:351: error: Wire.send() foi renomeada para Wire.write().
    Desd o Arduino 1.0, a função Wire.send() foi renomeada para Wire.write() por questões de consistência com outras bibliotecas.


    Wire.send(MEM_START_ADDR);

    É algum problema com a minha biblioteca? Se alguém puder ajudar eu seria extremamente grato.

    ResponderExcluir