#include "stm32c0xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
ADC_HandleTypeDef hadc1;
// Déclarations des variables et des fonctions
float Temperature = 0.0;
float Humidity = 0.0;
uint32_t potentiometerValue = 0;
uint32_t mappedValue = 0;
// Définitions des pins
#define SENSOR_PIN1 GPIO_PIN_0
#define SENSOR_PIN2 GPIO_PIN_1
#define SENSOR_PORT GPIOA
#define LED1_PIN GPIO_PIN_5
#define LED2_PIN GPIO_PIN_6
#define LED_PORT GPIOA
#define EMERGENCY_BUTTON_PIN GPIO_PIN_4
#define BUTTON_PORT GPIOA
#define LEDE_PIN GPIO_PIN_7
//volatile int humidityThreshold = 50;
// FreeRTOS handles
TaskHandle_t sensorTaskHandle;
TaskHandle_t valveTaskHandle;
TaskHandle_t emergencyTaskHandle;
TaskHandle_t TaskAdjustThresholdHandle;
QueueHandle_t commandQueue;
SemaphoreHandle_t emergencySemaphore;
SemaphoreHandle_t mutex;
// Prototypes
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void sensorTask(void *pvParameters);
void valveTask(void *pvParameters);
void emergencyTask(void *pvParameters);
void TaskAdjustThreshold(void *pvParameters);
void DHT22_Start(void);
uint8_t DHT22_CheckResponse(void);
uint8_t DHT22_ReadData(void);
float Read_DHT22(void);
void UART_Send(const char *message) {
printf("%s", message); // Utilisation de printf pour envoyer via UART (Wokwi fait la redirection automatiquement)
}
int main(void) {
HAL_Init();
SystemClock_Config();
MX_ADC1_Init();
MX_GPIO_Init();
// Initialisation des composants FreeRTOS
commandQueue = xQueueCreate(5, sizeof(uint8_t));
emergencySemaphore = xSemaphoreCreateBinary();
mutex = xSemaphoreCreateMutex();
// Création des tâches FreeRTOS
xTaskCreate(sensorTask, "SensorTask", 128, NULL, 1, &sensorTaskHandle);
xTaskCreate(valveTask, "ValveTask", 128, NULL, 2, &valveTaskHandle);
xTaskCreate(emergencyTask, "EmergencyTask", 128, NULL, 3, &emergencyTaskHandle);
xTaskCreate(TaskAdjustThreshold, "TaskAdjustThreshold", 128, NULL, 1, &TaskAdjustThresholdHandle);
// Démarrage du scheduler FreeRTOS
vTaskStartScheduler();
while (1) {
}
}
void TaskAdjustThreshold(void *pvParameters) {
char str[20];
HAL_ADC_Start(&hadc1);
UART_Send("Task 1: Hello from UART!\r\n");
for (;;) {
if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) {
// Lire la valeur de l'ADC
potentiometerValue = HAL_ADC_GetValue(&hadc1);
mappedValue = (potentiometerValue * 100) / 4095;
sprintf(str, "%lu", mappedValue);
UART_Send(str);
}
vTaskDelay(pdMS_TO_TICKS(500)); // Utilisation de vTaskDelay
}
}
void sensorTask(void *pvParameters) {
while (1) {
UART_Send("Task 2: Hello from UART!\r\n");
// Lire l'humidité à partir du DHT22
float humidity1 = Read_DHT22(); // Remplacer par une logique réelle de lecture du DHT22
int humidity2 = 40; // Remplacer par une logique réelle de lecture du DHT22
xSemaphoreTake(mutex, portMAX_DELAY);
xSemaphoreGive(mutex);
if (humidity1 != -1) {
if (humidity1 < mappedValue) {
uint8_t command = 1;
xQueueSend(commandQueue, &command, portMAX_DELAY);
}
if (humidity2 < mappedValue) {
uint8_t command = 2;
xQueueSend(commandQueue, &command, portMAX_DELAY);
}
}
vTaskDelay(pdMS_TO_TICKS(5000)); // Attendre avant de lire à nouveau
}
}
void valveTask(void *pvParameters) {
uint8_t command;
UART_Send("Task 3: Hello from UART!\r\n");
HAL_GPIO_WritePin(LED_PORT, LEDE_PIN, GPIO_PIN_RESET);
while (1) {
if (xQueueReceive(commandQueue, &command, portMAX_DELAY) == pdPASS) {
if (command == 1) {
HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_SET);
vTaskDelay(pdMS_TO_TICKS(10000)); // Attendre 10 secondes
HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_RESET);
} else if (command == 2) {
HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_SET);
vTaskDelay(pdMS_TO_TICKS(10000)); // Attendre 10 secondes
HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_RESET);
}
}
}
}
void emergencyTask(void *pvParameters) {
while (1) {
UART_Send("Task 4: Hello from UART!\r\n");
if (HAL_GPIO_ReadPin(BUTTON_PORT, EMERGENCY_BUTTON_PIN) == GPIO_PIN_SET) {
HAL_GPIO_WritePin(LED_PORT, LEDE_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_RESET);
xSemaphoreGive(emergencySemaphore);
}
vTaskDelay(pdMS_TO_TICKS(100)); // Attendre 100 ms
}
}
void MX_GPIO_Init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
// Configurer les pins pour les capteurs
GPIO_InitStruct.Pin = SENSOR_PIN1 | SENSOR_PIN2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(SENSOR_PORT, &GPIO_InitStruct);
// Configurer les pins pour les LEDs
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(LED_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LEDE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
// Configurer le bouton d'urgence
GPIO_InitStruct.Pin = EMERGENCY_BUTTON_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
}
static void MX_ADC1_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
// Configuration de l'ADC
hadc1.Instance = ADC1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC4;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);
// Configuration du canal pour le potentiomètre
sConfig.Channel = ADC_CHANNEL_3; // Correspond à PA3 (ADC_CHANNEL_3)
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
void DHT22_Start(void) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(20);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_Delay(1);
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
uint8_t DHT22_CheckResponse(void) {
uint8_t Response = 0;
HAL_Delay(1);
if (!(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1))) {
HAL_Delay(1);
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)) {
Response = 1;
}
}
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1));
return Response;
}
uint8_t DHT22_ReadData(void) {
uint8_t i, j;
uint8_t Data = 0;
for (j = 0; j < 8; j++) {
while (!(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)));
HAL_Delay(1);
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)) {
Data |= (1 << (7 - j));
}
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1));
}
return Data;
}
float Read_DHT22(void) {
uint8_t Presence = 0;
uint8_t Rh_Byte1, Rh_Byte2, Temp_Byte1, Temp_Byte2;
uint16_t SUM;
DHT22_Start();
Presence = DHT22_CheckResponse();
if (Presence) {
Rh_Byte1 = DHT22_ReadData();
Rh_Byte2 = DHT22_ReadData();
Temp_Byte1 = DHT22_ReadData();
Temp_Byte2 = DHT22_ReadData();
SUM = DHT22_ReadData();
if (SUM == (Rh_Byte1 + Rh_Byte2 + Temp_Byte1 + Temp_Byte2)) {
Humidity = ((Rh_Byte1 << 8) + Rh_Byte2) / 10.0;
Temperature = ((Temp_Byte1 << 8) + Temp_Byte2) / 10.0;
return Humidity;
}
}
return -1;
}
void loop(){}