#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
// --- [1] Mapeamento dos pinos ---
const byte ledPins[] = {13, 12, 14, 27}; // PORTB simulado
const byte buttonPins[] = {32, 33, 25, 26}; // PORTD simulado
const byte NUM_LEDS = 4;
// --- [2] Criação da Fila (1 posição, tipo byte = 8 bits) ---
QueueHandle_t xQueue_LED = xQueueCreate(1, sizeof(byte));
// --- [3] Protótipos das tarefas ---
void Ler_botoes(void *pvParameters); // Produtora
void LED_acende(void *pvParameters); // Consumidora
void setup() {
Serial.begin(115200);
Serial.println("Experimento 3 - Atividade 1: Comunicação com Queue");
// --- [4] Configuração dos pinos (botões ligados ao 3V3) ---
for (byte i = 0; i < NUM_LEDS; i++) {
pinMode(ledPins[i], OUTPUT);
pinMode(buttonPins[i], INPUT_PULLDOWN); // necessário para circuito com 3V3
}
// --- [5] Verificação da Fila e criação das tarefas ---
if (xQueue_LED != NULL) {
xTaskCreate(Ler_botoes, "Ler_botoes", 2048, NULL, 1, NULL);
xTaskCreate(LED_acende, "LED_acende", 2048, NULL, 1, NULL);
Serial.println("Fila e tarefas criadas com sucesso!");
} else {
Serial.println("ERRO: Falha ao criar a fila.");
}
}
void loop() {
vTaskDelete(NULL); // loop desativado — FreeRTOS assume controle
}
// --- [6] Tarefa Produtora: Lê botão pressionado e envia índice para a fila ---
void Ler_botoes(void *pvParameters) {
for (;;) {
for (byte i = 0; i < NUM_LEDS; i++) {
if (digitalRead(buttonPins[i]) == HIGH) { // botão pressionado (3V3)
byte indice = i;
Serial.printf("Botão %d pressionado. Enviando para fila...\n", i);
// Envia para fila com timeout de 100ms → evita deadlock
BaseType_t status = xQueueSend(xQueue_LED, &indice, pdMS_TO_TICKS(100));
if (status != pdPASS) {
Serial.println("ATENÇÃO: Fila cheia. Dado descartado.");
}
// Debounce: aguarda botão ser solto
while (digitalRead(buttonPins[i]) == HIGH) {
vTaskDelay(pdMS_TO_TICKS(20));
}
vTaskDelay(pdMS_TO_TICKS(50)); // atraso pós-soltar
}
}
vTaskDelay(pdMS_TO_TICKS(10)); // evita uso excessivo da CPU
}
}
// --- [7] Tarefa Consumidora: espera item da fila e acende o LED correspondente ---
void LED_acende(void *pvParameters) {
byte indice;
for (;;) {
// Espera bloqueado até dado chegar na fila (portMAX_DELAY = espera infinita)
if (xQueueReceive(xQueue_LED, &indice, portMAX_DELAY) == pdPASS) {
Serial.printf("Recebido da fila: %d. Acendendo LED...\n", indice);
digitalWrite(ledPins[indice], HIGH);
vTaskDelay(pdMS_TO_TICKS(1000)); // LED aceso por 1 segundo
digitalWrite(ledPins[indice], LOW);
Serial.printf("LED %d apagado.\n", indice);
}
}
}