#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
#include "esp_err.h"
#define LED_ROJO 5
#define LED_AZUL 17
#define LED_VERDE 16
#define LED_VIOLETA 4
#define LEDC_TIMER LEDC_TIMER_0 // Temporizador PWM (0)
#define LEDC_MODE LEDC_LOW_SPEED_MODE // Modo de baja velocidad
#define LEDC_DUTY_RES LEDC_TIMER_16_BIT // Resolución del duty cycle (16 bits)
#define LEDC_FREQUENCY (200) // Frecuencia de salida (200 Hz)
#define CANAL_ROJO LEDC_CHANNEL_0
#define CANAL_VERDE LEDC_CHANNEL_2
#define CANAL_AZUL LEDC_CHANNEL_1
#define CANAL_VIOLETA LEDC_CHANNEL_3
volatile uint16_t led_duty; // Variable para almacenar el duty cycle
void ModificarIntensidad(int canal, float porcentaje){
led_duty = (uint16_t)(65535 * porcentaje);
ledc_set_duty(LEDC_MODE, canal, led_duty);
ledc_update_duty(LEDC_MODE, canal);
}
static void configuracionSalidaPWM(int PinLed, int canal)
{
// Configura el temporizador PWM LEDC
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_MODE, // Modo de baja velocidad
.timer_num = LEDC_TIMER, // Número de temporizador
.duty_resolution = LEDC_DUTY_RES, // Resolución de duty cycle (16 bits)
.freq_hz = LEDC_FREQUENCY, // Frecuencia (200 Hz)
.clk_cfg = LEDC_AUTO_CLK // Reloj automático
};
ledc_timer_config(&ledc_timer); // Aplica la configuración del temporizador
// Configura el canal PWM LEDC
ledc_channel_config_t ledc_channel = {
.speed_mode = LEDC_MODE, // Modo de baja velocidad
.channel = canal, // Canal asignado
.timer_sel = LEDC_TIMER, // Temporizador asociado
.intr_type = LEDC_INTR_DISABLE, // Interrupciones deshabilitadas
.gpio_num = PinLed, // Pin GPIO asignado al LED
.duty = 0, // Duty cycle inicial (0%)
.hpoint = 0 // Punto alto inicial
};
ledc_channel_config(&ledc_channel); // Aplica la configuración del canal
}
// Definir las filas y columnas del teclado matricial
#define FILA_1 13
#define FILA_2 12
#define FILA_3 14
#define FILA_4 27
#define COLUMNA_1 26
#define COLUMNA_2 25
#define COLUMNA_3 33
#define COLUMNA_4 32
// Mapeo del teclado matricial (4x4)
char keys[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
// Configurar los pines GPIO
void configurarPines() {
// Configurar filas como salidas
gpio_config_t ConfiguracionFilas = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = (1ULL << FILA_1) | (1ULL << FILA_2) | (1ULL << FILA_3) | (1ULL << FILA_4)
};
gpio_config(&ConfiguracionFilas);
// Configurar columnas como entradas con pull-up
gpio_config_t ConfiguracionColumnas = {
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE, // Habilita la resistencia pull-up interna
.pin_bit_mask = (1ULL << COLUMNA_1) | (1ULL << COLUMNA_2) | (1ULL << COLUMNA_3) | (1ULL << COLUMNA_4)
};
gpio_config(&ConfiguracionColumnas);
}
// Función para determinar el estado de cada fila
volatile int estadoFila(int fila, int filaActual) {
if (fila == filaActual) {
return 0; // Activar la fila actual (bajo)
} else {
return 1; // Mantener otras filas en alto
}
}
// Escanear el teclado matricial y devolver el valor de la tecla presionada
char scanear_keypad() {
char key = '\0'; // Inicializar como ninguna tecla presionada
// Barrido de las filas
for (int fila = 0; fila < 4; fila++) {
// Activar la fila actual
gpio_set_level(FILA_1, estadoFila(0, fila));
gpio_set_level(FILA_2, estadoFila(1, fila));
gpio_set_level(FILA_3, estadoFila(2, fila));
gpio_set_level(FILA_4, estadoFila(3, fila));
// Esperar un poco para estabilizar
vTaskDelay(10 / portTICK_PERIOD_MS);
// Leer cada columna
if (gpio_get_level(COLUMNA_1) == 0) key = keys[fila][0]; // Columna 1
if (gpio_get_level(COLUMNA_2) == 0) key = keys[fila][1]; // Columna 2
if (gpio_get_level(COLUMNA_3) == 0) key = keys[fila][2]; // Columna 3
if (gpio_get_level(COLUMNA_4) == 0) key = keys[fila][3]; // Columna 4
// Salir del bucle si se detecta una tecla
if (key != '\0') {
break;
}
}
// Restablecer todas las filas a alto
gpio_set_level(FILA_1, 1);
gpio_set_level(FILA_2, 1);
gpio_set_level(FILA_3, 1);
gpio_set_level(FILA_4, 1);
return key;
}
/*
void teclaPresionada(bool estadoTecla, char *tecla, int canal) {
if (*estadoTecla==true){
*estadoTecla=false;
tecla=*tecla+1; // Marca que el botón ha sido presionado
if(*tecla>2){
*tecla=0;
}
switch (*tecla) {
case 0:
ModificarIntensidad(canal, 0.0); // 0%
break;
case 1:
ModificarIntensidad(canal, 0.1); // 10%
break;
case 2:
ModificarIntensidad(canal, 1.0); // 100%
break;
}
}
}
*/
void app_main() {
int bandera1=0;
int bandera2=0;
int bandera3=0;
int bandera4=0;
configurarPines(); // Configurar los pines GPIO
configuracionSalidaPWM(LED_ROJO, CANAL_ROJO);
configuracionSalidaPWM(LED_AZUL, CANAL_AZUL);
configuracionSalidaPWM(LED_VERDE, CANAL_VERDE);
configuracionSalidaPWM(LED_VIOLETA, CANAL_VIOLETA);
while (1) {
// Escanear el teclado matricial
char teclaPresionada = scanear_keypad();
//ACCIONES PARA LAS TECLAS 7 8 9
if (teclaPresionada != '\0') {
if(teclaPresionada=='7'){
ModificarIntensidad(CANAL_ROJO, 0.0);
ModificarIntensidad(CANAL_AZUL, 0.0);
ModificarIntensidad(CANAL_VERDE, 0.0);
ModificarIntensidad(CANAL_VIOLETA, 0.0);
}
if(teclaPresionada=='8'){
ModificarIntensidad(CANAL_ROJO, 0.1);
ModificarIntensidad(CANAL_AZUL, 0.1);
ModificarIntensidad(CANAL_VERDE, 0.1);
ModificarIntensidad(CANAL_VIOLETA, 0.1);
}
if(teclaPresionada=='9'){
ModificarIntensidad(CANAL_ROJO, 1.0);
ModificarIntensidad(CANAL_AZUL, 1.0);
ModificarIntensidad(CANAL_VERDE, 1.0);
ModificarIntensidad(CANAL_VIOLETA, 1.0);
}
//ACIONES PARA LAS TECLAS 1 2 3 4
if(teclaPresionada=='1'){
if(bandera1==0){
ModificarIntensidad(CANAL_ROJO,1.0);
bandera1=1;
}
else{
ModificarIntensidad(CANAL_ROJO,0.0);
bandera1=0;
}
}
if(teclaPresionada=='2'){
if(bandera2==0){
ModificarIntensidad(CANAL_AZUL,1.0);
bandera2=1;
}
else{
ModificarIntensidad(CANAL_AZUL,0.0);
bandera2=0;
}
}
if(teclaPresionada=='3'){
if(bandera3==0){
ModificarIntensidad(CANAL_VERDE,1.0);
bandera3=1;
}
else{
ModificarIntensidad(CANAL_VERDE,0.0);
bandera3=0;
}
}
if(teclaPresionada=='4'){
if(bandera4==0){
ModificarIntensidad(CANAL_VIOLETA,1.0);
bandera4=1;
}
else{
ModificarIntensidad(CANAL_VIOLETA,0.0);
bandera4=0;
}
}
printf("Tecla presionada: %c\n", teclaPresionada);
vTaskDelay(500 / portTICK_PERIOD_MS); // Retraso para evitar múltiples lecturas
}
vTaskDelay(100 / portTICK_PERIOD_MS); // Esperar un poco antes de la siguiente iteración
}
}