#include "stm32f3xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "stdio.h"
#include "DHT.h"
// Définition des pins pour les LEDs, bouton et potentiomètre
#define LED1_PIN GPIO_PIN_0 // Première LED (Zone 1)
#define LED2_PIN GPIO_PIN_1 // Deuxième LED (Zone 2)
#define BUTTON_PIN GPIO_PIN_13 // Bouton poussoir pour arrêt d'urgence
#define POT_PIN GPIO_PIN_2 // Potentiomètre pour ajuster le seuil
// Définition des pins pour les capteurs DHT22
#define DHT22_PIN_1 GPIO_PIN_5 // Pin pour le premier capteur DHT22 (Zone 1)
#define DHT22_PIN_2 GPIO_PIN_6 // Pin pour le second capteur DHT22 (Zone 2)
// Paramètres
#define HUMIDITY_THRESHOLD 50 // Seuil d'humidité par défaut
#define HUMIDITY_PERIOD_MS 5000 // Période de lecture des capteurs d'humidité en ms
#define VALVE_OPEN_TIME_MS 10000 // Durée d'ouverture de la vanne en ms
// Structures pour les messages
typedef enum {
ZONE1,
ZONE2
} Zone;
typedef struct {
Zone zone;
} ValveMessage;
// Variables globales
SemaphoreHandle_t emergencySemaphore;
QueueHandle_t valveQueue;
int humidityThreshold = HUMIDITY_THRESHOLD; // Seuil d'humidité
// Fonction d'initialisation de l'UART (simulation)
void UART_Init(void) {
// Initialisation UART pour la journalisation
// HAL_UART_Init(&huart2);
}
// Fonction de journalisation
void UART_Printf(const char *message) {
// Simulation de l'affichage sur le moniteur série
printf("%s\n", message);
}
// Initialisation des GPIOs
void GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// Initialisation des LEDs (simuler les vannes)
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = LED1_PIN | LED2_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// Initialisation du bouton poussoir pour l'arrêt d'urgence
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = BUTTON_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// Initialisation du potentiomètre
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = POT_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// Initialisation des capteurs DHT22 (pour chaque zone)
DHT_init(DHT22_PIN_1);
DHT_init(DHT22_PIN_2);
}
// Fonction pour lire l'humidité des capteurs DHT22
int ReadHumidityDHT(int sensor_pin) {
float humidity = 0.0;
if (sensor_pin == DHT22_PIN_1) {
humidity = DHT_readHumidity(DHT22_PIN_1);
} else if (sensor_pin == DHT22_PIN_2) {
humidity = DHT_readHumidity(DHT22_PIN_2);
}
return (int)humidity;
}
// Tâche pour la surveillance de l'humidité
void HumidityTask(void *pvParameters) {
int humidityZone1, humidityZone2;
while (1) {
// Lecture des capteurs DHT22 pour l'humidité
humidityZone1 = ReadHumidityDHT(DHT22_PIN_1); // Zone 1
humidityZone2 = ReadHumidityDHT(DHT22_PIN_2); // Zone 2
// Comparaison avec le seuil d'humidité
if (humidityZone1 < humidityThreshold) {
ValveMessage msg = {ZONE1};
xQueueSend(valveQueue, &msg, portMAX_DELAY); // Envoi du message dans la queue pour activer la vanne de la zone 1
}
if (humidityZone2 < humidityThreshold) {
ValveMessage msg = {ZONE2};
xQueueSend(valveQueue, &msg, portMAX_DELAY); // Envoi du message dans la queue pour activer la vanne de la zone 2
}
// Attente de 5 secondes avant la prochaine lecture
vTaskDelay(pdMS_TO_TICKS(HUMIDITY_PERIOD_MS));
}
}
// Tâche pour activer les vannes
void ValveControlTask(void *pvParameters) {
ValveMessage msg;
while (1) {
if (xQueueReceive(valveQueue, &msg, portMAX_DELAY)) {
// Activation de la LED en fonction de la zone
if (msg.zone == ZONE1) {
HAL_GPIO_WritePin(GPIOB, LED1_PIN, GPIO_PIN_SET); // Activer LED 1
UART_Printf("Zone 1 arrosage activé");
} else if (msg.zone == ZONE2) {
HAL_GPIO_WritePin(GPIOB, LED2_PIN, GPIO_PIN_SET); // Activer LED 2
UART_Printf("Zone 2 arrosage activé");
}
// Attente de la durée d'activation de la vanne
vTaskDelay(pdMS_TO_TICKS(VALVE_OPEN_TIME_MS));
// Désactivation de la LED après la durée
if (msg.zone == ZONE1) {
HAL_GPIO_WritePin(GPIOB, LED1_PIN, GPIO_PIN_RESET); // Désactiver LED 1
} else if (msg.zone == ZONE2) {
HAL_GPIO_WritePin(GPIOB, LED2_PIN, GPIO_PIN_RESET); // Désactiver LED 2
}
}
}
}
// Tâche pour gérer l'arrêt d'urgence
void EmergencyStopTask(void *pvParameters) {
while (1) {
if (HAL_GPIO_ReadPin(GPIOC, BUTTON_PIN) == GPIO_PIN_SET) {
// Si le bouton d'urgence est pressé
xSemaphoreGive(emergencySemaphore); // Signaler un arrêt d'urgence
UART_Printf("Arrêt d'urgence activé");
// Allumer la LED rouge pour l'arrêt d'urgence
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET); // Exemple LED rouge
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
// Tâche pour ajuster le seuil d'humidité
void ThresholdTask(void *pvParameters) {
while (1) {
// Simulation de la lecture de la valeur du potentiomètre pour ajuster le seuil
int potValue = HAL_GPIO_ReadPin(GPIOA, POT_PIN); // Simulation de la lecture
humidityThreshold = (potValue / 4095.0) * 100; // Conversion en pourcentage
// Journalisation de la nouvelle valeur du seuil
char msg[50];
snprintf(msg, sizeof(msg), "Nouveau seuil d'humidité: %d", humidityThreshold);
UART_Printf(msg);
// Attente avant la prochaine lecture du potentiomètre
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
// Tâche pour gérer le sémaphore d'urgence
void EmergencySemaphoreTask(void *pvParameters) {
while (1) {
if (xSemaphoreTake(emergencySemaphore, portMAX_DELAY)) {
// Fermer toutes les vannes et éteindre les LEDs
HAL_GPIO_WritePin(GPIOB, LED1_PIN | LED2_PIN, GPIO_PIN_RESET);
UART_Printf("Toutes les vannes fermées");
// Allumer la LED rouge d'urgence
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
}
}
}
int main(void) {
HAL_Init();
UART_Init();
GPIO_Init();
// Création des sémaphores et queues
emergencySemaphore = xSemaphoreCreateBinary();
valveQueue = xQueueCreate(10, sizeof(ValveMessage));
// Création des tâches
xTaskCreate(HumidityTask, "HumidityTask", 128, NULL, 1, NULL);
xTaskCreate(ValveControlTask, "ValveControlTask", 128, NULL, 1, NULL);
xTaskCreate(EmergencyStopTask, "EmergencyStopTask", 128, NULL, 1, NULL);
xTaskCreate(ThresholdTask, "ThresholdTask", 128, NULL, 1, NULL);
xTaskCreate(EmergencySemaphoreTask, "EmergencySemaphoreTask", 128, NULL, 1, NULL);
// Démarrage du scheduler FreeRTOS
vTaskStartScheduler();
while (1) {
// Code principal
}
}