#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include <stdio.h>
// GPIO pins for simulation
#define SENSOR_1_PIN A0
#define SENSOR_2_PIN A1
#define VALVE_1_PIN 2
#define VALVE_2_PIN 3
#define EMERGENCY_BUTTON_PIN 4
#define EMERGENCY_LED_PIN 5
#define POTENTIOMETER_PIN A2
// FreeRTOS resources
QueueHandle_t sensorQueue;
SemaphoreHandle_t emergencySemaphore;
SemaphoreHandle_t thresholdMutex; // Changed MutexHandle_t to SemaphoreHandle_t
// Global variables
int moistureThreshold = 50; // Default moisture threshold
// Function prototypes
void readSensorsTask(void *pvParameters);
void activateValvesTask(void *pvParameters);
void emergencyTask(void *pvParameters);
void adjustThresholdTask(void *pvParameters);
void logTask(void *pvParameters);
void setup() {
// Initialize hardware pins
pinMode(SENSOR_1_PIN, INPUT);
pinMode(SENSOR_2_PIN, INPUT);
pinMode(VALVE_1_PIN, OUTPUT);
pinMode(VALVE_2_PIN, OUTPUT);
pinMode(EMERGENCY_BUTTON_PIN, INPUT_PULLUP);
pinMode(EMERGENCY_LED_PIN, OUTPUT);
// Initialize FreeRTOS resources
sensorQueue = xQueueCreate(10, sizeof(int));
emergencySemaphore = xSemaphoreCreateBinary();
thresholdMutex = xSemaphoreCreateMutex(); // Use SemaphoreHandle_t for mutex
// Create tasks
xTaskCreate(readSensorsTask, "ReadSensors", 128, NULL, 2, NULL);
xTaskCreate(activateValvesTask, "ActivateValves", 128, NULL, 2, NULL);
xTaskCreate(emergencyTask, "Emergency", 128, NULL, 3, NULL);
xTaskCreate(adjustThresholdTask, "AdjustThreshold", 128, NULL, 1, NULL);
xTaskCreate(logTask, "Log", 128, NULL, 1, NULL);
// Start scheduler
vTaskStartScheduler();
}
void loop() {
// Empty, tasks run in FreeRTOS
}
void readSensorsTask(void *pvParameters) {
while (1) {
int sensor1Value = analogRead(SENSOR_1_PIN);
int sensor2Value = analogRead(SENSOR_2_PIN);
xQueueSend(sensorQueue, &sensor1Value, portMAX_DELAY);
xQueueSend(sensorQueue, &sensor2Value, portMAX_DELAY);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
void activateValvesTask(void *pvParameters) {
int sensorData;
while (1) {
if (xQueueReceive(sensorQueue, &sensorData, portMAX_DELAY)) {
xSemaphoreTake(thresholdMutex, portMAX_DELAY);
int currentThreshold = moistureThreshold;
xSemaphoreGive(thresholdMutex);
if (sensorData < currentThreshold) {
digitalWrite(VALVE_1_PIN, HIGH);
vTaskDelay(pdMS_TO_TICKS(10000)); // Keep valve open for 10 seconds
digitalWrite(VALVE_1_PIN, LOW);
}
}
}
}
void emergencyTask(void *pvParameters) {
while (1) {
if (digitalRead(EMERGENCY_BUTTON_PIN) == LOW) {
xSemaphoreGive(emergencySemaphore);
}
if (xSemaphoreTake(emergencySemaphore, portMAX_DELAY)) {
// Handle emergency stop
digitalWrite(VALVE_1_PIN, LOW);
digitalWrite(VALVE_2_PIN, LOW);
digitalWrite(EMERGENCY_LED_PIN, HIGH);
vTaskDelay(pdMS_TO_TICKS(2000)); // Emergency state indicator
digitalWrite(EMERGENCY_LED_PIN, LOW);
}
}
}
void adjustThresholdTask(void *pvParameters) {
while (1) {
int potValue = analogRead(POTENTIOMETER_PIN);
int newThreshold = map(potValue, 0, 1023, 0, 100);
xSemaphoreTake(thresholdMutex, portMAX_DELAY);
moistureThreshold = newThreshold;
xSemaphoreGive(thresholdMutex);
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
void logTask(void *pvParameters) {
while (1) {
xSemaphoreTake(thresholdMutex, portMAX_DELAY);
printf("Current moisture threshold: %d\n", moistureThreshold);
xSemaphoreGive(thresholdMutex);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
Loading
st-nucleo-c031c6
st-nucleo-c031c6