#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#define BOTON_MONEDA_DE_UNO GPIO_NUM_4
#define BOTON_MONEDA_DE_CINCO GPIO_NUM_13
#define BOTON_MONEDA_DE_DIEZ GPIO_NUM_14
#define BOTON_MONEDA_DE_VEINTE GPIO_NUM_16
#define LED_MONEDA_DE_UNO GPIO_NUM_17
#define LED_MONEDA_DE_CINCO GPIO_NUM_18
#define LED_MONEDA_DE_DIEZ GPIO_NUM_19
#define LED_RECIBO GPIO_NUM_21
#define COSTO 15
typedef enum {
eStart = 0,
eEsperarDinero,
eContarDinero,
eExpedirRecibo,
eDarCambio
} Estados;
void init_gpio(void);
uint8_t checkBtn(uint8_t);
void app_main() {
Estados estadoActual = eStart;
uint8_t dinero_recibido = 0, cambio = 0;
while (true) {
switch (estadoActual) {
case eStart:
init_gpio(); // Configurar los puertos de entrada y salida.
// Apagar LEDs.
gpio_set_level(LED_MONEDA_DE_UNO, 0);
gpio_set_level(LED_MONEDA_DE_CINCO, 0);
gpio_set_level(LED_MONEDA_DE_DIEZ, 0);
gpio_set_level(LED_RECIBO, 0);
printf("Go!\n");
estadoActual = eEsperarDinero;
break;
case eEsperarDinero:
if (checkBtn(BOTON_MONEDA_DE_UNO)) {
printf("Se recibio 1 peso!\n");
dinero_recibido += 1;
estadoActual = eContarDinero;
}
if (checkBtn(BOTON_MONEDA_DE_CINCO)) {
printf("Se recibieron 5 pesos!\n");
dinero_recibido += 5;
estadoActual = eContarDinero;
}
if (checkBtn(BOTON_MONEDA_DE_DIEZ)) {
printf("Se recibieron 10 pesos!\n");
dinero_recibido += 10;
estadoActual = eContarDinero;
}
if (checkBtn(BOTON_MONEDA_DE_VEINTE)) {
printf("Se recibieron 20 pesos!\n");
dinero_recibido += 20;
estadoActual = eContarDinero;
}
break;
case eContarDinero:
if (dinero_recibido >= COSTO)
estadoActual = eExpedirRecibo;
else
estadoActual = eEsperarDinero;
break;
case eExpedirRecibo:
printf("Total: %d pesos.\n", dinero_recibido);
cambio = dinero_recibido - COSTO; // Calcular el cambio.
printf("Cambio: %d pesos.\n", cambio);
gpio_set_level(LED_RECIBO, 1); // Encender el LED indicador del recibo.
if (cambio)
estadoActual = eDarCambio;
else {
vTaskDelay(2000/ portTICK_PERIOD_MS); // Esperar 1 seg.
gpio_set_level(LED_RECIBO, 0); // Apagar el LED indicador del recibo.
printf("Gracias por su pago!\n");
estadoActual = eEsperarDinero;
}
dinero_recibido = 0;
break;
case eDarCambio:
do {
if (cambio >= 10) { // Corregido para >= en lugar de >
gpio_set_level(LED_MONEDA_DE_DIEZ, 1); // Dar una moneda de diez.
printf("Se devolvieron 10 pesos!\n");
vTaskDelay(1000/ portTICK_PERIOD_MS); // Pequeña pausa para visualizar
gpio_set_level(LED_MONEDA_DE_DIEZ, 0); // Apagar LEDs después de dar cambio
cambio -= 10;
}
else if (cambio >= 5) { // Corregido para >= en lugar de >
gpio_set_level(LED_MONEDA_DE_CINCO, 1); // Dar una moneda de cinco.
printf("Se devolvieron 5 pesos!\n");
vTaskDelay(1000/ portTICK_PERIOD_MS); // Pequeña pausa para visualizar
gpio_set_level(LED_MONEDA_DE_CINCO, 0); // Apagar LEDs después de dar cambio
cambio -= 5;
}
else {
gpio_set_level(LED_MONEDA_DE_UNO, 1); // Dar una moneda de uno.
printf("Se devolvio 1 peso!\n");
vTaskDelay(1000/ portTICK_PERIOD_MS); // Pequeña pausa para visualizar
gpio_set_level(LED_MONEDA_DE_UNO, 0); // Apagar LEDs después de dar cambio
cambio -= 1;
}
vTaskDelay(500/ portTICK_PERIOD_MS); // Pequeña pausa para visualizar
} while(cambio > 0);
gpio_set_level(LED_RECIBO, 0); // Apagar el LED indicador del recibo.
printf("Gracias por su pago!\n");
estadoActual = eEsperarDinero;
break;
default:
break; // Manejo de estado no esperado
}
}
}
void init_gpio(void) {
// Configurar los pines de los botones como entrada y activar pull-down.
gpio_reset_pin(BOTON_MONEDA_DE_UNO);
gpio_set_direction(BOTON_MONEDA_DE_UNO, GPIO_MODE_INPUT);
gpio_set_pull_mode(BOTON_MONEDA_DE_UNO, GPIO_PULLDOWN_ONLY);
gpio_reset_pin(BOTON_MONEDA_DE_CINCO);
gpio_set_direction(BOTON_MONEDA_DE_CINCO, GPIO_MODE_INPUT);
gpio_set_pull_mode(BOTON_MONEDA_DE_CINCO, GPIO_PULLDOWN_ONLY);
gpio_reset_pin(BOTON_MONEDA_DE_DIEZ);
gpio_set_direction(BOTON_MONEDA_DE_DIEZ, GPIO_MODE_INPUT);
gpio_set_pull_mode(BOTON_MONEDA_DE_DIEZ, GPIO_PULLDOWN_ONLY);
gpio_reset_pin(BOTON_MONEDA_DE_VEINTE);
gpio_set_direction(BOTON_MONEDA_DE_VEINTE, GPIO_MODE_INPUT);
gpio_set_pull_mode(BOTON_MONEDA_DE_VEINTE, GPIO_PULLDOWN_ONLY);
// Configurar los pines de los leds como salida.
gpio_reset_pin(LED_MONEDA_DE_UNO);
gpio_set_direction(LED_MONEDA_DE_UNO, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(LED_MONEDA_DE_UNO, GPIO_FLOATING);
gpio_reset_pin(LED_MONEDA_DE_CINCO);
gpio_set_direction(LED_MONEDA_DE_CINCO, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(LED_MONEDA_DE_CINCO, GPIO_FLOATING);
gpio_reset_pin(LED_MONEDA_DE_DIEZ);
gpio_set_direction(LED_MONEDA_DE_DIEZ, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(LED_MONEDA_DE_DIEZ, GPIO_FLOATING);
gpio_reset_pin(LED_RECIBO);
gpio_set_direction(LED_RECIBO, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(LED_RECIBO, GPIO_FLOATING);
}
uint8_t checkBtn(uint8_t pinNumber) {
vTaskDelay(50 / portTICK_PERIOD_MS); // Debounce
return gpio_get_level(pinNumber) ? 1 : 0; // Retornar estado del botón
}