#include <Arduino.h>
// Task handles
TaskHandle_t sensorTaskHandle;
TaskHandle_t ButtonRedTaskHandle;
TaskHandle_t ButtonGreenTaskHandle;
TaskHandle_t ledBlinkTaskHandle;
TaskHandle_t ledPatternTaskHandle;
// Global variables
volatile bool sensorActive = true; // Tracks whether the sensor task is active
volatile bool buttonPressed1 = false; // Flag for button press
volatile bool buttonReleased1 = false; // Flag for button release
volatile bool buttonPressed2 = false; // Flag for button press
volatile bool buttonReleased2 = false; // Flag for button release
volatile bool ledPatternActive = false; // Flag to toggle LED pattern
volatile int sensorValue = 0; // Global sensor value
unsigned long lastDebounceTime = 0; // To implement debouncing
const unsigned long debounceDelay = 50; // 50ms debounce delay
// Sensor task: generates random sensor value
void sensorTask(void *parameter) {
while (1) {
// Update the global sensor value
sensorValue = random(0, 101); // Generate a random number between 0 and 100
Serial.print("Sensor value: ");
Serial.println(sensorValue);
vTaskDelay(1000 / portTICK_PERIOD_MS); // Delay for 1 second
}
}
// Task to run the LED pattern
void ledPatternTask(void *parameter) {
while (1) {
digitalWrite(15, HIGH);
vTaskDelay(1000 / portTICK_PERIOD_MS);
digitalWrite(15, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(2, HIGH);
vTaskDelay(1000 / portTICK_PERIOD_MS);
digitalWrite(2, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(4, HIGH);
vTaskDelay(1000 / portTICK_PERIOD_MS);
digitalWrite(4, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void checkButtonPressBlue() {
int buttonState = digitalRead(16); // Read the state of the button
digitalWrite(15, LOW);
digitalWrite(2, LOW);
digitalWrite(4, LOW);
if (buttonState == LOW) { // Button pressed (falling edge)
if (!buttonPressed2 && (millis() - lastDebounceTime) > debounceDelay) {
buttonPressed2 = true;
lastDebounceTime = millis(); // Reset debounce timer
}
} else { // Button released (rising edge)
if (buttonPressed2 && (millis() - lastDebounceTime) > debounceDelay) {
buttonPressed2 = false;
buttonReleased2 = true; // Set the flag to indicate the button was released
lastDebounceTime = millis(); // Reset debounce timer
}
}
}
// LED Blink Task: Blinks both RED and GREEN LEDs when sensor is inactive
void ledBlinkTask(void *parameter) {
while (1) {
if (!sensorActive) {
// Blink both LEDs simultaneously with a 1000ms interval
digitalWrite(27, HIGH); // Turn ON Red LED
digitalWrite(26, HIGH); // Turn ON Green LED
vTaskDelay(1000 / portTICK_PERIOD_MS);
digitalWrite(27, LOW); // Turn OFF Red LED
digitalWrite(26, LOW); // Turn OFF Green LED
vTaskDelay(1000 / portTICK_PERIOD_MS);
} else {
// When sensor is active, ensure we have a small delay to avoid CPU hogging
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
}
void toggleTaskBlue(void *parameter) {
while (1) {
checkButtonPressBlue(); // Check button state
if (buttonReleased2) {
buttonReleased2 = false; // Reset the flag
// Toggle LED pattern task
ledPatternActive = !ledPatternActive;
if (ledPatternActive) {
vTaskResume(ledPatternTaskHandle); // Resume the LED pattern task
Serial.println("LED pattern started.");
} else {
vTaskSuspend(ledPatternTaskHandle); // Suspend the LED pattern task
Serial.println("LED pattern stopped.");
// Turn off all LEDs when stopping the pattern
digitalWrite(15, LOW);
digitalWrite(2, LOW);
digitalWrite(4, LOW);
}
}
vTaskDelay(100 / portTICK_PERIOD_MS); // Small delay to check button state
}
}
// Button press detection logic with debounce
void checkButtonPressRedGreen() {
int buttonState = digitalRead(25); // Read the state of the button on pin 25
if (buttonState == LOW) { // Button pressed (falling edge)
if (!buttonPressed1 && (millis() - lastDebounceTime) > debounceDelay) {
buttonPressed1 = true;
lastDebounceTime = millis(); // Reset debounce timer
}
} else { // Button released (rising edge)
if (buttonPressed1 && (millis() - lastDebounceTime) > debounceDelay) {
buttonPressed1 = false;
buttonReleased1 = true; // Set the flag to indicate the button was released
lastDebounceTime = millis(); // Reset debounce timer
}
}
}
// Toggle sensor and LED behavior based on button press-release cycle
void toggleTaskRedGreen(void *parameter) {
while (1) {
checkButtonPressRedGreen(); // Check if button press/release happened
if (buttonReleased1) {
buttonReleased1 = false; // Reset the flag
// Toggle sensor activity
sensorActive = !sensorActive;
if (sensorActive) {
// Sensor task active: stop LED blinking and start sensor reading
vTaskResume(sensorTaskHandle);
Serial.println("Sensor task started. LEDs OFF.");
} else {
// Sensor task inactive: stop sensor reading and resume LED blinking
vTaskSuspend(sensorTaskHandle);
Serial.println("Sensor task stopped. Blinking LEDs.");
}
}
vTaskDelay(100 / portTICK_PERIOD_MS); // Small delay to check button state
}
}
// Task to handle Green LED based on sensor value
void ButtonGreenTask(void *parameter) {
while (1) {
if (sensorValue < 90) {
digitalWrite(14, HIGH); // Turn on Green LED
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(14, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS);
} else {
digitalWrite(14, LOW); // Turn off Green LED
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
}
// Task to handle Red LED based on sensor value
void ButtonRedTask(void *parameter) {
while (1) {
if (sensorValue >= 90) {
digitalWrite(12, HIGH); // Turn on Red LED
vTaskDelay(250 / portTICK_PERIOD_MS);
digitalWrite(12, LOW);
vTaskDelay(250 / portTICK_PERIOD_MS);
} else {
digitalWrite(12, LOW); // Turn off Red LED
}
vTaskDelay(250 / portTICK_PERIOD_MS); // Delay for 250ms
}
}
void setup() {
pinMode(12, OUTPUT); // Set pin 12 as OUTPUT for Red LED
pinMode(14, OUTPUT); // Set pin 14 as OUTPUT for Green LED
pinMode(27, OUTPUT); // Set pin 12 as OUTPUT for Red LED
pinMode(26, OUTPUT); // Set pin 14 as OUTPUT for Green LED
pinMode(25, INPUT_PULLUP); // Button input with internal pull-up
pinMode(18, OUTPUT);
pinMode(5, OUTPUT);
pinMode(17, OUTPUT);
pinMode(15, OUTPUT);
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(16, INPUT_PULLUP);
Serial.begin(9600); // Initialize serial communication
randomSeed(analogRead(0)); // Seed the random number generator
// Create the sensor task
xTaskCreatePinnedToCore(sensorTask, "Sensor Task", 1000, NULL, 1, &sensorTaskHandle, 0);
// Create the red LED task
xTaskCreatePinnedToCore(ButtonRedTask, "Red LED", 1000, NULL, 1, &ButtonRedTaskHandle, 1);
// Create the green LED task
xTaskCreatePinnedToCore(ButtonGreenTask, "Green LED", 1000, NULL, 2, &ButtonGreenTaskHandle, 1);
// Create the LED blink task
xTaskCreatePinnedToCore(ledBlinkTask, "LED Blink Task", 1000, NULL, 3, &ledBlinkTaskHandle, 1);
// Create the toggle task for button press detection
xTaskCreatePinnedToCore(toggleTaskRedGreen, "Toggle Task", 1000, NULL, 4, NULL, 0);
xTaskCreatePinnedToCore(ledPatternTask, "LED Pattern Task", 1000, NULL, 5, &ledPatternTaskHandle, 1);
vTaskSuspend(ledPatternTaskHandle); // Start with LED pattern task suspended
// Create task to toggle LED pattern based on button press
xTaskCreatePinnedToCore(toggleTaskBlue, "Toggle Task", 1000, NULL, 6, NULL, 1);
}
void loop() {
digitalWrite(18, HIGH);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(18, LOW);
vTaskDelay(1000 / portTICK_PERIOD_MS);
digitalWrite(5, HIGH);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(5, LOW);
vTaskDelay(1000 / portTICK_PERIOD_MS);
digitalWrite(17, HIGH);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(17, LOW);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}