#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
// === CONFIGURACIÓN DE PINES ===
#define BUTTON_1_PIN 17 // Botón moneda $1 (existente)
#define BUTTON_5_PIN 16 // Botón moneda $5 (nuevo)
#define BUTTON_10_PIN 4 // Botón moneda $10 (nuevo)
#define BUTTON_20_PIN 21 // Botón moneda $10 (nuevo)
#define LED_1_PIN 2 // LED moneda $1 (existente)
#define LED_5_PIN 18 // LED moneda $5 (nuevo)
#define LED_10_PIN 19 // LED moneda $10 (nuevo)
#define LED_20_PIN 5
#define DEBOUNCE_TICKS pdMS_TO_TICKS(200)
typedef enum{
pagando,
recibo,
cambio,
entregado
}Estados1;
typedef enum{
m1,
m5,
m10
}estados_monedas;
// === ESTRUCTURA PARA LA COLA ===
typedef struct {
int pinNumber;
int coinValue; // 1, 5 ,10 0 20 pesos
} button_event_t;
QueueHandle_t handlerQueue;
volatile TickType_t last_interrupt_tick_1 = 0;
volatile TickType_t last_interrupt_tick_5 = 0;
volatile TickType_t last_interrupt_tick_10 = 0;
volatile TickType_t last_interrupt_tick_20 = 0;
// === HANDLERS DE INTERRUPCIÓN ===
static void IRAM_ATTR gpio_interrupt_handler_1(void *args) {
TickType_t current_tick = xTaskGetTickCountFromISR();
if ((current_tick - last_interrupt_tick_1) > DEBOUNCE_TICKS) {
last_interrupt_tick_1 = current_tick;
int pinNumber = BUTTON_1_PIN;
button_event_t event = {pinNumber, 1};
xQueueSendFromISR(handlerQueue, &event, NULL);
}
}
static void IRAM_ATTR gpio_interrupt_handler_5(void *args) {
TickType_t current_tick = xTaskGetTickCountFromISR();
if ((current_tick - last_interrupt_tick_5) > DEBOUNCE_TICKS) {
last_interrupt_tick_5 = current_tick;
int pinNumber = BUTTON_5_PIN;
button_event_t event = {pinNumber, 5};
xQueueSendFromISR(handlerQueue, &event, NULL);
}
}
static void IRAM_ATTR gpio_interrupt_handler_10(void *args) {
TickType_t current_tick = xTaskGetTickCountFromISR();
if ((current_tick - last_interrupt_tick_10) > DEBOUNCE_TICKS) {
last_interrupt_tick_10 = current_tick;
int pinNumber = BUTTON_10_PIN;
button_event_t event = {pinNumber, 10};
xQueueSendFromISR(handlerQueue, &event, NULL);
}
}
static void IRAM_ATTR gpio_interrupt_handler_20(void *args) {
TickType_t current_tick = xTaskGetTickCountFromISR();
if ((current_tick - last_interrupt_tick_10) > DEBOUNCE_TICKS) {
last_interrupt_tick_10 = current_tick;
int pinNumber = BUTTON_10_PIN;
button_event_t event = {pinNumber, 20};
xQueueSendFromISR(handlerQueue, &event, NULL);
}
}
// === TASK DE CONTROL DE LEDs ===
/*
void LED_Control_Task(void *params) {
button_event_t event;
int count_1 = 0, count_5 = 0, count_10 = 0,count_total=0;
while(true) {
if(xQueueReceive(handlerQueue, &event, portMAX_DELAY)) {
switch(event.coinValue) {
case 1: // Moneda $1
count_1++;
//gpio_set_level(LED_1_PIN, !gpio_get_level(LED_1_PIN));
printf("Moneda $1 - Presionada %d veces. LED: %s\n",
count_1, gpio_get_level(LED_1_PIN) ? "ENCENDIDO" : "APAGADO");
count_total=(count_1)+(count_5*5)+(count_10*10);
printf("van %d pesos\n",count_total);
if(count_1>=5){
gpio_set_level(LED_1_PIN,1);
}
break;
case 5: // Moneda $5
count_5++;
//gpio_set_level(LED_5_PIN, !gpio_get_level(LED_5_PIN));
printf("Moneda $5 - Presionada %d veces. LED: %s\n",
count_5, gpio_get_level(LED_5_PIN) ? "ENCENDIDO" : "APAGADO");
count_total=(count_1)+(count_5*5)+(count_10*10);
printf("van %d pesos\n",count_total);
if(count_5>=5){
gpio_set_level(LED_5_PIN,1);
}
break;
case 10: // Moneda $10
count_10++;
//gpio_set_level(LED_10_PIN, !gpio_get_level(LED_10_PIN));
printf("Moneda $10 - Presionada %d veces. LED: %s\n",
count_10, gpio_get_level(LED_10_PIN) ? "ENCENDIDO" : "APAGADO");
count_total=(count_1)+(count_5*5)+(count_10*10);
printf("van %d pesos\n",count_total);
if(count_10>=5){
gpio_set_level(LED_10_PIN,1);
}
break;
//printf("van %d pesos\n",count_total);
}
}
}
}
*/
void LED_Control_Task(void *params) {
button_event_t event;
int count_1 = 0, count_5 = 0, count_10 = 0,count_20=0,count_total=0;
Estados1 estado_actual=pagando;
int ccambio=0,moneda1=0,moneda5=0,moneda10=10;
int i,j,k,l;
while(1){
switch(estado_actual){
case pagando:
//while(true) {
if(xQueueReceive(handlerQueue, &event, portMAX_DELAY)) {
switch(event.coinValue) {
case 1: // Moneda $1
count_1++;
//gpio_set_level(LED_1_PIN, !gpio_get_level(LED_1_PIN));
printf("Moneda $1 - Presionada %d veces. LED: %s\n",
count_1, gpio_get_level(LED_1_PIN) ? "ENCENDIDO" : "APAGADO");
count_total=(count_1)+(count_5*5)+(count_10*10)+(count_20*20);
printf("van %d pesos\n",count_total);
if(count_total>=15){
estado_actual=recibo;
//gpio_set_level(LED_1_PIN,1);
}
break;
case 5: // Moneda $5
count_5++;
//gpio_set_level(LED_5_PIN, !gpio_get_level(LED_5_PIN));
printf("Moneda $5 - Presionada %d veces. LED: %s\n",
count_5, gpio_get_level(LED_5_PIN) ? "ENCENDIDO" : "APAGADO");
count_total=(count_1)+(count_5*5)+(count_10*10)+(count_20*20);
printf("van %d pesos\n",count_total);
if(count_total>=15){
estado_actual=recibo;
//gpio_set_level(LED_5_PIN,1);
}
break;
case 10: // Moneda $10
count_10++;
//gpio_set_level(LED_10_PIN, !gpio_get_level(LED_10_PIN));
printf("Moneda $10 - Presionada %d veces. LED: %s\n",
count_10, gpio_get_level(LED_10_PIN) ? "ENCENDIDO" : "APAGADO");
count_total=(count_1)+(count_5*5)+(count_10*10)+(count_20*20);
printf("van %d pesos\n",count_total);
if(count_total>=15){
estado_actual=recibo;
//gpio_set_level(LED_10_PIN,1);
}
break;
//printf("van %d pesos\n",count_total);
case 20:
count_20++;
//gpio_set_level(LED_10_PIN, !gpio_get_level(LED_10_PIN));
printf("Moneda $20 - Presionada %d veces. LED: %s\n",
count_20, gpio_get_level(LED_20_PIN) ? "ENCENDIDO" : "APAGADO");
count_total=(count_1)+(count_5*5)+(count_10*10)+(count_20*20);
printf("van %d pesos\n",count_total);
if(count_total>=15){
estado_actual=recibo;
//gpio_set_level(LED_10_PIN,1);
}
break;
}
}
//}
break;
case recibo:
printf("ya se pagaron los 15 pesos gracias\n");
//while(1){gpio_set_level(LED_1_PIN,1);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_5_PIN,1);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_10_PIN,1);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_20_PIN,1);
vTaskDelay(500/portTICK_PERIOD_MS);
//apagado
gpio_set_level(LED_1_PIN,0);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_5_PIN,0);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_10_PIN,0);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_20_PIN,0);
vTaskDelay(500/portTICK_PERIOD_MS);
// }
estado_actual=cambio;
break;
case cambio:
ccambio=count_total-15;
printf("el total es de %d \n",count_total);
printf("el cambio es de %d \n",count_total-15);
switch(ccambio){
case 19:
moneda10=1;
moneda5=1;
moneda1=4;
break;
case 18:
moneda10=1;
moneda5=1;
moneda1=3;
break;
case 17:
moneda10=1;
moneda5=1;
moneda1=2;
break;
case 16:
moneda10=1;
moneda5=1;
moneda1=1;
break;
case 15:
moneda10=1;
moneda5=1;
moneda1=0;
break;
case 14:
moneda10=1;
moneda5=0;
moneda1=4;
break;
case 13:
moneda10=1;
moneda5=0;
moneda1=3;
break;
case 12:
moneda10=1;
moneda5=0;
moneda1=2;
break;
case 11:
moneda10=1;
moneda5=0;
moneda1=1;
break;
case 10:
moneda10=1;
moneda5=0;
moneda1=0;
break;
case 9:
moneda10=0;
moneda5=1;
moneda1=4;
break;
case 8:
moneda10=0;
moneda5=1;
moneda1=3;
break;
case 7:
moneda10=0;
moneda5=1;
moneda1=2;
break;
case 6:
moneda10=0;
moneda5=1;
moneda1=1;
break;
case 5:
moneda10=0;
moneda5=1;
moneda1=0;
break;
case 4:
moneda10=0;
moneda5=0;
moneda1=4;
break;
case 3:
moneda10=0;
moneda5=0;
moneda1=3;
break;
case 2:
moneda10=0;
moneda5=0;
moneda1=2;
break;
case 1:
moneda10=0;
moneda5=0;
moneda1=1;
break;
default:
moneda10=0;
moneda5=0;
moneda1=0;
break;
}
while(moneda10>0){
gpio_set_level(LED_10_PIN,1);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_10_PIN,0);
vTaskDelay(500/portTICK_PERIOD_MS);
moneda10--;
}
while(moneda5>0){
gpio_set_level(LED_5_PIN,1);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_5_PIN,0);
vTaskDelay(500/portTICK_PERIOD_MS);
moneda5--;
}
while(moneda1>0){
gpio_set_level(LED_1_PIN,1);
vTaskDelay(500/portTICK_PERIOD_MS);
gpio_set_level(LED_1_PIN,0);
vTaskDelay(500/portTICK_PERIOD_MS);
moneda1--;
}
estado_actual=entregado;
break;
case entregado:
count_1 = 0, count_5 = 0, count_10 = 0,count_20=0,count_total=0;
ccambio=0,moneda1=0,moneda5=0,moneda10=10;
estado_actual=pagando;
break;
default:
break;
}
}
}
// === CONFIGURACIÓN INICIAL ===
void configure_gpio() {
// Configurar LEDs
gpio_reset_pin(LED_1_PIN);
gpio_set_direction(LED_1_PIN, GPIO_MODE_OUTPUT);
gpio_reset_pin(LED_5_PIN);
gpio_set_direction(LED_5_PIN, GPIO_MODE_OUTPUT);
gpio_reset_pin(LED_10_PIN);
gpio_set_direction(LED_10_PIN, GPIO_MODE_OUTPUT);
gpio_reset_pin(LED_20_PIN);
gpio_set_direction(LED_20_PIN, GPIO_MODE_OUTPUT);
// Configurar botones con pull-down
gpio_reset_pin(BUTTON_1_PIN);
gpio_set_direction(BUTTON_1_PIN, GPIO_MODE_INPUT);
gpio_pulldown_en(BUTTON_1_PIN);
gpio_pullup_dis(BUTTON_1_PIN);
gpio_set_intr_type(BUTTON_1_PIN, GPIO_INTR_POSEDGE);
gpio_reset_pin(BUTTON_5_PIN);
gpio_set_direction(BUTTON_5_PIN, GPIO_MODE_INPUT);
gpio_pulldown_en(BUTTON_5_PIN);
gpio_pullup_dis(BUTTON_5_PIN);
gpio_set_intr_type(BUTTON_5_PIN, GPIO_INTR_POSEDGE);
gpio_reset_pin(BUTTON_10_PIN);
gpio_set_direction(BUTTON_10_PIN, GPIO_MODE_INPUT);
gpio_pulldown_en(BUTTON_10_PIN);
gpio_pullup_dis(BUTTON_10_PIN);
gpio_set_intr_type(BUTTON_10_PIN, GPIO_INTR_POSEDGE);
gpio_reset_pin(BUTTON_20_PIN);
gpio_set_direction(BUTTON_20_PIN, GPIO_MODE_INPUT);
gpio_pulldown_en(BUTTON_20_PIN);
gpio_pullup_dis(BUTTON_20_PIN);
gpio_set_intr_type(BUTTON_20_PIN, GPIO_INTR_POSEDGE);
}
// === MAIN ===
void app_main() {
//Estados1 estado_actual =pagando;
// int total =0;
// int moneda;
// Configurar GPIOs
configure_gpio();
// Crear cola para eventos
handlerQueue = xQueueCreate(10, sizeof(button_event_t));
// Crear task de control
xTaskCreate(LED_Control_Task, "LED_Control_Task", 2048, NULL, 1, NULL);
// Instalar servicio ISR y agregar handlers
gpio_install_isr_service(0);
gpio_isr_handler_add(BUTTON_1_PIN, gpio_interrupt_handler_1, NULL);
gpio_isr_handler_add(BUTTON_5_PIN, gpio_interrupt_handler_5, NULL);
gpio_isr_handler_add(BUTTON_10_PIN, gpio_interrupt_handler_10, NULL);
gpio_isr_handler_add(BUTTON_20_PIN, gpio_interrupt_handler_20, NULL);
printf("El cobro por el uso del estacionamiento es de 15 pesos...\n");
printf("Ingresar moneda...\n");
}
/*
switch(ccambio){
case 19:
moneda10=1;
moneda5=1;
moneda1=4;
break;
case 18:
moneda10=1;
moneda5=1;
moneda1=3;
break;
case 17:
moneda10=1;
moneda5=1;
moneda1=2;
break;
case 16:
moneda10=1;
moneda5=1;
moneda1=1;
break;
case 15:
moneda10=1;
moneda5=1;
moneda1=0;
break;
case 14:
moneda10=1;
moneda5=0;
moneda1=4;
break;
case 13:
moneda10=1;
moneda5=0;
moneda1=3;
break;
case 12:
moneda10=1;
moneda5=0;
moneda1=2;
break;
case 11:
moneda10=1;
moneda5=0;
moneda1=1;
break;
case 10:
moneda10=1;
moneda5=0;
moneda1=0;
break;
case 9:
moneda10=0;
moneda5=1;
moneda1=4;
break;
case 8:
moneda10=0;
moneda5=1;
moneda1=3;
break;
case 7:
moneda10=0;
moneda5=1;
moneda1=2;
break;
case 6:
moneda10=0;
moneda5=1;
moneda1=1;
break;
case 5:
moneda10=0;
moneda5=1;
moneda1=0;
break;
case 4:
moneda10=0;
moneda5=0;
moneda1=4;
break;
case 3:
moneda10=0;
moneda5=0;
moneda1=3;
break;
case 2:
moneda10=0;
moneda5=0;
moneda1=2;
break;
case 1:
moneda10=0;
moneda5=0;
moneda1=1;
break;
default:
break;
}*/