#include <Arduino.h>
#include <Arduino_FreeRTOS.h>
#include <DHT.h>
#include <LiquidCrystal.h>
#include <queue.h>
// LCD configuration
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
const int bufferSize= 2;
float humidityHist[bufferSize];
float tempHist[bufferSize];
int index=0;
// DHT sensor configuration
#define DHTPIN 2 // Pin connected to the DHT sensor
#define DHTTYPE DHT22 // Sensor type (DHT22)
DHT dht(DHTPIN, DHTTYPE);
// Pump and LED configuration
const int pumpPin = 3; // Pump (acts as the first LED) for humidity
const int ledPin = 4; // LED for temperature
const int ledPin2 = 5; // LED for temperature
// Thresholds for humidity and temperature
const int moistureThreshold = 40; // Humidity threshold
const int tempThreshold = 24; // Temperature threshold (degrees Celsius)
// Variables to store sensor readings
float humidity = 0.0;
float temperature = 0.0;
// Task handles
TaskHandle_t pumpControlTaskHandle = NULL;
TaskHandle_t ledControlTaskHandle = NULL;
TaskHandle_t readSensorsTaskHandle = NULL;
// Task function prototypes
void displayTask(void *pvParameters);
void readSensorsTask(void *pvParameters);
void pumpControlTask(void *pvParameters);
void ledControlTask(void *pvParameters);
void printTask(void *pvParameters) ;
QueueHandle_t my_queue1;
QueueHandle_t my_queue2;
void setup() {
Serial.begin(9600);
for(int i=0; i<= bufferSize; i++){
humidityHist[i] = 0.0;
tempHist[i] = 0.0;
}
// Initialize the LCD
lcd.begin(16, 2);
// Initialize the pump and LED pins
pinMode(pumpPin, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(pumpPin, LOW);
digitalWrite(ledPin, LOW);
// Initialize the DHT sensor
dht.begin();
xTaskCreate(printTask, "print History", 128, NULL, 3, NULL);
// Create the display task (always running)
xTaskCreate(displayTask, "Display", 128, NULL, 3, NULL);
my_queue1 = xQueueCreate(1, sizeof(float));
my_queue2 = xQueueCreate(1,sizeof(float));
}
void loop() {
// Loop is not used as FreeRTOS manages the tasks
}
// Task to display data on the LCD
void displayTask(void *pvParameters) {
while (1) {
// Display current humidity and temperature
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print("C");
// Create the sensor reading task if not already running
if (readSensorsTaskHandle == NULL ) {
xTaskCreate(readSensorsTask, "Read Sensors", 128, NULL, 2, &readSensorsTaskHandle);
}
vTaskDelay(1000 / portTICK_PERIOD_MS); // Update every second
}
}
// Task to read humidity and temperature from the DHT sensor
void readSensorsTask(void *pvParameters) {
while (1) {
xQueueSend(my_queue1, &humidity, portMAX_DELAY);
xQueueSend(my_queue2, &temperature, portMAX_DELAY);
humidity = dht.readHumidity();
temperature = dht.readTemperature();
if (isnan(humidity)) {
Serial.println("Failed to read humidity!");
humidity = 0.0; // Default value in case of error
}
if (isnan(temperature)) {
Serial.println("Failed to read temperature!");
temperature = 0.0; // Default value in case of error
}
humidityHist[index] = humidity;
tempHist[index] = temperature;
index = (index + 1) % bufferSize;
// Trigger pump control based on humidity condition
if (humidity < moistureThreshold && pumpControlTaskHandle == NULL) {
xTaskCreate(pumpControlTask, "Pump Control", 128, NULL, 1, &pumpControlTaskHandle);
}
// Trigger LED control based on temperature condition
if (( temperature > tempThreshold || temperature < 0 ) && ledControlTaskHandle == NULL) {
xTaskCreate(ledControlTask, "LED Control", 128, NULL, 1, &ledControlTaskHandle);
}
vTaskDelay(1000 / portTICK_PERIOD_MS); // Delay between sensor readings
}
}
// Task to control the pump (first LED for humidity)
void pumpControlTask(void *pvParameters) {
// Turn on the pump
digitalWrite(pumpPin, HIGH);
// Keep the pump running for 5 seconds
vTaskDelay(10000 / portTICK_PERIOD_MS);
// Turn off the pump
digitalWrite(pumpPin, LOW);
// After pump control task finishes, do not delete the task, keep it available for reuse
pumpControlTaskHandle = NULL; // Reset task handle for reuse
vTaskDelete(NULL);
}
// Task to control the temperature LED
void ledControlTask(void *pvParameters) {
xQueueReceive(my_queue1, &humidity, portMAX_DELAY );
xQueueReceive(my_queue2, &temperature, portMAX_DELAY);
int pin;
if (temperature > tempThreshold) {
pin = ledPin;
} else {
pin = ledPin2;
}
// Turn on the temperature LED
digitalWrite(pin, HIGH);
// Keep the LED on for 5 seconds
vTaskDelay(10000 / portTICK_PERIOD_MS);
// Turn off the LED
digitalWrite(pin, LOW);
// After LED control task finishes, do not delete the task, keep it available for reuse
ledControlTaskHandle = NULL; // Reset task handle for reuse
vTaskDelete(NULL);
}
void printTask(void *pvParameters) {
while(1){
xQueueReceive(my_queue1, &humidity, portMAX_DELAY );
xQueueReceive(my_queue2, &temperature, portMAX_DELAY);
Serial.println("Humidity History:");
for (int i = 0; i < bufferSize; i++) {
Serial.println(humidityHist[i]);
}
Serial.println("Temprature History:");
for (int i = 0; i < bufferSize; i++) {
Serial.println(tempHist[i]);
}
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}