#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
// Definição dos pinos
#define BUTTON1_PIN 3 // Botão 1 conectado ao pino 3
#define BUTTON2_PIN 46 // Botão 2 conectado ao pino 46
#define LED_PIN 8 // LED conectado ao pino 8
// Semáforo binário
SemaphoreHandle_t xSemaphore = NULL;
// Variável para armazenar o estado do LED
bool ledState = false;
// Função para alternar o estado do LED
void toggleLED() {
ledState = !ledState;
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
}
// Tarefa para alternar o LED
void vTaskToggleLED(void *pvParameters) {
int button = (int)pvParameters;
for (;;) {
// Aguarda o semáforo ser liberado
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
toggleLED(); // Alterna o estado do LED
xSemaphoreGive(xSemaphore); // Libera o semáforo imediatamente
}
vTaskDelay(10 / portTICK_PERIOD_MS); // Pequeno delay para evitar polling excessivo
}
}
// Função de interrupção para o botão 1
void IRAM_ATTR handleButton1Interrupt() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Libera o semáforo para a tarefa de alternar o LED
xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
// Realiza a troca de contexto, se necessário
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
// Função de interrupção para o botão 2
void IRAM_ATTR handleButton2Interrupt() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Libera o semáforo para a tarefa de alternar o LED
xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
// Realiza a troca de contexto, se necessário
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void setup() {
// Configuração dos pinos
pinMode(BUTTON1_PIN, INPUT_PULLUP); // Botão 1 com resistor pull-up interno
pinMode(BUTTON2_PIN, INPUT_PULLUP); // Botão 2 com resistor pull-up interno
pinMode(LED_PIN, OUTPUT); // LED como saída
// Inicializa o estado do LED como desligado
digitalWrite(LED_PIN, LOW);
// Criação do semáforo binário
xSemaphore = xSemaphoreCreateBinary();
if (xSemaphore == NULL) {
Serial.println("Falha ao criar o semáforo");
while (1); // Trava o sistema em caso de erro
}
// Libera o semáforo inicialmente
xSemaphoreGive(xSemaphore);
// Configuração das interrupções para os botões
attachInterrupt(digitalPinToInterrupt(BUTTON1_PIN), handleButton1Interrupt, FALLING);
attachInterrupt(digitalPinToInterrupt(BUTTON2_PIN), handleButton2Interrupt, FALLING);
// Criação das tarefas para alternar o LED
xTaskCreate(vTaskToggleLED, "ToggleLEDTask1", 1024, (void*)BUTTON1_PIN, 1, NULL);
xTaskCreate(vTaskToggleLED, "ToggleLEDTask2", 1024, (void*)BUTTON2_PIN, 1, NULL);
// Inicializa a comunicação serial
Serial.begin(115200);
}
void loop() {
// O loop está vazio, pois as tarefas e interrupções estão sendo gerenciadas pelo FreeRTOS
}