MPU6050 com ESP8266 (GY-521)

Atualmente estou em um projeto que envolve o ESP8266 com um giroscópio MPU6050, então aproveitei pra escrever um tutorial a respeito, mas o que vou fazer é bastante básico, portanto não pretendo abordar aqui todos os recursos disponíveis nesse módulo GY-521.

MPU6050 (GY-521)

O módulo pode ser adquirido a um bom preço nesse link da Auto Core Robótica. Ele opera entre 3V3 e 5V, por isso é fácil utilizá-lo junto a qualquer MCU/CPU que tenha suporte a I²C. O que ocasionalmente ocorre é uma diferença no regulador de tensão da board, que pode não permitir operar em 3V3, por isso você deve estar atento a esse detalhe quando for comprar seu módulo por aí, caso não queira pegar na Auto Core.

Já escrevi um artigo sobre ele, onde o utilizei para fazer um robô de auto-balanço utilizando um controlador PID que eu mesmo escrevi. Se quiser dar uma olhada no artigo clicando aqui.

Primeiro passo – identifique as coordenadas

É fundamental posicionar os eixos X,Y e Z adequadamente para que você possa pegar o deslocamento correto nos eixos. Para isso, olhe sobre o CI dessa board e procure o ponto, que deverá estar em um dos cantos. A partir daí, o posicionamento é esse:

Identificação dos eixos
Identificação dos eixos

Tudo o que se precisa saber está no datasheet





Não encontrei bibliotecas para Arduino, mas de qualquer modo eu preferi escrever o código para utilizar no ESP8266, portanto não sei se alguma dessas bibliotecas funcionaria no ESP8266, ainda mais porque utilizo meu próprio firmware com Sming. Isso não quer dizer que você não pode utilizar o meu código na IDE do Arduino, uma vez que ele é totalmente genérico.

Caso deseje dar uma olhadela no datasheet, esse é o link.

Você precisará do mapa de registradores também, que você encontra aqui.

Codificando

A primeira coisa a fazer é estabelecer uma conexão I²C com o dispositivo. Previamente, é necessário saber o endereço padrão; 0x68 com o pino AD0 desconectado e 0x69 com o pino AD0 conectado à 3v3. Sabendo disso podemos iniciar nosso código.

Não há necessidade de includes, uma vez que a biblioteca Wire do Sming é global e por acaso, extremamente semelhante (ou idêntica) à biblioteca Wire do Arduino.

Se você não é familizarizado com o barramento I²C, não se preocupe. Trata-se de uma comunicação serial também, só que obedece a um determinado protocolo. O I²C utiliza-se de 2 pinos da MCU/CPU, sendo SCL e SDA. Para facilitar, decore da seguinte maneira; tire o “S” da frente e você tem as iniciais de CLock e DAta.

Se você tentar utilizar o barramento sem inicializá-lo, terá problemas, portanto esse é o primeiro passo; inicializar o barramento I²C fazendo uso da biblioteca Wire. Nessa inicialização você pode especificar quais pinos utilizar para SDA e SCL, sendo o default 0 e 2 para SCL e SDA, respectivamente.

Antes de dar sequência à leitura dos dados do MPU6050, é fundamental que você saiba utilizar o barramento I²C para ler e escrever, por isso vou introduzir a utilização da biblioteca Wire e em seguida iniciaremos a manipulação dos dados do nosso módulo.

Ler e escrever no barramento I²C

Isso é tudo o que você quererá fazer; ler e escrever no barramento. Basicamente, há uma regra a seguir:

Essa é a regra; após inicializar o barramento, inicializa a transmissão, faz a requisição, lê os dados requeridos e finaliza a transmissão. Simples assim.

Quando se tratar de um dispositivo I²C sem registradores como por exemplo, o PCF8574, pode-se fazer da seguinte maneira:

Dispositivos que possuem registradores (como o MPU6050) necessitam de indicação do endereço do registrador a ser lido. Isso veremos de agora em diante nesse artigo.

Ler registrador do MPU6050

Não dá pra adivinhar o que deve ser lido em nenhum desses dispositivos com registradores. Para utilizá-los da maneira mais simples, você precisa de uma biblioteca pronta, mas nem sempre você encontrará bibliotecas prontas, pois isso depende da MCU/CPU e no caso do ESP8266, depende também do firmware que estiver sendo utilizado. Como no artigo de hoje estou utilizando o Sming como framework C++ para programar o ESP e consequentemente estou utilizando meu próprio firmware, preferi não utilizar uma biblioteca de Arduino (sim, elas são compatíveis com Sming). Mas sim, você pode utilizar, deve ser compatível, se houver alguma. Isso porque a biblioteca Wire me parece ter um funcionamento muito parecido e isso é tudo o que você precisa para fazer a comunicação I²C.

No datasheet está disposta a seguinte informação sobre a leitura do MPU6050:

leitura do registrador do MPU6050
leitura do registrador do MPU6050

Na tabela ao final da imagem, estão as descrições de cada um dos comandos na seqüência de leitura, mas isso não é o suficiente para saber o que fazer. O documento supracitado (relacionado ao mapa de registradores) é fundamental para saber o que fazer. Vou citar as partes que considero importantes.

PWR_MGMT_1

Esse é o registrador 107, ou 0x6B em hexadecimal. Os registradores do MPU6050 tem 8 bits e esse registrador em específico controla o comportamento do MPU6050. Os bits relacionados são:

Registrador de gerenciamento de energia
Registrador de gerenciamento de energia

Não é fundamental que você saiba interpretar datasheet, uma vez que terá o código disponível aqui, mas apenas para efeito de informação, lemos o registrador da direita para a esquerda, pois trata-se de binário.

Como você pode ver, os valores do registrador estão dispostos em hexadecimal e em decimal e você pode utilizar qualquer uma das bases para escrever para o dispositivo. Anota-se então o registrador e inicia-se a configuração dos bits. Mas esse registrador é fácil demais para configurar, considerando que você quererá mantê-lo permanentemente ligado. Para tal, todos os bits devem ser configurados para o valor 0. Se por acaso você quisesse desabilitar o sensor de temperatura, bastaria ajustar o respectivo bit para 1.Os primeiros 3 bits são relacionados ao clock do dispositivo e deixando esses 3 bits em 0, ele utiliza o oscilador interno de 8MHz.




O bit seguinte é o sensor de temperatura, que para ser desligado receberia o bit 1. Até aqui você tem o valor 0b1000, que representa 8 em hexa ou em decimal. O próximo bit é o ciclo, utilizado quando você quer fazer wake up e sleep continuamente, com leituras dentro de uma certa freqüência. O próximo bit é o sleep, que para manter o dispositivo ligado continuamente deve ser configurado para 0. Para o caso do uso cíclico, ajustado para 1. O último bit é o reset, que devolve todos os valores padrão para os registradores internos, de modo que devemos então deixá-lo em 0. Se fosse utlilizar o modo cíclico, o registrador 108 também precisaria ser configurado. É um pouquinho de trabalho, mas é só seguir as especificações do mapa de registradores e tudo acaba bem. No nosso caso, queremos apenas que o dispositivo envie suas informações, sem nos preocuparmos com a questão de gerenciamento de energia,por isso configuramos todos os bits para 0. A configuração inicial do MPU6050 fica assim:

Essa inicialização do dispositivo é fundamental porque ele inicia em sleep.

Validar o dispositivo no barramento é uma boa opção para debugging, mas só nesse primeiro momento. Eu mantenho o código normalmente, porque fica fácil saber assim se o dispositivo não está mais respondendo no barramento e desse modo considerar que seja um mal contato, por exemplo.

Como você pode reparar, a função endTransmission(bool) retorna o sucesso ou falha da finalização da comunicação. Sendo diferente de 0, o dispositivo não está presente. E esse recurso é interessante, porque dá pra fazer um scanner de barramento para dispositivos I²C que você não saiba qual é o endereço. Claro, eu fiz, não resisti:

Você pode ter até 126 dispositivos no mesmo barramento (2 MPU6050 no máximo). Supondo que você esteja utilizando apenas 1 dispositivo I²C e quer descobrir o endereço, basta rodar esse scan e ele retornará assim que o dispositivo for encontrado. Ou 0 se não for.

Contratempos e esquisitíces

Eu sugiro que você dê uma pesquisada no google e procure mais códigos de exemplo. Eu procurei um código pra me basear, encontrei alguns (uns, cópias de outros), mas nenhum deles funcionou pra mim. Não é possível que não funcionem em algum caso, pois tem até print da tela de leitura, mas sério, não funcionou pra mim. O que fiz no final foi realmente ler o datasheet de especificações do produto e o datasheet do mapa de registradores, então implementei tudo do zero. Ainda assim tive problemas, porque o dispositivo estava dormindo mesmo após enviar o byte zerado para o registrador de gerenciamento de energia, logo, eu posso ter me equivocado e meu código não está bonito, mas funciona! Também postei a situação anterior na wiki do Sming, mas nesse meio tempo consegui fazer funcionar com uma coisa que considero gambiarra, que é pedir pro dispositivo enviar o WHO_I_AM a cada chamada. Pra concluir a ideia, me ocorreu que um reset em todos os registradores tenha me auxiliado na reconfiguração do dispositivo, porque o comportamento dele se altera conforme a ordem que você configura os bits. Mas isso vou testar em outro módulo igual que tenho aqui e cito em outra oportunidade.

Em relação às esquisitices, bem, se você reparar no código, estou pegando um valor a cada 5 segundos e esse tempo vai aumentar no meu projeto (que não posso contar o que é). Nunca antes eu havia pensado em utilizar um dispositivo de tempo real para fazer leitura periódica, mas isso se dá pelo fato da estatística envolvida no meu projeto, cujos valores serão utilizados no modo raw. Não repare, é pra ser maluco mesmo. Além disso, note que ajustei a precisão do dado raw, porque isso é tudo o que preciso. Com certeza esse é outro comportamento atípico. O resultado dessa fase inicial (que ainda é depuração) é esse:

Leitura advinda do MPU6050
Leitura advinda do MPU6050

E o código para obter o resultado exibido é esse:

O código não está organizado, mas fica por sua conta. Eu já comecei arrumar o meu aqui, divirta-se também!

Vá até o final da página e veja se os artigos relacionados lhe interessam.

Inscreva-se no nosso newsletter, alí em cima à direita e receba novos posts por email.

Siga-nos no Do bit Ao Byte no Facebook.

Prefere twitter? @DobitAoByte.

Inscreva-se no nosso canal Do bit Ao Byte Brasil no YouTube.

Nossos grupos:

Arduino BR – https://www.facebook.com/groups/microcontroladorarduinobr/
Raspberry Pi BR – https://www.facebook.com/groups/raspberrybr/
Orange Pi BR – https://www.facebook.com/groups/OrangePiBR/
Odroid BR – https://www.facebook.com/groups/odroidBR/
Sistemas Embarcados BR – https://www.facebook.com/groups/SistemasEmbarcadosBR/
MIPS BR – https://www.facebook.com/groups/MIPSBR/
Do bit Ao Byte – https://www.facebook.com/groups/dobitaobyte/

Projetos Arduino e Eletrônica – https://www.facebook.com/groups/projetosarduinoeletronica/

ESP8266 BR – https://www.facebook.com/groups/ESP8266BR/

Próximo post a caminho!

Comments

comments

Djames Suhanko

Djames Suhanko é Perito Forense Digital. Já atuou com deployer em sistemas de missão critica em diversos países pelo mundão. Programador Shell, Python, C, C++ e Qt, tendo contato com embarcados ( ora profissionalmente, ora por lazer ) desde 2009.