#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#include <stdio.h>
#include <LiquidCrystal.h>
#define MAIN_LED_PIN 9
#define INTERMITTENT_LED_PIN 8
#define BUTTON_INCREMENT_PIN 7
#define BUTTON_DECREMENT_PIN 6
#define BUTTON_MAIN_PIN 5
#define BUTTON_RESET_PIN 4
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
volatile int mainLedState = HIGH;
volatile int recurrenceInterval = 100;
SemaphoreHandle_t mutex;
TaskHandle_t buttonAndLedTaskHandle;
TaskHandle_t blinkSecondLedTaskHandle;
TaskHandle_t rateChangeTaskHandle;
TaskHandle_t lcdUpdateTaskHandle;
TaskHandle_t idleTaskHandle;
TaskHandle_t taskResetRecurrenceTaskHandle;
TaskHandle_t outputPatternTaskHandle; // New task for generating output pattern
void buttonAndLedTask(void *pvParameters);
void blinkSecondLedTask(void *pvParameters);
void rateChangeTask(void *pvParameters);
void lcdUpdateTask(void *pvParameters);
void idleTask(void *pvParameters);
void taskResetRecurrence(void *pvParameters);
void outputPatternTask(void *pvParameters); // New function prototype
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
pinMode(BUTTON_MAIN_PIN, INPUT);
pinMode(BUTTON_INCREMENT_PIN, INPUT);
pinMode(BUTTON_DECREMENT_PIN, INPUT);
pinMode(MAIN_LED_PIN, OUTPUT);
pinMode(INTERMITTENT_LED_PIN, OUTPUT);
mutex = xSemaphoreCreateMutex();
xTaskCreate(buttonAndLedTask, "ButtonLed", 100, NULL, 1, &buttonAndLedTaskHandle);
xTaskCreate(blinkSecondLedTask, "IntermittentLed", 100, NULL, 1, &blinkSecondLedTaskHandle);
xTaskCreate(rateChangeTask, "RateChange", 100, NULL, 1, &rateChangeTaskHandle);
xTaskCreate(lcdUpdateTask, "UpdateLCD", 100, NULL, 2, &lcdUpdateTaskHandle);
xTaskCreate(taskResetRecurrence, "ResetRecurrency", 100, NULL, 1, &taskResetRecurrenceTaskHandle);
xTaskCreate(idleTask, "Idle", 100, NULL, 1, &idleTaskHandle);
xTaskCreate(outputPatternTask, "OutputPattern", 100, NULL, 1, &outputPatternTaskHandle); // Creating the new task
vTaskStartScheduler();
}
void loop() {
}
void buttonAndLedTask(void *pvParameters) {
(void)pvParameters;
const TickType_t debounceDelay = pdMS_TO_TICKS(200);
bool lastButtonState = LOW;
bool currentButtonState;
for (;;) {
currentButtonState = digitalRead(BUTTON_MAIN_PIN);
if (currentButtonState != lastButtonState && currentButtonState == LOW) {
mainLedState = !mainLedState;
if (mainLedState) {
digitalWrite(MAIN_LED_PIN, LOW);
digitalWrite(INTERMITTENT_LED_PIN, HIGH);
} else {
digitalWrite(INTERMITTENT_LED_PIN, LOW);
}
vTaskDelay(debounceDelay);
}
lastButtonState = currentButtonState;
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
void blinkSecondLedTask(void *pvParameters) {
(void)pvParameters;
TickType_t xLastWakeTime = xTaskGetTickCount();
for (;;) {
if (!mainLedState) {
digitalWrite(MAIN_LED_PIN, !digitalRead(MAIN_LED_PIN));
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(recurrenceInterval));
} else {
digitalWrite(INTERMITTENT_LED_PIN, HIGH);
vTaskDelay(pdMS_TO_TICKS(recurrenceInterval));
}
}
}
void rateChangeTask(void *pvParameters) {
while (1) {
if (digitalRead(BUTTON_INCREMENT_PIN) == HIGH) {
recurrenceInterval = (recurrenceInterval + 100 <= 600) ? recurrenceInterval + 100 : 600;
vTaskDelay(500 / portTICK_PERIOD_MS);
}
if (digitalRead(BUTTON_DECREMENT_PIN) == HIGH) {
recurrenceInterval = (recurrenceInterval - 100 >= 100) ? recurrenceInterval - 100 : 100;
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
}
void lcdUpdateTask(void *pvParameters) {
(void)pvParameters;
lcd.clear();
while (1) {
lcd.setCursor(0, 0);
lcd.print("Main LED: ");
lcd.print(mainLedState ? " On" : "Off");
lcd.setCursor(0, 1);
lcd.print("Interval: ");
lcd.print(recurrenceInterval);
lcd.print("ms");
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
void idleTask(void *pvParameters) {
(void)pvParameters;
while (1) {
Serial.print("Main LED: ");
Serial.println(mainLedState == HIGH ? "ON" : "OFF");
Serial.print("Intermittent LED: ");
Serial.println(digitalRead(INTERMITTENT_LED_PIN) == LOW ? "ON" : "OFF");
Serial.print("Recurrence Interval: ");
Serial.print(recurrenceInterval);
Serial.println(" ms\n______________________");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void taskResetRecurrence(void *pvParameters) {
while (1) {
if (digitalRead(BUTTON_RESET_PIN) == HIGH) {
vTaskDelay(50 / portTICK_PERIOD_MS);
if (digitalRead(BUTTON_RESET_PIN) == HIGH) {
recurrenceInterval = 100;
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void outputPatternTask(void *pvParameters) {
(void)pvParameters;
const char pattern[] = "(^-^)\n"; // Define your output pattern
while (1) {
for (int i = 0; pattern[i] != '\0'; ++i) {
lcd.print(pattern[i]); // Print each character in the pattern to the LCD
vTaskDelay(250 / portTICK_PERIOD_MS); // Adjust delay for pattern speed
}
vTaskDelay(5000 / portTICK_PERIOD_MS); // Delay before repeating the pattern
lcd.clear(); // Clear the LCD after displaying the pattern
}
}