Interface com acelerômetro e giroscópio com Arduino - Embarcados
Arduino – Interface com acelerômetro e giroscópio
Henrique Torres apresentou e explicou o princípio de funcionamento de acelerômetros e giroscópios MEMS. Neste artigo iremos apresentar o GY-521, cedido pela FILIPEFLOP para nossa avaliação. Analisaremos seus recursos e faremos uma aplicação simples utilizando a plataforma Arduino UNO.
A placa GY-521 é baseada no CI MPU-6050 da InvenSense. Este CI possui no mesmo invólucro um acelerômetro e um giroscópio de alta precisão com tecnologia MEMS. No total são 6 eixos, sendo três para o acelerômetro e 3 para o giroscópio. Há também a possibilidade da ligação de um magnetômetro externo através de pinos auxiliares.
O MPU-6050 possui internamente um recurso chamado DMP (Digital Motion Processor). O DMP permite que o algoritmo de detecção de movimento seja processado no próprio CI livrando o microcontrolador dessa tarefa. O DMP faz a aquisição do acelerômetro, giroscópio e sensor adicional e faz o processamento dos dados. O resultado pode ser lido diretamente ou colocado em um buffer do tipo FIFO.
O MPU-6050 possui internamente conversores A/D de 16 bits de resolução para cada canal, dessa forma todos os sinais podem ser amostrados ao mesmo tempo. Internamente há um buffer FIFO de 1024 bytes, onde os valores podem ser armazenados e depois lidos, conforme configuração desejada.
Outro recurso interessante do MPU-6050 é o sensor de temperatura interno que permite medidas de -40 °C a +85 °C.
A comunicação é feita através do padrão I2C usando os pinos SCL e SDA. A Figura 1 exibe a pinagem da placa GY-521:
Figura 1 – Pinagem placa GY-521 – Acelerômetro e Giroscópio
Vcc: Alimentação (3,3V à 5V);
GND: 0V;
SCL: I2C Serial Clock (SCL);
SDA (Slave_Data): I2C Serial Data (SDA);
XDA: I2C Master Serial Data, para conexão de sensor auxiliar;
XCL: I2C Master Serial Clock, para conexão de sensor auxiliar;
AD0: Define o endereço da I2C;
INT: pino para interrupção.
Conforme se pode observar na Figura 1, a placa possui poucos componentes, sendo os principais um regulador de tensão de 3,3 V e o MPU-6050. A Figura 2 exibe o esquema elétrico da placa:
Figura 2 – Esquema elétrico placa
Conforme descrito acima, a placa possui um pino de endereço, que é responsável pelo endereçamento do CI no barramento I2C. Quando esse pino está desconectado define que o endereço I2C do sensor é 0x68. Quando conectado a 3,3 V, define o endereço 0x69. Dessa forma é possível utilizar dois módulos em um mesmo circuito.
Para exemplificar a utilização deste sensor, iremos apresentar uma aplicação utilizando a plataforma Arduino. Neste exemplo serão lidos os sinais do acelerômetro, do giroscópio e do sensor de temperatura. Os valores serão exibidos no terminal serial em intervalos de aproximadamente 500 ms.
Exemplo – Lendo acelerômetro e giroscópio com Arduino
A montagem do hardware é bem simples. A Figura 3 exibe a ligação dos módulo GY-521 à placa Arduino Uno:
Figura 3 – Montagem do exemplo
O programa para o Arduino é baseado na biblioteca Wire. Consiste basicamente na inicialização e leitura dos registradores do MPU-6050 através da comunicação I2C. Os valores de cada eixo, tanto do acelerômetro quanto do giroscópio, são lidos e apresentados no terminal serial de forma simples, ou seja, sem nenhum tratamento. Confira a listagem do programa, baseado no exemplo disponível no site do Arduino:
#include<Wire.h> //Endereco I2C do MPU6050 const int MPU=0x68; //pino aberto 0X68 , pino ligado em 3,3V 0x69 //Variaveis globais int acelX,acelY,acelZ,temperatura,giroX,giroY,giroZ; //configurações iniciais void setup() { Serial.begin(9600); //inicia a comunicação serial Wire.begin(); //inicia I2C Wire.beginTransmission(MPU); //Inicia transmissão para o endereço do MPU Wire.write(0x6B); //Inicializa o MPU-6050 Wire.write(0); Wire.endTransmission(true); } //loop principal void loop() { Wire.beginTransmission(MPU); //transmite Wire.write(0x3B); // Endereço 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); //Finaliza transmissão Wire.requestFrom(MPU,14,true); //requisita bytes //Armazena o valor dos sensores nas variaveis correspondentes acelX=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) acelY=Wire.read()<<8|Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) acelZ=Wire.read()<<8|Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) temperatura=Wire.read()<<8|Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) giroX=Wire.read()<<8|Wire.read(); //0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) giroY=Wire.read()<<8|Wire.read(); //0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) giroZ=Wire.read()<<8|Wire.read(); //0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) //Envia valores lidos do acelerômetro Serial.print("Acel:"); Serial.print(" X:");Serial.print(acelX); Serial.print("\tY:");Serial.print(acelY); Serial.print("\tZ:");Serial.print(acelZ); //Envia valores lidos do giroscópio Serial.print("\tGiro:"); Serial.print(" X:");Serial.print(giroX); Serial.print("\tY:");Serial.print(giroY); Serial.print("\tZ:");Serial.print(giroZ); //Envia valor da temperatura em graus Celsius Serial.print("\tTemperatura: "); Serial.println(temperatura/340.00+36.53); //Aguarda 500 ms delay(500); }
const int MPU=0x68; //pino aberto 0X68 , pino ligado em 3,3V 0x69
int acelX,acelY,acelZ,temperatura,giroX,giroY,giroZ;
Wire.begin(); //inicia I2C
Wire.beginTransmission(MPU); //Inicia transmissão para o endereço do MPU
Wire.beginTransmission(MPU); //transmite
Wire.write(0x3B); // Endereço 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false); //Finaliza transmissão
Wire.requestFrom(MPU,14,true); //requisita bytes
acelX=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
acelY=Wire.read()<<8|Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
acelZ=Wire.read()<<8|Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
temperatura=Wire.read()<<8|Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
giroX=Wire.read()<<8|Wire.read(); //0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
giroY=Wire.read()<<8|Wire.read(); //0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
giroZ=Wire.read()<<8|Wire.read(); //0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
//Envia valores lidos do acelerômetro
Serial.print("Acel:");
Serial.print(" X:");Serial.print(acelX);
Serial.print("\tY:");Serial.print(acelY);
Serial.print("\tZ:");Serial.print(acelZ);
//Envia valores lidos do giroscópio
Serial.print("\tGiro:");
Serial.print(" X:");Serial.print(giroX);
Serial.print("\tY:");Serial.print(giroY);
Serial.print("\tZ:");Serial.print(giroZ);
//Envia valor da temperatura em graus Celsius
Serial.print("\tTemperatura: "); Serial.println(temperatura/340.00+36.53);
//Aguarda 500 ms
O resultado é apresentado na Figura 4. São exibidos os valores em sequência onde fica fácil perceber a variação dos eixos conforme o movimento.
Figura 4 – Valores lidos
Neste artigo foi apresentado como interfacear o módulo GY-521 baseado no MPU-6050, uma ótima opção para aplicações com acelerômetro e giroscópio, com Arduino. Foram apresentados suas características e recursos, além de um exemplo de interface com Arduino. Este artigo servirá como base para projetos e aplicação utilizando sensores do tipo MEMS em conjunto com a plataforma Arduino.
MPU-6050 Blog Arduino
AnteriorAnteriorIntel Curie
PróximoLightBlue Bean – Placa compatível com ArduinoPróximo
Fernando Avelino Ferreira
Uma duvida li no datasheet dele que a precisão seria para X,Y,Z = 2g,4g,8g porém não estou conseguindo entender/ converter esses números para graus para saber a precisão do sensor na medição de angulos em x,y,z estou orecisando fazer uma aplicação no qual eu precise de uma resolução de 0,05°.
Olá, tudo bem Fábio? Cara ficaria muito feliz se conseguisse compartilhar essa biblioteca com o bloco eletrônico do Giroscópio para o Proteus. Será que é possível? Agradeço desde já = ' ]
Olá Fábio! Gostaria de saber se esses valores de aceleração da gravidade nos três eixos X, Y e Z, os que aparecem no monitor serial, já estão convertidos em g [gravidade m/s²]. Caso não esteja, como faço para obter esses valores em g?
Advocir
se eu quiser colocar uma tela para não ter que usar um computador como ficaria?
Reply to Advocir
Ficaria ótimo! Você pode colocar um display oled, ou nokia. Olha esses exemplos:
https://cyaninfinite.com/mpu6050-and-3d-cube/
https://youtu.be/Rm9SUCM59ko
https://youtu.be/0vOSOYBYR2M
Olá, os dados mostrados no serial print do arduino já estão nas suas unidades corretas? Em graus para o giro e em g para o acelerômetro?
Olá! Esse sensor consegue medir até quantos g?? Não consegui achar no data sheet. Preciso de uma aplicação que meça até uns 2000g… Ou teria outro sensor mais amplo? E a taxa de amostragem? é 2000Hz??
Olá Augusto, segue o datasheet do fabricante: https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf
Sugiro você buscar o device que melhor te atende nos fabricantes, exemplo:
https://www.nxp.com/products/sensors/motion-sensors:MOTION-SENSORS
http://www.st.com/en/mems-and-sensors/accelerometers.html?querycriteria=productId=SC444
Você consegue filtra pelas características desejadas.
Se precisar de ajuda, me fala.
Estou participando de um projeto onde vamos utilizar um MPU-6050 para analise de aceleração, porem não consegui encontrar um código que converta a leitura em g (m/s^2), pelo que entendi a saída do Wire é somente os dados brutos.
o sensor pode ser utilizado sem a ligação com o arduíno?
gostaria de utilizar o giroscópio acelerômetro em um projeto porém, sem a interferência de cabos de conexão com outra placa. Seria possível?
Reply to Ariadne Soares
É necessário um circuito para comunicação com o sensor. Você pode fazer uma aplicação que envie dados via comunicação sem fio, usando um microcontrolador e circuito de rádio na aplicação.
Seria possível adaptar um giroscópio deste a um Arduíno, e entrando fazer com que este comunique com um smartphone via USB? Seria uma boa ideia para celulares dos quais não possuem giroscópio, 😉