blog-eletrogate-logo-desktop blog-eletrogate-logo-mobile
  • Categorias
    • Voltar
    • INICIANTES
    • INTERMEDIÁRIOS
    • AVANÇADOS
    • divide
    • Automação Residencial
    • Componentes Eletrônicos
    • Impressão 3D
    • IoT
    • Modelagem 3D
    • Módulos Wifi
    • Por trás da tecnologia
    • Projetos
    • Raspberry Pi
    • Robótica
    • Sensores
    • Shields
    • Sistemas Operacionais
    • Tipos de Arduino
    • Tutoriais
  • Apostilas
  • Quem Somos
  • Seja um redator
  • Trabalhe Conosco
    • Categorias
      • Voltar
      • INICIANTES
      • INTERMEDIÁRIOS
      • AVANÇADOS
      • divide
      • Automação Residencial
      • Componentes Eletrônicos
      • Impressão 3D
      • IoT
      • Modelagem 3D
      • Módulos Wifi
      • Por trás da tecnologia
      • Projetos
      • Raspberry Pi
      • Robótica
      • Sensores
      • Shields
      • Sistemas Operacionais
      • Tipos de Arduino
      • Tutoriais
    • Apostilas
    • Quem Somos
    • Seja um redator
    • Trabalhe Conosco
Loja Eletrogate
voltar
  • Introdução
  • O MPU6050
  • Comunicação
  • O Código
  • Material Necessário para o Projeto MPU6050 com BluePill e STM32CubeIDE
  • Execução
  • Conclusão
  • Referências
  • Sobre o Autor
Sensores

MPU6050 com BluePill e STM32CubeIDE

Eletrogate 19 de janeiro de 2023Atualizado em: 21 mar 2023

Introdução

Muitas das bibliotecas voltadas ao Arduino IDE são portadas para a BluePill, o que é um grande pró à escolha deste como ambiente de trabalho com a placa. O STM32CubeIDE, por outro lado, apesar de não apresentar tantas bibliotecas voltadas a esta placa -nenhuma oficial, inclusive, visto que a placa foi desenvolvida pela comunidade e não integra o portfólio da empresa-, oferece recursos personalizados para seus microcontroladores, o que faz com que o desenvolvimento de projetos neste seja mais dinâmico e aprofundado do que no primeiro. No post BluePill com STM32CubeIDE, aprendemos a desenvolver e carregar programas utilizando este IDE. Neste, exploraremos, um pouco, suas funções voltadas às interfaces USART e IIC.


O MPU6050

Na falta de uma biblioteca dedicada a este módulo, precisaremos compreender, em um nível mais baixo, seu funcionamento. A operação do MPU6050, cujo uso junto ao Arduino IDE é abordado no post Acelerômetros MPU-6050, MMA8452 e MPU-9250, é regida por seus registradores, explicados em https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf. Para nossa aplicação, precisamos nos atentar a poucos. Sobre estes, tratamos abaixo:

  • WHO_AM_I (0x75): identificação do sensor

Registrador para leitura, somente. Armazena o valor padrão 0x68. Pode ser utilizado para verificar se a comunicação foi estabelecida com sucesso.

  • PWR_MGMT_1 (0x6B): gerenciamento de energia
    • Seus bits [7:5] controlam os modos de consumo reduzido. Para operação normal, devem estar desativados.
    • O bit 4 é reservado.
    • Quando o bit 3 está acionado, o sensor de temperatura do módulo é desligado.
    • Os bits [2:0] selecionam a fonte de clock do sensor. Para nossa aplicação, são mantidos desativados.
  • CONFIG (0x1A): configurações gerais
    • Os bits [7:6] são reservados.
    • Os bits [5:3] determinam o registrador em que um sinal externo será armazenado. Em nossa aplicação, devem ser mantidos desativados.
    • Os bits [2:0] selecionam a faixa de corte do filtro passa-baixas do sensor. Optaremos pelo corte em 5 Hz, acionando os pinos [2:1].
  • ACCEL_CONFIG (0x1C): configuração do acelerômetro
    • Os bits [7:5] disparam o autoteste de cada eixo. Não usaremos este recurso.
    • Os bits[4:3] selecionam a escala do acelerômetro. Optaremos pela menor, ± 2 g, em que [g] é a aceleração da gravidade no local. Para isso, estes bits devem ser mantidos desativados.
    • Os bits [2:0] são reservados.
  • GYRO_CONFIG (0x1B): configuração do giroscópio
    • Os bits [7:5] disparam o autoteste de cada eixo. Não usaremos este recurso.
    • Os bits[4:3] selecionam a escala do giroscópio. Optaremos pela menor, ± 250 °/s. Para isso, estes bits devem ser mantidos desativados.
    • Os bits [2:0] são reservados.
  • ACCEL_XOUT_H (0x3B), ACCEL_XOUT_L (0x3C), ACCEL_YOUT_H (0x3D), ACCEL_YOUT_L (0x3E), ACCEL_ZOUT_H (0x3F) e ACCEL_ZOUT_L (0x40)

Cada par sucessivo de registradores compõe o resultado da leitura em um eixo. Assim, a concatenação dos registradores ACCEL_XOUT_H e ACCEL_XOUT_L corresponde à leitura da aceleração no eixo X, ACCEL_YOUT_H e ACCEL_YOUT_L no Y e ACCEL_ZOUT_H e ACCEL_ZOUT_L, no Z.

  • GYRO_XOUT_H (0x43), GYRO_XOUT_L (0x44), GYRO_YOUT_H (0x45), GYRO_YOUT_L (0x46), GYRO_ZOUT_H (0x47) e GYRO_ZOUT_L (0x48)

Cada par sucessivo de registradores compõe o resultado da leitura em um eixo. Assim, a concatenação dos registradores GYRO_XOUT_H e GYRO_XOUT_L corresponde à leitura da velocidade angular no eixo X, GYRO_YOUT_H e GYRO_YOUT_L no Y e GYRO_ZOUT_H e GYRO_ZOUT_L, no Z.


Comunicação

O MPU6050 se comunica por uma interface IIC. Por isso, utilizaremos este periférico da BluePill. O STM32CubeIDE, por meio de sua HAL, sigla para “Hardware Abstraction Layer”, “Camada de Abstração de Hardware”, disponibiliza duas funções voltadas à comunicação, por meio da IIC, com dispositivos regidos por memória:

  • HAL_I2C_Mem_Write(I2C_HandleTypeDef * hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t * pData, uint16_t Size, uint32_t Timeout);
    • I2C_HandleTypeDef * hi2c: ponteiro para a estrutura que armazena as informações sobre a interface;
    • uint16_t DevAddress: endereço do dispositivo com o qual a comunicação será realizada;
    • uint16_t MemAddress: endereço, na memória do dispositivo, em que o primeiro dado será escrito;
    • uint16_t MemAddSize: tamanho, em bytes, de cada célula da memória do dispositivo;
    • uint8_t * pData: ponteiro para, na memória do microcontrolador, os dados a serem enviados para o dispositivo;
    • uint16_t Size: quantidade de dados a serem enviados;
    • uint32_t Timeout: máximo de tempo a ser aguardado pelos sinais de confirmação do dispositivo;

Esta função permite a escrita de dados na memória do dispositivo.

  • HAL_I2C_Mem_Read(I2C_HandleTypeDef * hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t * pData, uint16_t Size, uint32_t Timeout);
    • I2C_HandleTypeDef * hi2c: ponteiro para a estrutura que armazena as informações sobre a interface;
    • uint16_t DevAddress: endereço do dispositivo com o qual a comunicação será realizada;
    • uint16_t MemAddress: endereço, na memória do dispositivo, de onde o primeiro dado será lido;
    • uint16_t MemAddSize: tamanho, em bytes, de cada célula da memória do dispositivo;
    • uint8_t * pData: ponteiro para, na memória do microcontrolador, o endereço em que os dados lidos serão armazenados;
    • uint16_t Size: quantidade de dados a ser lida;
    • uint32_t Timeout: máximo de tempo a ser aguardado pelos sinais de confirmação do dispositivo;

Esta função permite a leitura de dados da memória do dispositivo.

Com estas, será possível realizar toda a comunicação necessária para a configuração e leitura das medições do sensor.


O Código

No código, encontrado em BluePillMPU6050, primeiro, declaramos uma constante com o endereço do sensor, neste módulo, 0xD0: const uint8_t mpu6050Addr = 0xD0;. Abaixo, são definidas as estruturas a armazenar os dados lidos do sensor:

typedef struct leituraAcel {
    int16_t accelX;
    int16_t accelY;
    int16_t accelZ;
} leituraAcel;

typedef struct leituraGyro {
    int16_t gyroX;
    int16_t gyroY;
    int16_t gyroZ;
} leituraGyro;

Cada estrutura armazena, separadamente, o valor correspondente a cada eixo. Então, definimos a primeira função personalizada, void mpu6050Init(void). Esta verifica se a comunicação com o sensor está adequada e, em caso positivo, prossegue com sua configuração. Para configurar o módulo, serão escritos, nos registradores previamente abordados, os valores correspondentes às configurações escolhidas. Como o acesso à memória do dispositivo não pode ser feito bit-a-bit, mas byte-a-byte, devem ser enviados valores que correspondam ao acionamento, somente, dos bits corretos. A tabela abaixo relaciona cada registrador ao estado desejado para seus bits e ao correspondente valor hexadecimal.

Registrador Estado dos Bits Valor Hexadecimal
WHO_AM_I 01101000 68
PWR_MGMT_1 00001000 08
CONFIG 00000110 06
ACCEL_CONFIG 00000000 0
GYRO_CONFIG 00000000 0

O trecho abaixo contém a definição da função.

void mpu6050Init(void) {
    static const uint8_t whoAmIReg = 0x75;
    static const uint8_t pwrMgmt1Reg = 0x6B;
    static const uint8_t configReg = 0x1A;
    static const uint8_t accelConfigReg = 0x1C;
    static const uint8_t gyroConfigReg = 0x1B;
    static unsigned char msgErro[] = "Erro na inicializacao do MPU6050";

    uint8_t check;
    uint8_t data;

    HAL_I2C_Mem_Read(&hi2c1, mpu6050Addr, whoAmIReg, 1, &check, 1, 1000);

    if(check == 0x68) {

        data = 0x08;
        HAL_I2C_Mem_Write(&hi2c1, mpu6050Addr, pwrMgmt1Reg, 1, &data, 1, 1000);

        data = 0x06;
        HAL_I2C_Mem_Write(&hi2c1, mpu6050Addr, configReg, 1, &data, 1, 1000);

        data = 0x00;
        HAL_I2C_Mem_Write(&hi2c1, mpu6050Addr, accelConfigReg, 1, &data, 1, 1000);

        data = 0x00;
        HAL_I2C_Mem_Write(&hi2c1, mpu6050Addr, gyroConfigReg, 1, &data, 1, 1000);
    } else {
        HAL_UART_Transmit(&huart1, msgErro, sizeof(msgErro), 100);
    }
}

A próxima função, void mpu6050ReadAccel(leituraAcel *leitura), lê e armazena as medições do acelerômetro. Para isso, são lidos 6 bytes a partir de accelXoutHReg. Cada par é, então, concatenado e armazenado na componente da estrutura correspondente ao respectivo eixo.

void mpu6050ReadAccel(leituraAcel *leitura) {
    static const uint8_t accelXoutHReg = 0x3B;
    uint8_t recData[6];

    HAL_I2C_Mem_Read(&hi2c1, mpu6050Addr, accelXoutHReg, 1, recData, 6, 1000);

    leitura->accelX = (int16_t) (recData[0] << 8 | recData [1]);
    leitura->accelY = (int16_t) (recData[2] << 8 | recData [3]);
    leitura->accelZ = (int16_t) (recData[4] << 8 | recData [5]);
}

Muito similar, void mpu6050ReadGyro(leituraGyro *leitura) lê e armazena as medições do giroscópio.

void mpu6050ReadGyro(leituraGyro *leitura) {
    static const uint8_t gyroXoutHReg = 0x43;
    uint8_t recData[6];

    HAL_I2C_Mem_Read(&hi2c1, mpu6050Addr, gyroXoutHReg, 1, recData, 6, 1000);

    leitura->gyroX = (int16_t) (recData[0] << 8 | recData [1]);
    leitura->gyroY = (int16_t) (recData[2] << 8 | recData [3]);
    leitura->gyroZ = (int16_t) (recData[4] << 8 | recData [5]);
}

Já na função principal, primeiro, são declarados o buffer para os caracteres da mensagem de saída, que é, também, inicializado como vazio, e as estruturas que receberão as medições.

uint8_t mensagem[128] = {0};
leituraAcel leituraA;
leituraGyro leituraG;

Após, o sensor é inicializado e configurado pela chamada mpu6050Init();. No loop infinito, os dados são lidos e armazenados nas estruturas, convertidos para as unidades de medidas correspondentes e formatados para, por fim, serem enviados pela interface USART.

while(1) {
    mpu6050ReadAccel(&leituraA);
    mpu6050ReadGyro(&leituraG);

    float accelG[3] = {leituraA.accelX / 16384.0, leituraA.accelY / 16384.0, leituraA.accelZ / 16384.0};
    float gyroGpS[3] = {leituraG.gyroX / 131.0, leituraG.gyroY / 131.0, leituraG.gyroZ / 131.0};

  sprintf((char *) mensagem, "a (x, y, z) [g]: %.2f %.2f %.2f | v (x, y, z) [°/s]: %.2f %.2f %.2f\r\n", accelG[0], accelG[1], accelG[2], gyroGpS[0], gyroGpS[1], gyroGpS[2]);
  HAL_UART_Transmit(&huart1, mensagem, sizeof(mensagem), 100);
  HAL_Delay(100);
}

Como o microcontrolador utilizado não possui hardware para aritmética de ponto flutuante, alguns recursos que a usam são, por padrão, desabilitados. Por isso, para formatar a mensagem como no trecho acima, é necessário habilitar a passagem de números em ponto flutuante como parâmetro para a função sprintf. Para isso, acesse Project → Properties → C/C++ Build → Settings → MCU Settings e habilite a caixa de seleção “Use float with printf from newlib-nano (-u _printf_float)”, como mostra a imagem abaixo.

Acesse Project → Properties → C/C++ Build → Settings → MCU Settings e habilite a caixa de seleção "Use float with printf from newlib-nano (-u _printf_float)".

Caminho para habilitar a formatação de números de ponto flutuante


Material Necessário para o Projeto MPU6050 com BluePill e STM32CubeIDE

  • Placa de Desenvolvimento STM32F103C6T6 Arm Stm32
  • Programador ST-LINK V2
  • Acelerômetro e Giroscópio 3 Eixos 6 DOF MPU-6050 – GY-521
  • Módulo Conversor USB para RS232 TTL – FTDI FT232RL
  • Jumpers – Macho/Macho – 40 Unidades de 10cm
  • Protoboard 830 Pontos

cta_cart

Estes são conectados conforme o esquemático abaixo.

O GND de cada dispositivo deve estar conectado ao dos demais. Vcc da BluePill deve estar conectado ao Vcc do MPU. A9 da BluePill, ao RX do conversor serial. B6 e B7 da BluePill, respectivamente, a SCL e SDA do MPU.

Diagrama de conexões


Execução

A demonstração utiliza o terminal serial do próprio IDE e pode ser vista abaixo.

https://blog.eletrogate.com/wp-content/uploads/2023/01/demonstracao.mp4

Conclusão

Em linhas de raciocínio similares, outros sensores podem ser utilizados juntos a esta placa e ao IDE. Além disso, para o MPU6050, as funções deste post podem ser reutilizadas.


Referências

  • https://controllerstech.com/how-to-interface-mpu6050-gy-521-with-stm32/;
  • https://microcontrollerslab.com/stm32-blue-pill-uart-tutorial-polling-method/

Sobre o Autor


Eduardo Henrique
LinkedIn

Formado técnico em mecatrônica no CEFET-MG, atualmente estuda Engenharia de Controle e Automação na UFMG. É apaixonado por eletrônica, controle, arte e, principalmente, por sua companheira, Beatriz.


Eletrogate

19 de janeiro de 2023 Atualizado em: 21 mar 2023

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!

Sensores

Guia de Uso do Sensor de Chama com Arduino

Eletrogate1 de junho de 2023

Aprenda a usar o Sensor Infravermelho de Chama e Fogo com a placa Arduino Leonardo R3 para dar mais segurança a seus projetos.

Sensores

Guia de Uso do Sensor de Chama com Arduino

Eletrogate1 de junho de 2023

Aprenda a usar o Sensor Infravermelho de Chama e Fogo com a placa Arduino Leonardo R3 para dar mais segurança a seus projetos.

Automação Residencial

Controle de Luminosidade com LDR sem Arduino

Eletrogate25 de maio de 2023

Podemos usar um sensor LDR junto com uma placa Arduino para interpretar a variação luminosa. Mas, também podemos usar poucos componentes eletrônicos para fazer isso, sem programação.

Automação Residencial

Controle de Luminosidade com LDR sem Arduino

Eletrogate25 de maio de 2023

Podemos usar um sensor LDR junto com uma placa Arduino para interpretar a variação luminosa. Mas, também podemos usar poucos componentes eletrônicos para fazer isso, sem programação.

Módulos Wifi

Deauther com NodeMCU ESP-12E

Eletrogate18 de maio de 2023 Atualizado em: 29 maio 2023

No post de hoje, iremos aprender a fazer um deauther com o esp8266. Venha conferir!

Módulos Wifi

Deauther com NodeMCU ESP-12E

Eletrogate18 de maio de 2023 Atualizado em: 29 maio 2023

No post de hoje, iremos aprender a fazer um deauther com o esp8266. Venha conferir!

Componentes Eletronicos

Conhecendo a Pastilha Piezoelétrica

Eletrogate11 de maio de 2023

Como converter energia mecânica em energia elétrica e ainda usar o Arduino para gerenciar isso tudo.

Componentes Eletronicos

Conhecendo a Pastilha Piezoelétrica

Eletrogate11 de maio de 2023

Como converter energia mecânica em energia elétrica e ainda usar o Arduino para gerenciar isso tudo.

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!

blog-eletrogate-logo-footer

Rua Rio de Janeiro, 441 - Sala 1301
Centro - Belo Horizonte/MG
CEP 30160-041
*Não temos atendimento físico

ANWAR SLEIMAN HACHOUCHE - ME
CNPJ: 18.917.521/0001-73

Atendimento

(31) 3142-3800

contato@eletrogate.com


Seg a Sex - das 8h às 17h

Institucional

  • Apostilas
  • Quem Somos
  • Privacidade
  • Seja um Redator
  • Trabalhe Conosco

Nos acompanhe

Facebook Instagram Youtube

© ELETROGATE 2023 - Todos os direitos reservados. Termos de uso e Política de privacidade.