Monitoramento de Temperatura e Umidade com DHT11 e Franzininho C0 e Exibição em Display OLED

Este post faz parte da série Franzininho C0 com STM32CubeIDE

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

ComponentesPinos
DisplaySDA: C14SCL:  B6GNDVCC
DHT11Sinal (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.

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 

  1. Abra STM32Cube , crie um novo projeto e selecione o microcontrolador de destino “STM32C011F6P6”. 
  1. 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.
  1. 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.
  1. 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. 
  1. 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. 
  1. Por fim, gere o código em “Project” > “Generate Code”.

Implementação do código

  1. 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.
  1. Após baixar os arquivos os inclua em seu projeto:
  1. Abra o arquivo main.c
  1. Inclua as seguintes bibliotecas:
#include "stdio.h"
#include "string.h"
#include "ssd1306.h"
#include "ssd1306_fonts.h"
  1. Crie as variáveis para guardar os valores de temperatura e umidade:
uint16_t temperatura, umidade;
  1. Crie a função para leitura do DHT11:
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.
  1. Crie a função para exibição no display:
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();
}
  1. Modifique a função principal int main:
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.

Franzininho C0 com STM32CubeIDE

Configuração da Interface I2C na Franzininho C0 para Utilização de Display OLED Controle de LED com Botão usando Azure RTOS na Franzininho C0
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
0 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Home » Hardware » Microcontroladores » Monitoramento de Temperatura e Umidade com DHT11 e Franzininho C0 e Exibição em Display OLED

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: