#include <FreeRTOS.h>
// Definiciones de pines
#define Led_verde 12 // Indicará si hay lugares disponibles
#define Led_rojo 13 // Indicará que no hay lugares disponibles
#define Led_amarillo 7 // Indicará que la interrupción está activa
#define sensor_i 11 // Registrará el ingreso de vehículos
#define sensor_s 10 // Registrará la salida de vehículos
#define barrera 9 // Pin de control de la barrera
#define reset 8 // Pin para el mecanismo de reset
#define interrupcion 2 // Pin para la interrupción
// Variables globales
int cantidad_de_lugares = 4;
bool interrupcion_activa = false;
void setup() {
pinMode(sensor_i, INPUT_PULLUP); // Configura el sensor como entrada con pull-up
pinMode(sensor_s, INPUT_PULLUP); // Configura el sensor como entrada con pull-up
pinMode(barrera, OUTPUT); // Configura el pin de la barrera como salida
pinMode(Led_verde, OUTPUT); // Configura el pin del LED verde como salida
pinMode(Led_rojo, OUTPUT); // Configura el pin del LED rojo como salida
pinMode(Led_amarillo, OUTPUT); // Configura el pin del LED amarillo como salida
pinMode(reset, INPUT_PULLUP); // Configura el pin de reset como entrada con pull-up
pinMode(interrupcion, INPUT_PULLUP); // Configura el pin de interrupción como entrada con pull-up
digitalWrite(Led_verde, HIGH); // Enciende el LED verde al inicio indicando lugares disponibles
digitalWrite(Led_rojo, LOW); // Apaga el LED rojo al inicio
digitalWrite(Led_amarillo, LOW); // Apaga el LED amarillo al inicio
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(interrupcion), activarInterrupcion, FALLING); // Asigna la función de interrupción al pin
xTaskCreate(TaskEntrada, "TaskEntrada", 100, NULL, 1, NULL);
xTaskCreate(TaskSalida, "TaskSalida", 100, NULL, 1, NULL);
xTaskCreate(TaskInterrupcion, "TaskInterrupcion", 100, NULL, 2, NULL);
// Tarea para gestionar la entrada de vehículos
static void TaskEntrada(void *pvParameters) {
while (1) {
if (!interrupcion_activa && digitalRead(sensor_i) == LOW) {
if (cantidad_de_lugares > 0) {
digitalWrite(Led_verde, HIGH);
digitalWrite(Led_rojo, LOW);
digitalWrite(barrera, HIGH);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(barrera, LOW);
cantidad_de_lugares--;
vTaskDelay(1000 / portTICK_PERIOD_MS);
} else {
digitalWrite(Led_rojo, HIGH);
digitalWrite(Led_verde, LOW);
Serial.println(F("TaskEntrada"));
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
vTaskDelay(100 / portTICK_PERIOD_MS); // Delay para evitar lectura excesiva
}
}
static void Task_2(void* pvParameters) {
while (1) {
// Verificar si la interrupción está activa
if (interrupcion_activa) {
digitalWrite(Led_amarillo, HIGH); // Enciende el LED amarillo si la interrupción está activa
// No permite que se sumen autos mientras la interrupción esté activa
delay(5000); // Espera un segundo antes de volver a verificar
} else {
// Verificar si un vehículo está ingresando (solo si la interrupción no está activa)
if (!interrupcion_activa && digitalRead(sensor_i) == LOW) {
if (cantidad_de_lugares > 0) {
digitalWrite(Led_verde, HIGH); // Enciende el LED verde si hay espacio disponible
digitalWrite(Led_rojo, LOW); // Apaga el LED rojo si hay espacio disponible
digitalWrite(barrera, HIGH); // Simulación de levantamiento de la barrer
delay(500); // Espera 5 segundos para simular el paso del vehículo
digitalWrite(barrera, LOW); // Baja la barrera
cantidad_de_lugares--; // Decrementa la cantidad de lugares disponibles
delay(1000); // Espera un segundo para evitar la detección repetida del mismo vehículo
} else {
digitalWrite(Led_rojo, HIGH); // Enciende el LED rojo si no hay espacio disponible
digitalWrite(Led_verde, LOW); // Apaga el LED verde si no hay espacio disponible
delay(1000); // Espera un segundo antes de volver a verificar
}
}
}
// Verificar si un vehículo está saliendo (solo si la interrupción no está activa)
if (!interrupcion_activa && digitalRead(sensor_s) == LOW) {
// Simulación de salida del vehículo
digitalWrite(barrera, HIGH); // Levanta la barrera
delay(5000); // Espera 5 segundos para simular el paso del vehículo
digitalWrite(barrera, LOW); // Baja la barrera
cantidad_de_lugares++; // Incrementa la cantidad de lugares disponibles
delay(1000); // Espera un segundo antes de volver a verificar
}
}
Serial.println(F("Task"));
vTaskDelay(1100 / portTICK_PERIOD_MS);
}
}
// Función para activar la interrupción
void activarInterrupcion() {
if (digitalRead(interrupcion) == LOW) {
interrupcion_activa = true;
} else {
interrupcion_activa = false;
digitalWrite(Led_amarillo, HIGH); // Apaga el LED amarillo cuando la interrupción se desactiva
}
}