Í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
Este artigo aborda o monitoramento de temperatura e umidade utilizando o sensor DHT11 e a placa Franzininho C0, com a exibição dos valores obtidos em um display OLED. Vamos realizar a configuração inicial da Franzininho C0 com a ferramenta CubeMX e depois adaptar o código conforme necessário.
Componentes necessários
- 1 Franzininho C0
- 1 Módulo DHT11
- 1 Display OLED ssd1306
Esquemático para montagem circuito
Componentes | Pinos |
Display | SDA: C14SCL: B6GNDVCC |
DHT11 | Sinal (s): A4GNDVCC |
Funcionamento DHT11
Processo de Comunicação:
Quando o MCU envia um sinal de início, o DHT11 muda do modo de baixo consumo de energia para o modo de operação, aguardando que o MCU complete o sinal de início. Uma vez concluído, o DHT11 envia um sinal de resposta com 40 bits de dados que incluem as informações de umidade relativa e temperatura para o MCU.
Sinal de Início para o DHT:
Normalmente, o barramento de dados está em um nível de tensão alta. Quando o MCU começa a se comunicar com o DHT11, ele baixa essa tensão de alta para baixa e mantém assim por pelo menos 18ms. Isso garante que o DHT11 detecte o sinal do MCU. Depois disso, o MCU aumenta novamente a tensão e espera entre 20 a 40μs para receber a resposta do DHT11.
Resposta do DHT ao MCU:
Assim que o DHT detecta o sinal de início, ele envia um sinal de resposta de baixo nível de tensão, que dura 80μs. Em seguida, o DHT muda a tensão do barramento de dados de baixo para alto e mantém assim por 80μs para se preparar para enviar os dados.
Embarcados Experience 2024: Evento Presencial
Participe do Embarcados Experience 2024 em São Paulo. Conhecimento técnico, palestras, workshops e oportunidade de networking com profissionais experientes.
Durante a transmissão de dados do DHT para o MCU, cada bit de dados começa com um nível de baixa tensão de 50μs, e a duração do sinal de alta tensão seguinte determina se o bit de dados é “0” ou “1”.
Formato dos dados:
8 bits de dados integrais de umidade relativa (RH) + 8 bits de dados decimais de umidade relativa (RH) + 8 bits de dados integrais de temperatura (T) + 8 bits de dados decimais de temperatura (T) + 8 bits de soma de verificação (check-sum).
Para mais informações acesse o datasheet: https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
Configuração CubeMX
- Abra STM32Cube , crie um novo projeto e selecione o microcontrolador de destino “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. Pressione a tecla “Enter” e deixe o aplicativo resolver os divisores/multiplicadores PLL necessários para atingir a taxa de clock desejada. Depois volte para a página de configuração dos pinos, selecione “Trace and Debug” e habilite “Serial Wire.
- Configure a interface I2C. Selecione o pino C14 como SDA e o pino PB6 como SCL. Clique em “Connectivity” > I2C1 e habilite o I2C. As demais configurações, para esse exemplo, podemos deixar padrão.
- Selecione o pino PA4 como saída, ajuste o output level como “high”, o mode como “output push pull” e o speed como “very high”. Também renomeie o nome do pino como dht.
- Em seguida, vamos configurar o TIM3 com um tempo de 1us. Para isso, selecione o Clock Source como “Internal Clock” e o Preescaler como 48-1, de forma que a frequência passe a ser 1Mhz.
- Por fim, gere o código em “Project” > “Generate Code”.
Implementação do código
- Para começar, faça o download dos arquivos da biblioteca para o display OLED. Está disponível em: Repositório da biblioteca OLED para Franzininho C0.
- Após baixar os arquivos os inclua em seu projeto:
- Abra o arquivo main.c
- Inclua as seguintes bibliotecas:
1 2 3 4 |
#include "stdio.h" #include "string.h" #include "ssd1306.h" #include "ssd1306_fonts.h" |
- Crie as variáveis para guardar os valores de temperatura e umidade:
1 |
uint16_t temperatura, umidade; |
- Crie a função para leitura do DHT11:
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
void dht11(uint16_t *temperatura, uint16_t *umidade) { //Variáveis para execução de cálculos da função. uint16_t tempcalc, umidcalc; //Configurações para seleção da direção do Pino 'dht11' como saída digital: GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = dht_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(dht_GPIO_Port, &GPIO_InitStruct); //Sinal em nivel lógico 0 - Conforme Datasheet. HAL_GPIO_WritePin(dht_GPIO_Port, dht_Pin, GPIO_PIN_RESET); //Tempo mínimo de 18ms - Conforme Datasheet. HAL_Delay(20); //Configura para 20ms //Sinal em nivel lógico 1 - Conforme Datasheet. HAL_GPIO_WritePin(dht_GPIO_Port, dht_Pin, GPIO_PIN_SET); //Configurações para seleção da direção do Pino 'dht11' como entrada digital: GPIO_InitStruct.Pin = dht_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(dht_GPIO_Port, &GPIO_InitStruct); //Lógica Principal: //Seta contador Timer 3 para 0. __HAL_TIM_SET_COUNTER(&htim3, 0); //Variáveis Auxiliares. uint16_t ler[2]; uint16_t dados[42]; uint8_t bits[40]; uint16_t temph = 0; uint16_t umidh = 0; //Lógica Para Captura do Tempo Alto dos Dados. for(int i = 0; i < 42; i++) { while(HAL_GPIO_ReadPin(dht_GPIO_Port, dht_Pin) == GPIO_PIN_RESET); ler[0] = __HAL_TIM_GET_COUNTER(&htim3); while(HAL_GPIO_ReadPin(dht_GPIO_Port, dht_Pin) == GPIO_PIN_SET); ler[1] = __HAL_TIM_GET_COUNTER(&htim3); dados[i] = ler[1] - ler[0]; } //Definindo bits conforme tempos do datasheet. for(int i = 0; i < 40; i++) { if((dados[i+2] >=20) && (dados[i+2] <=32)) { bits[i] = 0; } else if((dados[i+2] >=65) && (dados[i+2] <=75)) { bits[i] = 1; } } //Cálculo da temperatura e umidade determinado pelos bits. for(int i = 0; i < 8; i++) { temph += bits[i+16] << (7 - i); umidh += bits[i] << (7 - i); } //Atribuição dos valores calculados nas variáveis tempcalc = temph; umidcalc = umidh; *temperatura = tempcalc; *umidade = umidcalc; } |
Essa função realiza a leitura de temperatura e umidade a partir de um sensor DHT11 seguindo o que foi indicado no funcionamento do sensor descrito no artigo:
- Configuração inicial: Define o pino do sensor DHT11 como saída, envia um sinal de baixo por 20ms e então muda o pino para entrada.
- Leitura dos dados: Utiliza um timer (TIM3) para medir tempos entre transições de nível lógico no pino do sensor, capturando os tempos altos dos dados enviados pelo DHT11.
- Decodificação dos dados: Com base nos tempos medidos, determina se cada bit dos dados recebidos é um 0 ou um 1, seguindo os intervalos especificados pelo datasheet do DHT11.
- Cálculo de temperatura e umidade: A partir dos bits recebidos, calcula os valores de temperatura e umidade.
- Retorno dos valores: Armazena os valores calculados nas variáveis temperatura e umidade, que são passadas por referência para a função.
- Crie a função para exibição no display:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void Display_Data(uint16_t *temperatura, uint16_t *umidade) { char temp_str[16]; char hum_str[16]; // Formatando as strings de temperatura e umidade manualmente sprintf(temp_str, "Temp: %dC", (int)*temperatura); sprintf(hum_str, "Umid: %d%%", (int)*umidade); // Limpar o display ssd1306_Fill(Black); // Definir o cursor e escrever a string de temperatura ssd1306_SetCursor(4, 4); ssd1306_WriteString(temp_str, Font_11x18, White); // Definir o cursor e escrever a string de umidade ssd1306_SetCursor(4, 24); ssd1306_WriteString(hum_str, Font_11x18, White); // Atualizar o display ssd1306_UpdateScreen(); } |
- Modifique a função principal int main:
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 33 |
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_I2C1_Init(); MX_TIM3_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_Base_Start(&htim3); //Inicializa Timer 3 -> '1us' ssd1306_Init(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ dht11(&temperatura, &umidade); Display_Data(&temperatura, &umidade); HAL_Delay(5000); // Aguarda 5 segundos antes de fazer uma nova leitura } /* USER CODE END 3 */ } |
No int main, estamos realizando o seguinte:
- Inicialização Geral com HAL_Init() e SystemClock_Config().
- Inicialização dos Periféricos com MX_GPIO_Init(), MX_I2C1_Init(), MX_TIM3_Init().
- Inicializações Específicas com HAL_TIM_Base_Start(&htim3) e ssd1306_Init().
- No Loop Infinito é chamado a função dht11() para ler a temperatura e umidade do sensor e depois é chamado Display_Data() para exibição dos dados de temperatura e umidade no display OLED. É aguardado 5 segundos antes de realizar uma nova leitura.
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
Conclusão
Neste artigo, demonstramos como monitorar temperatura e umidade usando o sensor DHT11 e a placa Franzininho C0, exibindo os valores obtidos em um display OLED. O processo envolveu a configuração do hardware utilizando o STM32CubeMX e a implementação do código necessário para leitura e exibição dos dados.
Através deste projeto, aprendemos a implementar a comunicação com o sensor DHT11, entendendo seu protocolo de transmissão de dados e como decodificar os sinais recebidos e a utilizar um display OLED para exibir as leituras de temperatura e umidade, formatando e atualizando as informações de maneira eficiente.