Tutoriel Complet - Bibliothèque STM32_DHT
Interface C pour capteurs de température et d'humidité DHT11, DHT22, et DHT21 sur microcontrôleurs STM32
Consultez la librairie sur GitHub.
1. Introduction
La bibliothèque STM32_DHT est une interface C conçue pour faciliter la communication entre les microcontrôleurs STM32 et les capteurs de température et d'humidité de la famille DHT (DHT11, DHT22, DHT21). Cette bibliothèque utilise le framework HAL (Hardware Abstraction Layer) de ST Microelectronics pour assurer la portabilité entre les différentes familles de microcontrôleurs STM32.
2. Compatibilité et Prérequis
Compatibilité Matérielle
- Toutes les familles de microcontrôleurs STM32 supportant HAL et disposant d'un périphérique I2C.
- Capteur DHT11, DHT22 et DHT21.
Prérequis Logiciels
- Un microcontrôleur STM32.
- STM32CubeIDE.
- Le bus I2C sur lequel se troue votre capteur doit être configuré et initialisé dans votre projet.
- La librairie HAL
STM32_DHT
présente dans le répertoire STM32_Libraries.
3. Les Capteurs DHT
Les capteurs DHT sont des capteurs numériques de température et d'humidité abordables et populaires dans les projets électroniques. La bibliothèque supporte trois variantes principales :
Modèle | Plage de Température | Précision Température | Plage d'Humidité | Précision Humidité | Fréquence de Lecture |
---|---|---|---|---|---|
DHT11 | 0 à 50°C | ±2°C | 20 à 80% RH | ±5% RH | 1 Hz (une fois par seconde) |
DHT22 / AM2302 | -40 à 80°C | ±0.5°C | 0 à 100% RH | ±2% RH | 0.5 Hz (une fois toutes les 2 secondes) |
DHT21 / AM2301 | -40 à 80°C | ±0.5°C | 0 à 100% RH | ±2% RH | 0.5 Hz (une fois toutes les 2 secondes) |
4. Principe de Fonctionnement
Les capteurs DHT utilisent un protocole de communication série propriétaire sur un bus à fil unique. Le processus de communication se déroule comme suit :
- Signal de démarrage : Le microcontrôleur envoie un signal bas puis haut pour initier la communication
- Réponse du capteur : Le capteur répond par un signal bas puis haut
- Transfert de données : Le capteur envoie 40 bits (5 octets) de données :
- 8 bits pour la partie entière de l'humidité
- 8 bits pour la partie décimale de l'humidité
- 8 bits pour la partie entière de la température
- 8 bits pour la partie décimale de la température
- 8 bits pour la somme de contrôle (checksum)
La bibliothèque STM32_DHT gère toute cette communication et effectue la conversion des valeurs brutes en données utilisables (température en °C et humidité relative en %).
3. Fichiers de la librairie
STM32_DHT.h
: Fichier d'en-tête contenant les déclarations des fonctions et constantes.STM32_DHT.c
: Fichier source contenant l'implémentation des fonctions.
n'oubliez pas de modifier le fichier STM32_DHT.h
pour
l'adapter à votre configuration matérielle #include "stm32l0xx_hal.h" // Remplacez stm32l0xx_hal.h si vous utilisez une autre série de carte ex : stm32f4xx_hal.h.
5. Installation et Configuration
Pour installer la bibliothèque dans votre projet STM32 :
- Créez un dossier nommé
STM32_DHT
dans le répertoireDrivers
de votre projet STM32 et copiez y les fichiersSTM32_DHT.h
etSTM32_DHT.c
. - Ajoutez les chemins d'inclusion : dans les propriétés de votre projet STM32CubeIDE, dans C/C++ General,
> Paths and Symbols > Onglet Includes, dans GNU ajoutez le chemin vers le dossier
STM32_DHT
.
N'oublier pas d'activer le float dans les propriétés du projet pour afficher le nombres flottants dans le printf.
6. Branchement du Capteur
Brochage des capteurs DHT
Les capteurs DHT ont généralement 3 ou 4 broches :
- VCC : Alimentation (3.3V ou 5V selon le modèle)
- DATA : Signal de données
- GND : Masse
- NC : Non connecté (sur certains modèles à 4 broches)
Connexion au STM32
- VCC → 3.3V (DHT22/21) ou 5V (DHT11)
- DATA → Broche GPIO de votre choix (D2 -> PA10 dans l'exemple)
- GND → GND
Il est recommandé d'ajouter une résistance pull-up de 4.7kΩ à 10kΩ entre VCC et DATA pour stabiliser le signal.

7. Configuration du Timer
La bibliothèque nécessite un timer précis pour mesurer les intervalles de temps du protocole DHT. Voici comment configurer un timer STM32 pour qu'il compte en microsecondes :
Configuration avec STM32CubeMX
- Ouvrez votre projet dans STM32CubeMX
- Activez un timer (par exemple, TIM1)
- Configurez-le comme suit :
- Clock Source: Internal Clock
- Prescaler: (Fréquence d'horloge en MHz - 1)
- Par exemple, si votre horloge système est à 80MHz, utilisez 79
- Counter Period: 0xFFFFFF - 1 (65534)
- Counter Mode: Up
- Générez le code et vérifiez la configuration dans le fichier de configuration du timer
Configuration Manuelle
// Configuration du timer pour compter en microsecondes
htim1.Instance = TIM1;
htim1.Init.Prescaler = 79; // Pour une horloge système de 80MHz
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 0xFFFFFF - 1; // Valeur maximale pour un timer 16 bits
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_Base_Init(&htim1);
Prescaler = (Fréquence d'horloge système en Hz / 1,000,000) - 1Par exemple, pour 80MHz : Prescaler = (80,000,000 / 1,000,000) - 1 = 79
8. Utilisation de la Bibliothèque
8.1 Inclusion de la Bibliothèque
Pour utiliser la bibliothèque, incluez le fichier d'en-tête dans votre programme main.c :
/* USER CODE BEGIN Includes */
#include <stdio.h> // Pour printf
#include "STM32_DHT.h" // Inclure la bibliothèque STM32_DHT
/* USER CODE END Includes */
8.2 Fonctions pour le `prinf` et la gestions des erreurs de la dht.h
Incluez le fichier d'en-tête dans la section USER CODE BEGIN Includes
:
/* USER CODE BEGIN 0 */
/**
* @brief Fonction de sortie pour printf
*
* Cette fonction redirige la sortie de printf vers l'UART2.
* Elle est utilisée pour afficher des messages sur le terminal série.
*
* @param ch Le caractère à envoyer
* @return int Le caractère envoyé
*/
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart2, (uint8_t*) &ch, 1, 0xFFFF); // Pour Envoyer le caractère via UART
// ITM_SendChar(ch); // Option alternative pour envoyer le caractère via ITM
return ch;
}
/* USER CODE END 0 */
8.3 Initialisation
Initialisez le capteur dans la section USER CODE BEGIN 2
:
/* USER CODE BEGIN 2 */
HAL_Delay(250); // Attendre 250ms pour la stabilisation
printf("test STM32_DHT\r\n"); // Affiche un message de test dans la console/
HAL_TIM_Base_Start(&htim2); // Démarrer le timer utilisé pour les délais en microsecondes
DHT_Sensor DHT22sensor; // Déclaration de la structure pour le capteur DHT22
DHT_Init(&DHT22sensor, &htim2, GPIOA, GPIO_PIN_10, DHT22); // Initialise le capteur DHT22 sur GPIOA, PIN 10 avec TIM2
float data[2]; // Tableau pour stocker la température [0] et l'humidité [1]
DHT_GetData(&DHT22sensor, data); // Lance une lecture pour réveiller le capteur
HAL_Delay(100); // Attendre 100ms pour la stabilisation
/* USER CODE END 2 */
8.4 Lecture des Données
Pour lire les données de température et d'humidité dans la section USER CODE BEGIN WHILE
:
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_StatusTypeDef result = DHT_GetData(&DHT22sensor, data); // Lire les données du capteur
if (result == HAL_OK) { // Si ok
printf("Température: %.1f°C, Humidité: %.1f%%\r\n", data[0], data[1]);
} else if (result == HAL_ERROR) { // Si erreur de somme de contrôle ou autre erreur générale
printf("Erreur lors de la lecture du capteur\r\n");
} else if (result == HAL_TIMEOUT) { // Si pas de réponse du capteur ou timeout pendant la communication
printf("Timeout lors de la communication avec le capteur\r\n");
}
HAL_Delay(2000);
/* USER CODE END WHILE */
9. Dépannage
Problèmes Courants et Solutions
Problème | Causes Possibles | Solutions |
---|---|---|
HAL_TIMEOUT lors de la communication |
|
|
HAL_ERROR (erreur de checksum) |
|
|
Valeurs incorrectes ou incohérentes |
|
|
Débogage
Pour faciliter le débogage, vous pouvez ajouter des instructions de trace dans votre code :
/* USER CODE BEGIN WHILE */
while (1)
{
// Exemple de débogage détaillé
HAL_StatusTypeDef result = DHT_GetData(&DHT22sensor, data);
switch (result) {
case HAL_OK:
printf("Lecture réussie - Température: %.1f°C, Humidité: %.1f%%\r\n", data[0], data[1]);
printf("Données brutes - T1: %u, T2: %u, H1: %u, H2: %u, Sum: %u\r\n",
DHT22sensor.temp1, DHT22sensor.temp2, DHT22sensor.hum1, DHT22sensor.hum2, DHT22sensor.SUM);
break;
case HAL_ERROR:
if (DHT22sensor.CHECK != DHT22sensor.SUM) {
printf("Erreur de checksum - Calculé: %u, Reçu: %u\r\n", DHT22sensor.CHECK, DHT22sensor.SUM);
} else {
printf("Erreur générale\r\n");
}
break;
case HAL_TIMEOUT:
printf("Timeout - Pas de réponse du capteur\r\n");
break;
default:
printf("Erreur inconnue\r\n");
break;
}
HAL_Delay(2000);
/* USER CODE END WHILE */
10. Utilisation Avancée
Utilisation de Plusieurs Capteurs
La bibliothèque permet d'utiliser plusieurs capteurs DHT simultanément sur différentes broches GPIO. Voici comment procéder :
/* USER CODE BEGIN 2 */
HAL_Delay(250); // Attendre 250ms pour la stabilisation
printf("test STM32_DHT\r\n"); // Affiche un message de test dans la console
HAL_TIM_Base_Start(&htim2); // Démarrer le timer utilisé pour les délais en microsecondes
DHT_Sensor dht11Sensor; // Déclaration de la structure pour le capteur DHT11
DHT_Sensor dht22Sensor; // Déclaration de la structure pour le capteur DHT22
DHT_Init(&dht11Sensor, &htim2, GPIOB, GPIO_PIN_3, DHT11); // Initialise le capteur DHT11 sur GPIOB, PIN 3 avec TIM2
DHT_Init(&dht22Sensor, &htim2, GPIOA, GPIO_PIN_10, DHT22); // Initialise le capteur DHT22 sur GPIOA, PIN 10 avec TIM2
float dht11Data[2]; // Tableau pour stocker la température [0] et l'humidité [1] de DHT11
float dht22Data[2]; // Tableau pour stocker la température [0] et l'humidité [1] de DHT22
DHT_GetData(&dht11Sensor, dht11Data); // Lance une lecture pour réveiller le capteur DHT11
DHT_GetData(&DHT22sensor, dht22Data); // Lance une lecture pour réveiller le capteur DHT22
HAL_Delay(100); // Attendre 100ms pour la stabilisation
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
// Lecture du premier capteur
if (DHT_GetData(&dht11Sensor, dht11Data) == HAL_OK) {
printf("DHT11 - Temp: %.1f°C, Hum: %.1f%%\r\n", dht11Data[0], dht11Data[1]);
}
HAL_Delay(100); // Petit délai entre les lectures pour éviter les interférences
// Lecture du deuxième capteur
if (DHT_GetData(&dht22Sensor, dht22Data) == HAL_OK) {
printf("DHT22 - Temp: %.1f°C, Hum: %.1f%%\r\n", dht22Data[0], dht22Data[1]);
}
HAL_Delay(2000); // Attendre avant le prochain cycle de lecture
/* USER CODE END WHILE */
Échantillonnage et Moyennage
Pour améliorer la fiabilité des mesures, vous pouvez implémenter un système d'échantillonnage multiple avec moyennage (copier les sections nécessaires dans votre code):
/* USER CODE BEGIN Includes */
#include <stdio.h> // Pour printf
#include "STM32_DHT.h" // Inclure la bibliothèque STM32_DHT
/* USER CODE END Includes */
/* USER CODE BEGIN PTD */
// Structure pour stocker les données moyennées
typedef struct {
float tempSum;
float humSum;
uint8_t sampleCount;
uint8_t maxSamples;
float avgTemp;
float avgHum;
uint32_t lastSampleTime;
} DHT_AveragingData;
// Initialisation de la structure de moyennage
void DHT_InitAveraging(DHT_AveragingData* avgData, uint8_t samples) {
avgData->tempSum = 0.0f;
avgData->humSum = 0.0f;
avgData->sampleCount = 0;
avgData->maxSamples = samples;
avgData->avgTemp = 0.0f;
avgData->avgHum = 0.0f;
avgData->lastSampleTime = 0;
}
/* USER CODE END PTD */
/* USER CODE BEGIN PD */
#define SAMPLE_INTERVAL 2000 // Intervalle d'échantillonnage en ms
/* USER CODE END PD */
/* USER CODE BEGIN PFP */
// Ajouter un échantillon et calculer la moyenne si assez d'échantillons
HAL_StatusTypeDef DHT_AddSampleAndAverage(DHT_Sensor* sensor, DHT_AveragingData* avgData);
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/**
* @brief Fonction de sortie pour printf
*
* Cette fonction redirige la sortie de printf vers l'UART2.
* Elle est utilisée pour afficher des messages sur le terminal série.
*
* @param ch Le caractère à envoyer
* @return int Le caractère envoyé
*/
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart2, (uint8_t*) &ch, 1, 0xFFFF); // Pour Envoyer le caractère via UART
// ITM_SendChar(ch); // Option alternative pour envoyer le caractère via ITM
return ch;
}
// Ajouter un échantillon et calculer la moyenne si assez d'échantillons
HAL_StatusTypeDef DHT_AddSampleAndAverage(DHT_Sensor* sensor, DHT_AveragingData* avgData) {
float data[2];
HAL_StatusTypeDef result;
// Vérifier le temps écoulé depuis le dernier échantillon
uint32_t currentTime = HAL_GetTick();
if (currentTime - avgData->lastSampleTime < SAMPLE_INTERVAL) {
// Pas assez de temps écoulé, attendre
return HAL_BUSY;
}
// Lecture du capteur
result=DHT_GetData(sensor, data);
avgData->lastSampleTime = currentTime;
if (result == HAL_OK) {
// Ajouter les données à la somme
avgData->tempSum += data[0];
avgData->humSum += data[1];
avgData->sampleCount++;
// Si nous avons assez d'échantillons, calculer la moyenne
if (avgData->sampleCount >= avgData->maxSamples) {
avgData->avgTemp = avgData->tempSum / avgData->maxSamples;
avgData->avgHum = avgData->humSum / avgData->maxSamples;
// Réinitialiser pour le prochain cycle
avgData->tempSum = 0.0f;
avgData->humSum = 0.0f;
avgData->sampleCount = 0;
return HAL_OK; // Moyennes calculées
}
return HAL_BUSY; // Pas encore assez d'échantillons
}
return result; // Erreur lors de la lecture
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_Delay(250); // Attendre 250ms pour la stabilisation
printf("test STM32_DHT\r\n"); // Affiche un message de test dans la console/
HAL_TIM_Base_Start(&htim2); // Démarrer le timer2 utilisé pour les délais en microsecondes
DHT_Sensor DHT22sensor; // Déclaration de la structure pour le capteur DHT22
DHT_Init(&DHT22sensor, &htim2, GPIOA, GPIO_PIN_10, DHT22); // Initialise le capteur DHT22 sur GPIOA, PIN 10 avec TIM2
float data[2]; // Tableau pour stocker la température [0] et l'humidité [1]
DHT_GetData(&DHT22sensor, data); // Lance une lecture pour réveiller le capteur
HAL_Delay(100); // Attendre 100ms pour la stabilisation
// Initialiser la structure de moyenne avec 5 échantillons
DHT_AveragingData averagingData;
DHT_InitAveraging(&averagingData, 5);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
// Tenter d'ajouter un échantillon et calculer la moyenne si possible
HAL_StatusTypeDef status = DHT_AddSampleAndAverage(&DHT22sensor, &averagingData);
// Si des moyennes ont été calculées, les afficher
if (status == HAL_OK) {
printf("Moyennes calculées - Température: %.1f°C, Humidité: %.1f%%\r\n",
averagingData.avgTemp, averagingData.avgHum);
}
// Si erreur de lecture, afficher un message
else if (status != HAL_BUSY) {
printf("Erreur de lecture du capteur: %d\r\n", status);
}
// Attendre avant la prochaine itération (petit délai pour ne pas surcharger le CPU)
HAL_Delay(500);
/* USER CODE END WHILE */
Conclusion
La bibliothèque STM32_DHT vise à simplifier l'utilisation des capteurs DHT avec les microcontrôleurs STM32 en encapsulant la complexité de la communication et de la conversion des données. En suivant ce tutoriel, vous devriez être en mesure de configurer, brancher et lire les données de température et d'humidité de vos capteurs DHT11, DHT22 et DHT21.