#define RED_CAR_LED 2
#define YELLOW_CAR_LED 4
#define GREEN_CAR_LED 5
#define PEDESTRIAN_BUTTON 18
SemaphoreHandle_t semaphoreBinary;
SemaphoreHandle_t semaphoreMutex;
enum TrafficLightState {
RED,
GREEN,
YELLOW
};
TrafficLightState carTrafficState = GREEN;
bool pedestrianRequest = false;
void carTrafficTask(void *parameter) {
for (;;) {
xSemaphoreTake(semaphoreMutex, portMAX_DELAY);
switch (carTrafficState) {
case GREEN:
digitalWrite(GREEN_CAR_LED, HIGH);
digitalWrite(YELLOW_CAR_LED, LOW);
digitalWrite(RED_CAR_LED, LOW);
vTaskDelay(pdMS_TO_TICKS(5000));
if (pedestrianRequest) {
carTrafficState = YELLOW;
}
break;
case YELLOW:
digitalWrite(GREEN_CAR_LED, LOW);
digitalWrite(YELLOW_CAR_LED, HIGH);
digitalWrite(RED_CAR_LED, LOW);
vTaskDelay(pdMS_TO_TICKS(2000));
carTrafficState = RED;
break;
case RED:
digitalWrite(GREEN_CAR_LED, LOW);
digitalWrite(YELLOW_CAR_LED, LOW);
digitalWrite(RED_CAR_LED, HIGH);
vTaskDelay(pdMS_TO_TICKS(5000));
pedestrianRequest = false;
carTrafficState = GREEN;
break;
}
xSemaphoreGive(semaphoreMutex);
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void pedestrianTask(void *parameter) {
for (;;) {
if (xSemaphoreTake(semaphoreBinary, portMAX_DELAY) == pdTRUE) {
xSemaphoreTake(semaphoreMutex, portMAX_DELAY);
pedestrianRequest = true;
xSemaphoreGive(semaphoreMutex);
}
}
}
void IRAM_ATTR pedestrianButtonISR() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(semaphoreBinary, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void setup() {
pinMode(RED_CAR_LED, OUTPUT);
pinMode(YELLOW_CAR_LED, OUTPUT);
pinMode(GREEN_CAR_LED, OUTPUT);
pinMode(PEDESTRIAN_BUTTON, INPUT_PULLUP);
semaphoreBinary = xSemaphoreCreateBinary();
semaphoreMutex = xSemaphoreCreateMutex();
if (semaphoreBinary == NULL || semaphoreMutex == NULL) {
Serial.println("Erro ao criar os semáforos!");
while (1);
}
attachInterrupt(digitalPinToInterrupt(PEDESTRIAN_BUTTON), pedestrianButtonISR, FALLING);
xTaskCreate(carTrafficTask, "Car Traffic Task", 1024, NULL, 1, NULL);
xTaskCreate(pedestrianTask, "Pedestrian Task", 1024, NULL, 1, NULL);
vTaskDelete(NULL);
}
void loop() {
}