#include "stm32c0xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
UART_HandleTypeDef huart1;
ADC_HandleTypeDef hadc1; // Déclaration de l'ADC1
// Prototypes des fonctions
void UART_Init(void);
void ADC1_Init(void);
void GPIO_Init(void);
void Task_SensorRead(void *pvParameters);
void Task_ValveControl(void *pvParameters);
void Task_EmergencyStop(void *pvParameters);
void Task_AdjustThreshold(void *pvParameters);
// Variables globales
QueueHandle_t xSensorQueue;
SemaphoreHandle_t xEmergencySemaphore;
SemaphoreHandle_t xMutexThreshold;
uint16_t humidityThreshold = 500; // Valeur initiale du seuil d'humidité
// Fonction UART_Init
void UART_Init(void) {
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK) {
while (1); // Boucle d'erreur
}
UART_Transmit("UART initialisé avec succès\n");
}
// Fonction pour envoyer des messages via UART
void UART_Transmit(const char *message) {
HAL_UART_Transmit(&huart1, (uint8_t *)message, strlen(message), HAL_MAX_DELAY);
}
// Fonction ADC1_Init
void ADC1_Init(void) {
__HAL_RCC_ADC_CLK_ENABLE(); // Activez l'horloge ADC
hadc1.Instance = ADC1; // Utilisez ADC1
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK) {
UART_Transmit("Erreur lors de l'initialisation de l'ADC\n");
while (1); // Boucle d'erreur
}
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_3; // Adaptez selon le pin utilisé
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5; // Temps d'échantillonnage
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
UART_Transmit("Erreur lors de la configuration du canal ADC\n");
while (1); // Boucle d'erreur
}
UART_Transmit("ADC initialisé avec succès\n");
}
// Fonction GPIO_Init
void GPIO_Init(void) {
// Initialisation des GPIOs utilisés pour les vannes et boutons
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
// GPIO pour les vannes
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// GPIO pour le bouton d'arrêt d'urgence
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
UART_Transmit("GPIO initialisés avec succès\n");
}
// Tâche : Lire les capteurs d'humidité
void Task_SensorRead(void *pvParameters) {
uint16_t sensorValue1 = 0;
uint16_t sensorValue2 = 0;
for (;;) {
// Simulation des valeurs des capteurs
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) {
sensorValue1 = HAL_ADC_GetValue(&hadc1); // Lecture du capteur 1
}
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) {
sensorValue2 = HAL_ADC_GetValue(&hadc1); // Lecture du capteur 2
}
// Si l'humidité est en dessous du seuil, envoyer un message à la queue
if (sensorValue1 < humidityThreshold) {
xQueueSend(xSensorQueue, &sensorValue1, portMAX_DELAY);
UART_Transmit("Arrosage activé pour Zone 1\n");
}
if (sensorValue2 < humidityThreshold) {
xQueueSend(xSensorQueue, &sensorValue2, portMAX_DELAY);
UART_Transmit("Arrosage activé pour Zone 2\n");
}
vTaskDelay(pdMS_TO_TICKS(5000)); // Attendre 5 secondes
}
}
// Tâche : Contrôler les vannes
void Task_ValveControl(void *pvParameters) {
uint16_t receivedValue;
for (;;) {
if (xQueueReceive(xSensorQueue, &receivedValue, portMAX_DELAY)) {
// Simuler l'ouverture de la vanne
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // Activer la vanne
UART_Transmit("Vanne 1 activée\n");
vTaskDelay(pdMS_TO_TICKS(10000)); // Maintenir ouverte 10 secondes
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // Désactiver la vanne
UART_Transmit("Vanne 1 désactivée\n");
}
}
}
// Tâche : Gérer l'arrêt d'urgence
void Task_EmergencyStop(void *pvParameters) {
for (;;) {
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_SET) { // Bouton d'arrêt appuyé
UART_Transmit("Arrêt d'urgence activé\n");
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // Fermer toutes les vannes
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
xSemaphoreGive(xEmergencySemaphore); // Déclencher l'événement d'urgence
}
vTaskDelay(pdMS_TO_TICKS(100)); // Vérifier toutes les 100 ms
}
}
// Tâche : Ajuster le seuil d'humidité
void Task_AdjustThreshold(void *pvParameters) {
uint16_t potentiometerValue;
for (;;) {
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) {
potentiometerValue = HAL_ADC_GetValue(&hadc1); // Lecture du potentiomètre
if (xSemaphoreTake(xMutexThreshold, portMAX_DELAY)) {
humidityThreshold = potentiometerValue;
xSemaphoreGive(xMutexThreshold);
UART_Transmit("Seuil d'humidité mis à jour\n");
}
}
vTaskDelay(pdMS_TO_TICKS(2000)); // Attendre 2 secondes
}
}
// Fonction vApplicationIdleHook (ne nécessite pas loop())
void vApplicationIdleHook(void) {
// Cette fonction est appelée lorsque le processeur est inactif
// Elle est nécessaire pour éviter l'erreur liée à "loop"
}
// Définir une fonction vide "loop" pour satisfaire STM32duino
void loop(void) {
// La fonction loop() est requise par STM32duino mais nous ne l'utilisons pas
}
// Fonction principale
int main(void) {
HAL_Init();
UART_Init();
ADC1_Init();
GPIO_Init();
// Création des objets FreeRTOS
xSensorQueue = xQueueCreate(5, sizeof(uint16_t));
xEmergencySemaphore = xSemaphoreCreateBinary();
xMutexThreshold = xSemaphoreCreateMutex();
// Création des tâches
xTaskCreate(Task_SensorRead, "Sensor Read", 128, NULL, 1, NULL);
xTaskCreate(Task_ValveControl, "Valve Control", 128, NULL, 1, NULL);
xTaskCreate(Task_EmergencyStop, "Emergency Stop", 128, NULL, 2, NULL);
xTaskCreate(Task_AdjustThreshold, "Adjust Threshold", 128, NULL, 1, NULL);
// Démarrage du scheduler FreeRTOS
vTaskStartScheduler;}