#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#include <queue.h>
// Semáforos e filas
SemaphoreHandle_t interruptSemaphore;
SemaphoreHandle_t mutex_v;
QueueHandle_t ledQueue;
// Variáveis para debounce e estado do LED
volatile unsigned long last_micros = 0;
long debouncing_time = 150; // Tempo de debounce em milissegundos
volatile uint8_t ledState = 0; // Estado do LED: 0: off, 1: red, 2: green, 3: blue
void setup() {
Serial.begin(9600);
// Configuração dos pinos dos LEDs e botão
pinMode(2, INPUT_PULLUP);
pinMode(10, OUTPUT); // LED vermelho
pinMode(11, OUTPUT); // LED verde
pinMode(12, OUTPUT); // LED azul
// Configura interrupção para o botão no pino 2
attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, CHANGE);
// Inicialização de semáforos e fila
interruptSemaphore = xSemaphoreCreateBinary();
mutex_v = xSemaphoreCreateMutex();
ledQueue = xQueueCreate(10, sizeof(uint8_t));
if (interruptSemaphore == NULL || mutex_v == NULL || ledQueue == NULL) {
Serial.println("Erro ao criar semáforo/mutex/fila");
}
// Criação de tarefas
xTaskCreate(TaskLEDControl, "LEDControl", 128, NULL, 1, NULL);
xTaskCreate(Task1, "Task1", 128, NULL, 1, NULL);
xTaskCreate(Task2, "Task2", 128, NULL, 1, NULL);
}
void loop() {
// Função loop vazia em programas FreeRTOS
}
// Função de interrupção chamada pelo botão
void handleInterrupt() {
unsigned long currentMicros = micros();
if (currentMicros - last_micros > debouncing_time * 1000) {
last_micros = currentMicros;
xSemaphoreGiveFromISR(interruptSemaphore, NULL);
}
}
// Tarefa que controla o LED RGB
void TaskLEDControl(void *pvParameters) {
while (1) {
if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdTRUE) {
ledState = (ledState + 1) % 4; // Alterna entre 0 (off) e 1, 2, 3 (cores)
switch (ledState) {
case 0: digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW); break; // Desliga todos
case 1: digitalWrite(10, HIGH); digitalWrite(11, LOW); digitalWrite(12, LOW); break; // Vermelho
case 2: digitalWrite(10, LOW); digitalWrite(11, HIGH); digitalWrite(12, LOW); break; // Verde
case 3: digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, HIGH); break; // Azul
}
}
}
}
// Tarefa 1: Envia mensagens periódicas na porta serial
void Task1(void *pvParameters) {
while (1) {
if (xSemaphoreTake(mutex_v, portMAX_DELAY) == pdTRUE) {
Serial.println("Task 1 is running");
xSemaphoreGive(mutex_v);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
}
// Tarefa 2: Envia mensagens mais frequentes na porta serial
void Task2(void *pvParameters) {
while (1) {
if (xSemaphoreTake(mutex_v, portMAX_DELAY) == pdTRUE) {
Serial.println("Task 2 is running");
xSemaphoreGive(mutex_v);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
}