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

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

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!

Componentes Eletronicos

Conceitos Básicos sobre Solda Eletrônica

Eletrogate26 de janeiro de 2023

Este post aborda os tipos de ferro de solda, tipos de solda, acessórios para o processo e procedimentos para manutenção do ferro de solda.

Componentes Eletronicos

Conceitos Básicos sobre Solda Eletrônica

Eletrogate26 de janeiro de 2023

Este post aborda os tipos de ferro de solda, tipos de solda, acessórios para o processo e procedimentos para manutenção do ferro de solda.

Sensores

MPU6050 com BluePill e STM32CubeIDE

Eletrogate19 de janeiro de 2023

Neste post, veremos como medir aceleração e velocidade angular utilizando o MPU6050 junto de uma BluePill programada pelo STM32CubeIDE.

Sensores

MPU6050 com BluePill e STM32CubeIDE

Eletrogate19 de janeiro de 2023

Neste post, veremos como medir aceleração e velocidade angular utilizando o MPU6050 junto de uma BluePill programada pelo STM32CubeIDE.

Robótica

Controle de Corrente em Servomotores

Eletrogate12 de janeiro de 2023

Este post trata acerca de um simples sistema que visa ajustar o período do pulso de controle de um servomotor evitando que este permaneça em um estado de alto consumo de corrente.

Robótica

Controle de Corrente em Servomotores

Eletrogate12 de janeiro de 2023

Este post trata acerca de um simples sistema que visa ajustar o período do pulso de controle de um servomotor evitando que este permaneça em um estado de alto consumo de corrente.

Tipos de Arduino

BluePill com STM32CubeIDE

Eletrogate6 de janeiro de 2023 Atualizado em: 09 jan 2023

Neste post, desenvolveremos, utilizando recursos do STM32CubeIDE, um simples piscaLED para a placa BluePill.

Tipos de Arduino

BluePill com STM32CubeIDE

Eletrogate6 de janeiro de 2023 Atualizado em: 09 jan 2023

Neste post, desenvolveremos, utilizando recursos do STM32CubeIDE, um simples piscaLED para a placa BluePill.

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.