#include <Arduino.h>
#include <STM32FreeRTOS.h>
// ===== Configuración del alfabeto =====
#define USAR_ALFABETO_CON_ENIE 0
// ===== Pines para segmentos del display =====
const uint8_t PINES_SEGMENTOS[7] = { D2, D3, D4, D5, D6, D7, D8 };
// ===== Display CÁTODO COMÚN =====
#define ENCENDER_SEGMENTO HIGH
#define APAGAR_SEGMENTO LOW
// Patrones de segmentos para dígitos 0-9 (a,b,c,d,e,f,g)
const uint8_t PATRONES_DIGITOS[10][7] = {
{1,1,1,1,1,1,0}, {0,1,1,0,0,0,0}, {1,1,0,1,1,0,1}, {1,1,1,1,0,0,1}, {0,1,1,0,0,1,1},
{1,0,1,1,0,1,1}, {1,0,1,1,1,1,1}, {1,1,1,0,0,0,0}, {1,1,1,1,1,1,1}, {1,1,1,1,0,1,1}
};
char textoNombre[32] = "";
volatile bool nombreRecibido = false;
// ===== Funciones utilitarias =====
uint8_t convertirLetraAPosicion(char caracter){
if (caracter >= 'a' && caracter <= 'z') caracter = caracter - 'a' + 'A';
unsigned char caracterUnsigned = (unsigned char)caracter;
#if USAR_ALFABETO_CON_ENIE
// Alfabeto con Ñ (27 letras)
if (caracterUnsigned == 0xD1 || caracterUnsigned == 0xF1) return 15;
if (caracter >= 'A' && caracter <= 'Z') {
uint8_t posicionBase = (uint8_t)(caracter - 'A') + 1;
if (caracter >= 'O') posicionBase++;
return posicionBase;
}
return 0;
#else
// Alfabeto sin Ñ (26 letras)
if (caracter >= 'A' && caracter <= 'Z') return (uint8_t)(caracter - 'A') + 1;
if (caracterUnsigned == 0xD1 || caracterUnsigned == 0xF1) return 0;
return 0;
#endif
}
void mostrarNumeroEnDisplay(uint8_t digito){
if (digito > 9) digito = 0;
for (uint8_t indiceSegmento = 0; indiceSegmento < 7; indiceSegmento++)
digitalWrite(PINES_SEGMENTOS[indiceSegmento], PATRONES_DIGITOS[digito][indiceSegmento] ? ENCENDER_SEGMENTO : APAGAR_SEGMENTO);
}
void apagarDisplayCompletamente(){
for (uint8_t indiceSegmento = 0; indiceSegmento < 7; indiceSegmento++)
digitalWrite(PINES_SEGMENTOS[indiceSegmento], APAGAR_SEGMENTO);
}
// ===== Tareas FreeRTOS =====
void tareaRecepcionSerial(void* parametro){
static uint8_t indiceBuffer = 0;
for(;;){
while (Serial.available() > 0){
char caracterEntrante = Serial.read();
static bool caracterAnteriorFueC3 = false;
if ((uint8_t)caracterEntrante == 0xC3) {
caracterAnteriorFueC3 = true;
continue;
}
if (caracterAnteriorFueC3) {
caracterAnteriorFueC3 = false;
if ((uint8_t)caracterEntrante == 0x91) caracterEntrante = (char)0xD1; // Ñ
else if ((uint8_t)caracterEntrante == 0xB1) caracterEntrante = (char)0xF1; // ñ
}
if (caracterEntrante == '\n' || caracterEntrante == '\r'){
if (indiceBuffer > 0){
textoNombre[indiceBuffer] = '\0';
indiceBuffer = 0;
nombreRecibido = true;
Serial.print("Nombre recibido: ");
Serial.println(textoNombre);
}
} else if (indiceBuffer < sizeof(textoNombre) - 1){
textoNombre[indiceBuffer++] = caracterEntrante;
}
}
vTaskDelay(pdMS_TO_TICKS(40));
}
}
void tareaControlDisplay(void* parametro){
const TickType_t TIEMPO_DIGITO = pdMS_TO_TICKS(1000); // 1 segundo por dígito
const TickType_t PAUSA_ENTRE_LETRAS = pdMS_TO_TICKS(200); // pausa entre letras
for(;;){
if (nombreRecibido){
Serial.println("Mostrando posiciones alfabeticas...");
for (uint8_t indiceLetra = 0; textoNombre[indiceLetra] != '\0'; ++indiceLetra){
uint8_t posicionAlfabetica = convertirLetraAPosicion(textoNombre[indiceLetra]);
if (!posicionAlfabetica) continue;
Serial.print("Letra: ");
Serial.print(textoNombre[indiceLetra]);
Serial.print(" -> Posicion: ");
Serial.println(posicionAlfabetica);
if (posicionAlfabetica < 10) {
mostrarNumeroEnDisplay(posicionAlfabetica);
vTaskDelay(TIEMPO_DIGITO);
} else {
uint8_t decena = (posicionAlfabetica / 10) % 10;
uint8_t unidad = posicionAlfabetica % 10;
mostrarNumeroEnDisplay(decena);
vTaskDelay(TIEMPO_DIGITO);
mostrarNumeroEnDisplay(unidad);
vTaskDelay(TIEMPO_DIGITO);
}
apagarDisplayCompletamente();
vTaskDelay(PAUSA_ENTRE_LETRAS);
}
apagarDisplayCompletamente();
nombreRecibido = false;
Serial.println("Proceso completado. Puede ingresar otro nombre:");
}
vTaskDelay(pdMS_TO_TICKS(80));
}
}
// ===== Configuración inicial =====
void setup(){
Serial.begin(9600);
#if USAR_ALFABETO_CON_ENIE
Serial.println("\n=== Sistema Display 7 Segmentos ===");
Serial.println("Configuracion: Alfabeto CON Ñ (27 letras)");
#else
Serial.println("\n=== Sistema Display 7 Segmentos ===");
Serial.println("Configuracion: Alfabeto SIN Ñ (26 letras)");
#endif
Serial.println("Display: Catodo Comun");
Serial.println("Ingrese un nombre por el monitor serial:");
Serial.println("(Configurar: 9600 baudios, Both NL & CR)");
for (uint8_t indicePin = 0; indicePin < 7; indicePin++){
pinMode(PINES_SEGMENTOS[indicePin], OUTPUT);
digitalWrite(PINES_SEGMENTOS[indicePin], APAGAR_SEGMENTO);
}
xTaskCreate(tareaRecepcionSerial, "SerialRX", 256, NULL, 2, NULL);
xTaskCreate(tareaControlDisplay, "Display", 256, NULL, 1, NULL);
vTaskStartScheduler();
}
void loop(){}