#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
//Definir los GPIO de los leds
#define led0 GPIO_NUM_21
#define led1 GPIO_NUM_19
#define led2 GPIO_NUM_18
#define led3 GPIO_NUM_5
#define led4 GPIO_NUM_15
#define led5 GPIO_NUM_2
#define led6 GPIO_NUM_4
#define led7 GPIO_NUM_14
//Definir los GPIO de los push buttons
#define push GPIO_NUM_33
#define push1 GPIO_NUM_25
#define push2 GPIO_NUM_32
//Definir los GPIO para la máscara de bits
#define gpio_outputs ((1ULL<<led0)|(1ULL<<led1)|(1ULL<<led2)|(1ULL<<led3)|(1ULL<<led4)|(1ULL<<led5)|(1ULL<<led6)|(1ULL<<led7))
//Función para definir los leds como binario
void gpio_set_number(uint8_t numero)
{
gpio_set_level(led0, (numero >> 0 & 0x01));
gpio_set_level(led1, (numero >> 1 & 0x01));
gpio_set_level(led2, (numero >> 2 & 0x01));
gpio_set_level(led3, (numero >> 3 & 0x01));
gpio_set_level(led4, (numero >> 4 & 0x01));
gpio_set_level(led5, (numero >> 5 & 0x01));
gpio_set_level(led6, (numero >> 6 & 0x01));
gpio_set_level(led7, (numero >> 7 & 0x01));
}
// Función para definir los push como binario
uint8_t gpio_set_push ()
{
// Obtener el estado de los push
int boton1 = gpio_get_level(push);
int boton2 = gpio_get_level(push1);
int boton3 = gpio_get_level(push2);
// Interpretar el valor de los estados de los push como binario
return (boton3 << 2) |(boton2 << 1) | (boton1 << 0);
}
//Función secuencia ojo de kit
void ojo_de_kit()
{
// Encender los leds uno a uno hacia la derecha
for (int i = 1; i <= 128; i *= 2)
{
gpio_set_number(i);
vTaskDelay(300 / portTICK_PERIOD_MS);
}
// Encender los leds uno a uno en reversa
for (int i = 64; i > 1; i /= 2)
{
gpio_set_number(i);
vTaskDelay(300 / portTICK_PERIOD_MS);
}
}
// Función secuencia incremento binario
void incremento_binario()
{
// Incremento de 1 en 1
for (int i = 1; i < 256; i++)
{
gpio_set_number(i);
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
// Función secuencia corrimiento alternante hacia la derecha
void corrimiento_alternante_ala_derecha()
{
// Inicializamos en número la primer combinación
int numero = 85;
// Bucle principal
for (int i = 0; i < 4; i++)
{
// Mostramos la primer combinación en los leds
gpio_set_number(numero);
vTaskDelay(300/portTICK_PERIOD_MS);
// Mostramos la siguiente combinación (algoritmicamente, la siguiente combinación siempre es el doble de la primera)
gpio_set_number(numero * 2);
vTaskDelay(300/portTICK_PERIOD_MS);
// En la primer combinación se resta 1
if (i == 0)
{
numero -= 1;
}
// En la siguiente combinación se resta 4
else if (i == 1)
{
numero -= 4;
}
// En la siguiente combinación se resta 16
else if (i == 2)
{
numero -= 16;
}
}
}
// Función corrimiento alternante hacia la izquierda
void corrimiento_alternante_ala_izquierda()
{
// Inicializamos la primer combinación
int numero = 128;
// Bucle principal
for (int i = 0; i < 4; i++)
{
// Mostramos la primer combinación
gpio_set_number(numero);
vTaskDelay(300/portTICK_PERIOD_MS);
// Mostramos la segunda combinación (algorítmicamente siempre es la mitad de la primera)
gpio_set_number(numero / 2);
vTaskDelay(300/portTICK_PERIOD_MS);
// En la combinación 1 se suma 32
if (i == 0)
{
numero += 32;
}
// En la combinación 2 se suma 8
else if (i == 1)
{
numero += 8;
}
// En la combinación 3 se suma 2
else if (i == 2)
{
numero += 2;
}
}
}
// Función secuencia ojo de kit doble
void ojo_de_kit_doble()
{
// De los lados hacia adentro
for(int i = 128, j = 1; i > 12; i /= 2, j *= 2)
{
gpio_set_number(i + j);
vTaskDelay(300 / portTICK_PERIOD_MS);
}
// Secuencia en reversa
for (int i = 32, j = 4; i < 128; i *= 2, j /=2)
{
gpio_set_number(i + j);
vTaskDelay(300 / portTICK_PERIOD_MS);
}
}
// Función para el corrimiento alternante en una sola rutina
void corrimiento_alternante_una_rutina()
{
// Inicializamos la primer combinación que se mostrará
int numero = 85;
// Bucle del corrimiento hacia la derecha
for (int i = 0; i < 4; i++)
{
// Mostrar la primer combinación
gpio_set_number(numero);
vTaskDelay(300/portTICK_PERIOD_MS);
// Mostrar la siguiente combinación
gpio_set_number(numero * 2);
vTaskDelay(300/portTICK_PERIOD_MS);
if (i == 0)
{
numero = numero - 1;
}
else if (i == 1)
{
numero = numero - 4;
}
else if (i == 2)
{
numero = numero - 16;
}
}
// Inicializamos la primer combinación que se mostrará en reversa
numero = 128;
// Bucle del corrimiento hacia la izquierda
for (int i = 0; i < 4; i++)
{
// Mostramos la primer combinación
gpio_set_number(numero);
vTaskDelay(300/portTICK_PERIOD_MS);
// Mostramos la siguiente combinación
gpio_set_number(numero / 2);
vTaskDelay(300/portTICK_PERIOD_MS);
if (i == 0)
{
numero += 32;
}
else if (i == 1)
{
numero += 8;
}
else if (i == 2)
{
numero += 2;
}
}
}
// Función principal
void app_main()
{
// Rutina para configuración de salidas
gpio_config_t pin_conf = {}; // Estructura
pin_conf.mode = GPIO_MODE_OUTPUT; // Modo Output
pin_conf.pin_bit_mask = gpio_outputs; // Mascara de salida
pin_conf.intr_type = GPIO_INTR_DISABLE; // Desactivar interrupciones
pin_conf.pull_up_en = 0; // Quita resistencias pull up
pin_conf.pull_down_en = 0; // Quita resistencias pull down
gpio_config(&pin_conf); // Cargar configuración anterior
// Rutina para configuración de entrada (Push Buttons)
pin_conf.mode = GPIO_MODE_DEF_INPUT; // Modo Input para el botón
pin_conf.pin_bit_mask = ((1ULL << push)|(1ULL << push1)|(1ULL << push2)); // Mascara de los botones
pin_conf.intr_type = GPIO_INTR_DISABLE; // Desactivar interrupciones
pin_conf.pull_up_en = 1; // Habilitar pull-up para el botón
pin_conf.pull_down_en = 0; // Quitar resistencias pull down
gpio_config(&pin_conf); // Cargar configuración anterior
// Loop principal
while(1)
{
// Almacena el valor de los push
int botones = gpio_set_push();
// Switch para elegir la secuencia
switch (botones)
{
// Botones 100
case 3:
corrimiento_alternante_ala_izquierda();
break;
// Botones 000
case 7:
gpio_set_number(0);
break;
// Botones 010
case 5:
incremento_binario();
break;
// Botones 001
case 6:
ojo_de_kit();
break;
// Botones 011
case 4:
corrimiento_alternante_ala_derecha();
break;
// Botones 101
case 2:
ojo_de_kit_doble();
break;
//Botones 110
case 1 :
corrimiento_alternante_una_rutina();
break;
}
}
}