ÍNDICE DE CONTEÚDO
- Como instalar o STM32CubeIDE: Guia de Primeiros Passos
- Franzininho C0: Entradas e Saídas no STMcubeIDE
- Franzininho C0: aprenda a trabalhar com Timers
- Aprendendo a trabalhar com interrupções externas e USART na Franzininho C0
- Medindo Intervalos de Tempo com a Franzininho C0: Integrando Timer, Interrupções e USART
- Como gravar a Franzininho C0 via USB/Serial usando o STM32CubeProgrammer
- Como usar display 7 segmentos com a Franzininho C0
- Trabalhando com ADC no Franzininho C0: Tutorial Completo no STM32CubeIDE
- Entendendo o Controle PWM e Aplicando no Franzininho C0
- Projeto Prático: Utilizando o Módulo GPS GY-NEO6MV2 com a Franzininho C0
- Projeto Iluminação Automatizada com LDR e Franzininho C0
- Trabalhando com o sensor de temperatura interno da Franzininho C0
- Como Utilizar o RTC (Relógio de Tempo Real) da Franzininho C0 para Capturar Data e Hora
- Configuração da Interface I2C na Franzininho C0 para Utilização de Display OLED
- Monitoramento de Temperatura e Umidade com DHT11 e Franzininho C0 e Exibição em Display OLED
- Controle de LED com Botão usando Azure RTOS na Franzininho C0
- Leitura dos Eixos X, Y e Z do acelerômetro LIS3DH com a Franzininho C0 via SPI
- Medição de ângulo com acelerômetro LIS3DH e Franzininho C0
- Detecção de Queda Livre com acelerômetro LIS3DH e Franzininho C0
Introdução
A identificação de queda livre é uma aplicação frequente em sistemas com acelerômetros, sendo muito utilizada em dispositivos como smartphones, wearables e sistemas de segurança. Essa técnica permite que dispositivos reconheçam quando estão em uma queda, o que pode disparar uma série de ações automáticas, como a ativação de alarmes de emergência ou sistemas de proteção.
Neste terceiro artigo com o acelerômetro LIS3DH, vamos implementar a detecção de queda livre que acionará um LED e exibirá a informação pela Serial.
Circuito:
Configuração CubeMx
- Abra STM32Cube, crie um novo projeto e selecione o microcontrolador “STM32C011F6P6”.
- Vá para a página de configurações de relógio e em HCLK digite 48 MHz para a frequência de saída desejada do sistema. Depois volte para a página de configuração dos pinos, selecione “Trace and Debug” e habilite “Serial Wire.
- Para configurar a UART, selecione o pino PA10 como “USART1_RX” e PA9 como “USART1_TX”. Em “Connectivity” selecione a opção “USART1” e em Mode escolha o “Asynchronous”. As demais configurações deixe padrão.
- Para a configuração do SPI, vá em “Connectivity’ > “SPI”, habilite o modo “FullDuplex Master” e mude o “Clock Parameter” > “Prescaler (Baud Rate)” para 32. Os demais parâmetros de configuração não será necessário modificar.
- O pino de CS é necessário configurar manualmente, então, selecione o PA4 como “GPIO_Output”.
- Configure também o pino PB6 como “GPIO_Output”, nele está conectado o LED.
- Por fim, gere o código em “Project” > “Generate Code”.
Implementação Código
- Crie em “Inc” “lis3dh.h” e em “Src” crie “lis3dh.c”.
- Em lis3dh.h, adicione algumas definições (#define) dos registradores do acelerômetro LIS3DH, assim como os protótipos das funções que serão implementadas em lis3dh.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdint.h> #define LIS3DH_CTRL_REG1 0x20 #define LIS3DH_CTRL_REG3 0x22 #define LIS3DH_CTRL_REG4 0x23 #define LIS3DH_INT1_CFG 0x30 #define LIS3DH_INT1_SRC 0x31 #define LIS3DH_INT1_THS 0x32 #define LIS3DH_INT1_DURATION 0x33 /* Public APIs */ uint8_t LIS3DH_ReadReg(uint8_t address); void LIS3DH_WriteReg(uint8_t address, uint8_t data); void LIS3DH_FreeFallConfig(); void freeFallStatus(); |
- Em li3dh.c, adicione a inclusão das bibliotecas e seguintes variáveis:
1 2 3 4 5 6 |
#include "lis3dh.h" #include "stdio.h" #include "string.h" extern SPI_HandleTypeDef hspi1; extern UART_HandleTypeDef huart1; uint8_t msg[] = "Queda livre detectada! \r\n"; |
- Depois, adicione as funções de leitura e escrita por SPI:
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 |
// Leitura por SPI uint8_t LIS3DH_ReadReg(uint8_t address) { uint8_t txData[2]; uint8_t rxData[2]; txData[0] = address | 0x80 ; // Set read bit (MSB = 1) txData[1] = 0x00; // Dummy byte HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low // delay to ensure CS is correctly registered HAL_Delay(1); if (HAL_SPI_TransmitReceive(&hspi1, txData, rxData, 2, HAL_MAX_DELAY) != HAL_OK) { char error_msg[] = "SPI Transmit/Receive Error\r\n"; HAL_UART_Transmit(&huart1, (uint8_t *)error_msg, strlen(error_msg), 1000); } HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high return rxData[1]; // The second byte received is the actual data } // Escrita por SPI void LIS3DH_WriteReg(uint8_t address, uint8_t data) { uint8_t txData[2]; txData[0] = address; txData[1] = data; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low // delay to ensure CS is correctly registered HAL_Delay(1); if (HAL_SPI_Transmit(&hspi1, txData, 2, HAL_MAX_DELAY) != HAL_OK) { char error_msg[] = "SPI Write Error\r\n"; HAL_UART_Transmit(&huart1, (uint8_t *)error_msg, strlen(error_msg), 1000); } HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high } |
- Em seguida, crie as funções de configuração dos registradores no LIS3DH para trabalhar com identificação de queda livre:
1 2 3 4 5 6 7 8 9 |
// Função para configurar o LIS3DH para detecção de queda livre void LIS3DH_FreeFallConfig(void) { LIS3DH_WriteReg(LIS3DH_CTRL_REG1, 0x97); // CTRL_REG1: Ativar XYZ, 50 Hz ODR LIS3DH_WriteReg(LIS3DH_CTRL_REG4, 0x88); // CTRL_REG4: High resolution, BDU enabled, ±2g LIS3DH_WriteReg(LIS3DH_CTRL_REG3, 0x40); // CTRL_REG3: AOI1 interrupt on INT1 pin LIS3DH_WriteReg(LIS3DH_INT1_CFG, 0x95); // INT1_CFG: 6 direction movement recognition LIS3DH_WriteReg(LIS3DH_INT1_THS, 0x16); // INT1_THS: Threshold = 350 mg LIS3DH_WriteReg(LIS3DH_INT1_DURATION, 0x03); // INT1_DURATION: Minimum event duration = 1/OD } |
- CTRL_REG1: Ative o sensor e defina a taxa de dados (ODR). Por exemplo, para configurar uma taxa de 50Hz com todos os eixos ativos, envie: 0x97 (10010111).
- CTRL_REG3: Configure as interrupções. Para roteá-las para o pino INT1, envie: 0x40 (01000000).
- CTRL_REG4 (0x23): Configure a faixa de medição, se necessário. Para uma faixa de ±2g, por exemplo, envie: 0x88 (10001000).
- INT1_CFG (0x30): Configure o tipo de evento para gerar a interrupção. Para detecção de queda livre, você deve monitorar quando todas as acelerações nos eixos caem abaixo de um determinado limiar. Configure: 0x95 (10010101) para habilitar a interrupção em todos os eixos com “6-direction movement recognition”.
- INT1_THS: Defina o limiar de aceleração para detectar queda livre. Valores baixos, como 0x10 (0010000).
- INT1_DURATION: Defina a duração mínima para considerar como queda livre. Um valor baixo, como 0x03 é suficiente para detectar quedas rápidas.
- Ainda no arquivo li3dh.c, crie a função para identificar queda livre:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Função para verificar o status da interrupção de queda livre void freeFallStatus() { uint8_t int1Src; int1Src = LIS3DH_ReadReg(LIS3DH_INT1_SRC); // Verifica se o bit de queda livre foi ativado if (int1Src & 0x40) { // Verifique se todos os bits XLow, YLow e ZLow estão setados if ((int1Src & 0x01) && (int1Src & 0x04) && (int1Src & 0x10)) { // Queda livre detectada: Todos os eixos estão abaixo do limiar configurado HAL_UART_Transmit(&huart1, msg, (sizeof(msg)-1), 1000); // Transmite mensagem serial pela UART HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6); //muda estado led } } } |
Essa função verifica se houve uma queda livre lendo o registrador de interrupção do acelerômetro. Primeiro, checa se o bit que indica uma interrupção de queda livre está ativado. Se estiver, a função então verifica se os eixos X, Y e Z estão todos abaixo do limite configurado. Se sim, a função aciona envia uma mensagem pela UART e alterna o estado de um LED.
- Veja na imagem abaixo o código do arquivo lis3dh.c
- Depois da finalização do código em lis3dh.c, acesse main.c. Nele incluímos a biblioteca “lis3dh.h” adicionando ao ínicio do código:
1 |
#include "lis3dh.h" |
- Depois modificamos o int main com:
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 |
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI1_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); HAL_Delay(500); LIS3DH_FreeFallConfig(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ freeFallStatus(); } /* USER CODE END 3 */ } |
Nessa etapa, é chamado a configuração do acelerômetro com LIS3DH_FreeFallConfig e depois é lido continuamente o estado com freeFallStatus.
Seminário Linux Embarcado 2024: Evento Presencial em São Paulo
Participe do Seminário Linux Embarcado 2024 em São Paulo. Conhecimento técnico, palestras, workshops e oportunidade de networking com profissionais experientes.
Gravação
Ao finalizar o código, partiremos para gravação. Nessa etapa você pode utilizar o ST-Link seguindo as conexões da imagem abaixo e clicando em “run” no STM32CubeIde.
Ou você pode optar por utilizar um cabo usb e gravar conforme explicado no seguinte tutorial: gravar-franzininho-c0-via-stm32cubeprogrammer
Funcionamento
Para testar o funcionamento simule um queda, como jogar a placa.
Desafio extra
No exemplo deste artigo estamos verificando constantemente o status da queda livre dentro no loop infinito. No entanto, essa não é a melhor abordagem, como desafio, configure um pino na Franzininho C0 para interrupção externa e o conecte no “INT1” do acelerômetro, então chame a verificação do status da queda livre sempre que houver interrupção no pino. Em caso de dúvidas temos um artigo explicando como configurar interrupção externa, acesse: https://embarcados.com.br/aprendendo-a-trabalhar-com-interrupcoes-externas-e-usart-na-franzininho-c0/
Conclusão
Neste artigo, demonstramos como configurar o acelerômetro LIS3DH para detectar quedas livres usando a Franzininho C0. Configuramos os registradores necessários e a implementamos o código para verificar o status de queda, acionando um LED e enviando uma mensagem pela Serial. Essa solução básica permite a identificação de quedas de forma simples e pode ser expandida com o uso de interrupções para otimizar o desempenho do sistema.