#include <FreeRTOS.h>
#include <semphr.h>
// Pins de simulation
#define CAPTEUR_1_PIN A0
#define CAPTEUR_2_PIN A1
#define POTENTIOMETER_PIN A2
#define EMERGENCY_BUTTON 2
#define VALVE_1_LED 10
#define VALVE_2_LED 11
#define EMERGENCY_LED 12
// Variables globales
QueueHandle_t queueHandle;
SemaphoreHandle_t emergencySemaphore;
SemaphoreHandle_t thresholdMutex;
int humidityThreshold = 50; // Initialisé à 50%
int valveDuration = 10000; // Durée d'activation par défaut (10 secondes)
volatile bool emergencyActive = false; // Indique si l'urgence est active
// Logging UART
void logEvent(const char *message) {
Serial.println(message);
}
// Tâche : Surveillance de l'humidité
void Task_SoilMoistureMonitor(void *pvParameters) {
int sensorValue1, sensorValue2;
for (;;) {
if (!emergencyActive) {
sensorValue1 = analogRead(CAPTEUR_1_PIN);
sensorValue2 = analogRead(CAPTEUR_2_PIN);
xSemaphoreTake(thresholdMutex, portMAX_DELAY);
int threshold = humidityThreshold;
xSemaphoreGive(thresholdMutex);
if (sensorValue1 < threshold) {
int zone = 1;
xQueueSend(queueHandle, &zone, portMAX_DELAY);
logEvent("Zone 1: Humidité en dessous du seuil. Activation demandée.");
}
if (sensorValue2 < threshold) {
int zone = 2;
xQueueSend(queueHandle, &zone, portMAX_DELAY);
logEvent("Zone 2: Humidité en dessous du seuil. Activation demandée.");
}
}
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
// Tâche : Activation des vannes
void Task_ValveControl(void *pvParameters) {
int zone;
for (;;) {
if (xQueueReceive(queueHandle, &zone, portMAX_DELAY)) {
if (!emergencyActive) {
if (zone == 1) {
digitalWrite(VALVE_1_LED, HIGH);
logEvent("Zone 1: Vanne activée.");
vTaskDelay(pdMS_TO_TICKS(valveDuration));
digitalWrite(VALVE_1_LED, LOW);
logEvent("Zone 1: Vanne désactivée.");
} else if (zone == 2) {
digitalWrite(VALVE_2_LED, HIGH);
logEvent("Zone 2: Vanne activée.");
vTaskDelay(pdMS_TO_TICKS(valveDuration));
digitalWrite(VALVE_2_LED, LOW);
logEvent("Zone 2: Vanne désactivée.");
}
}
}
}
}
// Tâche : Gestion de l'arrêt d'urgence
void Task_EmergencyStop(void *pvParameters) {
for (;;) {
if (digitalRead(EMERGENCY_BUTTON) == HIGH) {
xSemaphoreGive(emergencySemaphore);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
// Tâche : Gestion de l'état d'urgence
void Task_HandleEmergency(void *pvParameters) {
for (;;) {
if (xSemaphoreTake(emergencySemaphore, portMAX_DELAY)) {
emergencyActive = true;
digitalWrite(VALVE_1_LED, LOW);
digitalWrite(VALVE_2_LED, LOW);
digitalWrite(EMERGENCY_LED, HIGH);
logEvent("Urgence : Toutes les vannes désactivées et LED rouge allumée.");
// Attendre que l'urgence soit désactivée
while (digitalRead(EMERGENCY_BUTTON) == HIGH) {
vTaskDelay(pdMS_TO_TICKS(100));
}
digitalWrite(EMERGENCY_LED, LOW);
emergencyActive = false;
logEvent("Urgence résolue : Retour à la normale.");
}
}
}
// Tâche : Ajustement du seuil
void Task_AdjustThreshold(void *pvParameters) {
for (;;) {
int potentiometerValue = analogRead(POTENTIOMETER_PIN);
xSemaphoreTake(thresholdMutex, portMAX_DELAY);
humidityThreshold = map(potentiometerValue, 0, 1023, 0, 100);
xSemaphoreGive(thresholdMutex);
logEvent("Seuil d'humidité mis à jour.");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
// Initialisation
void setup() {
Serial.begin(9600);
pinMode(CAPTEUR_1_PIN, INPUT);
pinMode(CAPTEUR_2_PIN, INPUT);
pinMode(POTENTIOMETER_PIN, INPUT);
pinMode(EMERGENCY_BUTTON, INPUT_PULLUP);
pinMode(VALVE_1_LED, OUTPUT);
pinMode(VALVE_2_LED, OUTPUT);
pinMode(EMERGENCY_LED, OUTPUT);
queueHandle = xQueueCreate(5, sizeof(int));
emergencySemaphore = xSemaphoreCreateBinary();
thresholdMutex = xSemaphoreCreateMutex();
xTaskCreate(Task_SoilMoistureMonitor, "SoilMonitor", 1000, NULL, 1, NULL);
xTaskCreate(Task_ValveControl, "ValveControl", 1000, NULL, 1, NULL);
xTaskCreate(Task_EmergencyStop, "EmergencyStop", 1000, NULL, 2, NULL);
xTaskCreate(Task_HandleEmergency, "HandleEmergency", 1000, NULL, 3, NULL);
xTaskCreate(Task_AdjustThreshold, "AdjustThreshold", 1000, NULL, 1, NULL);
vTaskStartScheduler();
}
void loop() {
// FreeRTOS gère tout
}