Por Diego Collazos, José David Jayk Vanegas y Samuel Corrales
Primero importamos las librerías del teclado matricial y TextLCD haciendo algunas modificaciones para un correcto funcionamiento.
Creamos un objeto lcd de tipo TextLCD donde indicamos cada uno de los puertos que vamos a utilizar:
TextLCD lcd(D2, D3, D4, D5, D6, D7, TextLCD::LCD16x2);
- D2: [RS], este pin controla dónde dentro de la memoria de la pantalla se va a guardar toda la información que se le envie.
- D3: [E], este pin permite el flujo de información entre el microcontrolador y la pantalla.
- D4-D7: estos pines son los que se encargan de pasar información del computador a la pantalla LCD.
Se creó un método void llamado darMensaje()
donde mostramos un mensaje de bienvenida y la interfaz de nuestro proyecto.
void darMensaje(){
lcd.printf("Bienvenido profe Juan, Arq Hard");
wait_us(2000000);
lcd.cls();
lcd.printf("Elija una opcion y presione *");
wait_us(2000000);
lcd.cls();
lcd.printf("(1) Raices de un polinomio");
wait_us(2000000);
lcd.cls();
lcd.printf("(2) Mostrar colores");
wait_us(2000000);
lcd.cls();
lcd.printf("(3) Mostrar notas");
}
Usamos el método printf()
de la librería TextLCD para mostrar un mensaje en la pantalla LCD
Usamos el método cls()
de la librería TextLCD para limpiar la pantalla LCD
Usamos el método wati_us()
de la librería TextLCD para darle un tiempo de espera al siguiente mensaje de nuestra pantalla LCD
PwmOut ledR(LED1);
PwmOut ledG(LED2);
PwmOut ledB(LED3);
PwmOut ledR(LED1);
Esta línea declara una variable llamada ledR de tipo PwmOut, que se utiliza para controlar la intensidad luminosa (brillo) de un LED. Está configurada para controlar el LED físico conectado al pin LED1 en una placa de desarrollo. La clase PwmOut se utiliza comúnmente para controlar LEDs y otros dispositivos que requieren un control preciso de la intensidad luminosa mediante modulación por anchura de pulso (PWM).
Lo mismo se hace con ledG y ledB
void setRGBColor(float red, float green, float blue) {
ledR = red;
ledG = green;
ledB = blue;
}
Definimos una función llamada setRGBColor que toma tres argumentos de tipo float: red, green y blue. Esta función se utiliza para establecer el color de los LEDs RGB controlados por ledR, ledG y ledB. La función toma los valores de intensidad luminosa para los componentes rojo, verde y azul, respectivamente, y los asigna a las variables ledR, ledG y ledB utilizando PWM para controlar el brillo de cada componente del LED RGB.
const int numRows = 4;
const int numCols = 4;
char keyMap[numRows][numCols] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
Definimos una matriz bidimensional de caracteres llamada keyMap que representa la disposición del teclado de membrana de 4 filas por 4 columnas. Lo definimos como 4x4 por si en el futuro disponemos de un teclado 4x4, esto no afecta el funcionamiento del programa.
Definimos dos arreglos de objetos que interactúan con los pines de entrada y salida digital de nuestra tarjeta de desarrollo.
DigitalOut rowPins[numRows] = {DigitalOut(D2), DigitalOut(D3), DigitalOut(D4), DigitalOut(D5)};
DigitalIn colPins[numCols] = {DigitalIn(D6), DigitalIn(D7), DigitalIn(D8), DigitalIn(D9)};
DigitalOut
es una clase que se utiliza para controlar pines de salida digital en nuestra tarjeta de desarrollo.
{DigitalOut(D2), DigitalOut(D3), DigitalOut(D4), DigitalOut(D5)}
nicializa el arreglo rowPins con cuatro objetos DigitalOut, cada uno asociado a un pin específico de la tarjeta de desarrollo (en este caso, los pines D2, D3, D4 y D5).
DigitalIn
es una clase que se utiliza para leer el estado de pines de entrada digital en una tarjeta de desarrollo.
{DigitalIn(D6), DigitalIn(D7), DigitalIn(D8), DigitalIn(D9)}
inicializa el arreglo colPins con cuatro objetos DigitalIn, cada uno asociado a un pin específico de la tarjeta de desarrollo (en este caso, los pines D6, D7, D8 y D9).
char inputBuffer[50];
int bufferIndex = 0;
bool recording = false;
Estas líneas declaran variables que se utilizarán para capturar la entrada del usuario.
inputBuffer
es un arreglo de caracteres que almacena la entrada del usuario.
bufferIndex
es un índice que se utiliza para rastrear la posición actual en inputBuffer.
recording
es una bandera que indica si el programa está actualmente capturando la entrada.
char convertToGrade(float N) {
char nota;
if (N >= 0 && N <= 3) {
nota = 'A';
} else if (N > 3 && N <= 4) {
nota = 'B';
...
}
Esta es una función llamada convertToGrade
que toma un valor numérico N
como entrada del teclado matricial y devuelve la nota alfanumérica correspondiente. Se utiliza una serie de declaraciones if
para determinar en qué condicion cae el valor N
y luego asigna la nota correspondiente a la variable nota que se declaro como un char. Es decir si el usuario ingresa el numero 1 en el teclado matricial esta fumcion devolvera un A y asi sucesivamente se van considerando las siguientes condiciones:
- Si la nota esta entre 0<=N<=3 devuelve A
- Si la nota esta entre 3<N<=4 devuelve B
- Si la nota esta entre 4<N<=5 devuelve C
- Si la nota esta entre 5<N<=7 devuelve D
- Si la nota esta entre 7<N<9 devuelve E
- Si la nota esta entre 9<=N<=10 devuelve F
void processKey(char key) {
if (key == '*' && !recording) {
recording = true; // Iniciar la grabación del número
} else if (key == '*' && recording) {
if (bufferIndex > 0) {
inputBuffer[bufferIndex] = '\0'; // Null-terminate the string
printf("Numero ingresado: %s\n", inputBuffer);
lcd.cls();
lcd.printf("Numero ingresado: %s\n", inputBuffer);
wait_us(3500000);
// Convertir la entrada a un número
float N = atof(inputBuffer);
if (N >= 0 && N <= 10) {
char nota = convertToGrade(N);
printf("Nota alfanumerica: %c\n", nota);
lcd.cls();
lcd.printf("Nota alfanumerica: %c\n", nota);
wait_us(3500000);
} else {
printf("Valor de nota no valido: %s\n", inputBuffer);
lcd.cls();
lcd.printf("Valor de nota no valido: %s\n", inputBuffer);
wait_us(3500000);
}
bufferIndex = 0;
}
recording = false; // Detener la grabación después de la conversión
} else if (recording) {
inputBuffer[bufferIndex++] = key;
}
}
void processKey(char key) {
: Esta línea define la funciónprocessKey
. Toma un argumentokey
, que representa la tecla presionada del teclado matricial.if (key == '*' && !recording) {
: Comienza una estructura condicionalif
. Se verifica si la tecla presionada es * y si la grabación no está en curso (es decir,recording
esfalse
).recording = true;
: Si la condición del primerif
se cumple, esto significa que se ha presionado * por primera vez para iniciar la grabación del número. Se establece recording entrue
para indicar que ahora estamos grabando una entrada numérica.} else if (key == '*' && recording) {
: Dentro de la estructura condicionalif
, se verifica si la tecla presionada es * nuevamente y si la grabación ya está en curso. Esto ocurre cuando el usuario presiona * por segunda vez para finalizar la grabación y convertir el número en una nota alfanumérica.if (bufferIndex > 0) {
: Se verifica sibufferIndex
es mayor que 0. Esto garantiza que haya algo eninputBuffer
para convertir antes de continuar. SibufferIndex
es 0, significa que no se ha ingresado ningún número y no hay nada que convertir.inputBuffer[bufferIndex] = '\0';
: Se coloca un carácter nulo('\0')
al final del contenido eninputBuffer
. Esto es importante porqueinputBuffer
es un arreglo de caracteres y debe estar null-terminado para que la funcionatof
funcione correctamente.printf("Número ingresado: %s\n", inputBuffer);
: Imprime el número ingresado por el usuario en termite. Esto es útil para verificar que se ha capturado correctamente el número.lcd.cls();
: Esta linea de codigo sirve para limpiar la pantalla del LCDlcd.printf("Nota alfanumerica: %c\n", nota);
: Aqui se imprime el mensaje en el LCDwait_us(3500000);
: Es el tiempo en milisegundos que se le da al mensaje,float N = atof(inputBuffer);
: Utiliza la funciónatof
para convertir la cadena eninputBuffer
en un número decimal de punto flotante (float).atof
toma la cadena y la interpreta como un número.if (N >= 0 && N <= 10) {
: Verifica si el número está dentro del rango válido, es decir, entre 0 y 10. Si no está en ese rango, se considera un valor de nota no válido.char nota = convertToGrade(N);
: Llama a la funciónconvertToGrade
para convertir el númeroN
en una nota alfanumérica y almacena el resultado en la variablenota
.printf("Nota alfanumérica: %c\n", nota);
: Imprime la nota alfanumérica calculada en termite.lcd.cls();
: Limpiamos la pantalla para imprimir un nuevo mensajelcd.printf("Nota alfanumerica: %c\n", nota);
: Imprime la nota calculada en la pantalla LCDwait_us(3500000);
: Es el tiempo de espera que se le da al mensajebufferIndex = 0;
: ReiniciabufferIndex
a 0 para estar listo para capturar un nuevo número que ingrese el usuario.recording = false;
: Finalmente, se establecerecording
enfalse
para indicar que la grabación ha terminado.} else if (recording) {
: Esta parte se ejecuta cuando no se presiona *, pero la grabación está en curso.inputBuffer[bufferIndex++] = key;
: Aquí, la tecla actual (key
) se agrega al búfer de entradainputBuffer
.bufferIndex
se utiliza como un índice para rastrear la posición actual en el búfer, y después de agregar la tecla, se incrementa para prepararse para la próxima tecla. Esto permite la captura de múltiples dígitos y caracteres para formar un número.
void mostrarNotas(){
while (true) {
for (int i = 0; i < numRows; i++) {
rowPins[i] = 0;
for (int j = 0; j < numCols; j++) {
if (!colPins[j]) {
processKey(keyMap[i][j]);
ThisThread::sleep_for(500ms); // Evita lecturas múltiples mientras la tecla está presionada
}
}
rowPins[i] = 1;
}
}
}
En la función mostrarNotas()
, se ejecuta un bucle infinito. En este bucle, se recorren todas las filas del teclado matricial y se comprueban las columnas para detectar cuándo se presiona una tecla. Cuando se detecta una tecla presionada, se llama a la función processKey
para manejarla. La pausa de 500 ms evita múltiples lecturas cuando una tecla se mantiene presionada. Luego, se cambian las filas para repetir el proceso en la siguiente fila del teclado matricial.
Este es el método que se llama en el main para la Función de Notas Alfanuméricas.
Para generas estos colores usamos la función void showColors()
Este es el método que se llama en el main para la Función de Generar colores en un LED RGB.
void showColors() {
char inputBuffer[32];
int bufferIndex = 0;
unsigned int numerosDecimales[3];
int numeroActual = 0;
while (numeroActual < 3) {
for (int i = 0; i < numRows; i++) {
rowPins[i] = 0;
for (int j = 0; j < numCols; j++) {
if (!colPins[j]) {
char keyPressed = keyMap[i][j];
if (keyPressed == '*') {
inputBuffer[bufferIndex] = '\0';
sscanf(inputBuffer, "%u", &numerosDecimales[numeroActual]);
printf("Numero %d ingresado: %u\n", numeroActual + 1, numerosDecimales[numeroActual]);
lcd.cls();
lcd.printf("Numero %d ingresado: %u\n", numeroActual + 1, numerosDecimales[numeroActual]);
wait_us(500000);
memset(inputBuffer, 0, sizeof(inputBuffer));
bufferIndex = 0;
numeroActual++;
if (numeroActual >= 3) {
break;
}
} else {
inputBuffer[bufferIndex] = keyPressed;
bufferIndex++;
}
ThisThread::sleep_for(500ms);
}
}
if (numeroActual >= 3) {
break;
}
rowPins[i] = 1;
}
}
float red = 1 - (float)(numerosDecimales[0] / 255.0f);
float green = 1 - (float)(numerosDecimales[1] / 255.0f);
float blue = 1 - (float)(numerosDecimales[2] / 255.0f);
setRGBColor(red, green, blue);
}
Esta función está diseñada para permitir al usuario seleccionar colores ingresando valores numéricos desde un teclado de membrana y luego mostrar el color correspondiente utilizando LEDs RGB.
char inputBuffer[32];
Declaramos un arreglo de caracteres llamado inputBuffer
con capacidad para almacenar hasta 32 caracteres. Este buffer se utiliza para almacenar temporalmente las teclas presionadas por el usuario en el teclado de membrana.
int bufferIndex = 0;
Inicializamos una variable llamada bufferIndex
con un valor de 0. Esta variable se utiliza para realizar un seguimiento de la posición actual en el inputBuffer, es decir, la posición donde se debe almacenar el próximo carácter ingresado.
unsigned int numerosDecimales[3];
Declaramos un arreglo de enteros sin signo llamado numerosDecimales con una longitud de 3 elementos. Este arreglo se utiliza para almacenar los 3 valores numéricos que representan la intesidad de los LEDs RED, GREEN, BLUE ingresados por el usuario desde el teclado de membrana. Por ejemplo si el usuario quiere visualizar el color rojo debe agregar estos valores [255, 0, 0] que se guardarán en el arreglo numeroDecimales
.
int numeroActual = 0;
Inicializamos una variable llamada numeroActual con un valor de 0. Esta variable se utiliza para realizar un seguimiento de cuántos valores numéricos se han ingresado hasta el momento. La función espera tres valores numéricos en total.
while (numeroActual < 3) {
Inicializamos un bucle while que se ejecutará hasta que se ingresen los tres valores numéricos que necesitamos para formar el color.
for (int i = 0; i < numRows; i++) {
Hacemos un bucle for que recorre las filas de nuestro teclado de membrana.
rowPins[i] = 0;
Establecemos en bajo (0) el pin correspondiente a la fila actual en el teclado de membrana. Esto asegura que solo se lean las teclas de una fila a la vez.
for (int j = 0; j < numCols; j++) {
Hacemos otro bucle for que recorre las columnas del teclado de membrana.
if (!colPins[j]) {
Verificamos si el pin de la columna actual en el teclado de membrana está en bajo (es decir, si una tecla se ha presionado en esa posición).
char keyPressed = keyMap[i][j];
Obtenemos el carácter asociado a la tecla presionada en la posición actual y lo guardamos en la variable keyPressed
.
if (keyPressed == '*') {
Verificamos si la tecla presionada es un asterisco (*), que en nuestro caso se utiliza como una especie de "enter".
inputBuffer[bufferIndex] = '\0';
Se agrega un carácter nulo al final del inputBuffer para convertirlo en una cadena de caracteres válida.
sscanf(inputBuffer, "%u", &numerosDecimales[numeroActual]);
Utilizamos la función sscanf para convertir la cadena almacenada en inputBuffer en un valor numérico sin signo, que se almacena en el arreglo numerosDecimales
en la posición numeroActual
.
printf("Número %d ingresado: %u\n", numeroActual + 1, numerosDecimales[numeroActual]);
Imprimimos el número recien ingresado indicando que número hemos ingresado, por ejemplo: "Número 1 ingresado: 255".
lcd.cls();
: Limpia la pantalla, para mostrar un nuevo mensaje
lcd.printf("Numero %d ingresado: %u\n", numeroActual + 1, numerosDecimales[numeroActual]);
: Imprimimos el número en la pantalla LCD recien ingresado indicando que número hemos ingresado, por ejemplo: "Número 1 ingresado: 255".
wait_us(500000);
: Es el tiempo de espera que se le da al mensaje en la LCD
memset(inputBuffer, 0, sizeof(inputBuffer));
Se borra el contenido del inputBuffer
para prepararlo para el próximo valor numérico.
bufferIndex = 0;
Se reinicia el índice del buffer a 0 para empezar a almacenar el próximo carácter desde el principio.
numeroActual++;
Se incrementa el contador de valores numéricos ingresados.
else {
inputBuffer[bufferIndex] = keyPressed;
bufferIndex++;
}
Si la tecla presionada no es un asterisco (*), se agrega al inputBuffer y se incrementa el índice del buffer para la próxima entrada.
ThisThread::sleep_for(500ms);
Se espera durante 500 milisegundos antes de leer la siguiente columna. Esto evita la lectura múltiple mientras una tecla está presionada.
rowPins[i] = 1;
Se vuelve a establecer en alto (1) el pin de la fila actual en el teclado de membrana para prepararse para la siguiente iteración del bucle for que recorre las filas.
Fin del bucle for
Fin del bucle while
float red = 1 - (float)(numerosDecimales[0] / 255.0f);
float green = 1 - (float)(numerosDecimales[1] / 255.0f);
float blue = 1 - (float)(numerosDecimales[2] / 255.0f);
setRGBColor(red, green, blue);
Después de salir del bucle while, se calculan los valores de rojo (red), verde (green) y azul (blue) en función de los valores numéricos ingresados. Estos valores se convierten en flotantes entre 0 y 1, y se utilizan para establecer el color en los LEDs RGB mediante la función setRGBColor
.
char inputBufferRaiz[50];
int bufferIndexRaiz = 0;
bool recordingRaiz = false;
Aqui declaramos variables para manejar la entrada de coeficientes.
inputBuffer
es un arreglo de caracteres que almacenará la entrada del usuario.
bufferIndex
es un índice para rastrear la posición actual en inputBuffer
.
recording
es una bandera que indica si estamos en modo de grabación de coeficientes.
unsigned int coeficientes[3];
int numeroActual = 0;
Creamos un arreglo coefficients
para almacenar los coeficientes a, b, y c del polinomio de grado 2.
coefficientIndex
es un índice para rastrear qué coeficiente se está ingresando actualmente.
void calculateRoots(int a, int b, int c) {
int discriminant = b * b - 4 * a * c;
if (discriminant > 0) {
// Dos raíces enteras
int root1 = (-b + sqrt(discriminant)) / (2 * a);
int root2 = (-b - sqrt(discriminant)) / (2 * a);
printf("Raices enteras: %d y %d\n", root1, root2);
lcd.cls();
lcd.printf("Raices: %d & %d", root1, root2); // Utilizamos una cadena de formato
wait_us(3500000);
} else if (discriminant == 0) {
// Una raíz real
int root = -b / (2 * a);
printf("Raiz entera unica: %d\n", root);
lcd.cls();
lcd.printf("Raiz unica: %d", root); // Utilizamos una cadena de formato
wait_us(3500000);
} else {
// Raíces complejas (no aplicable en este caso)
printf("El polinomio no tiene raices enteras.\n");
lcd.cls();
lcd.printf("No tiene raices"); // Utilizamos una cadena de formato
lcd.locate(0,1);
lcd.printf("enteras");
wait_us(3500000);
}
}
Definimos una función calculateRoots
que toma tres coeficientes enteros a, b y c
y calcula las raíces del polinomio de grado 2 utilizando la fórmula cuadrática o mejor conocida como formula del estudiante. La función verifica si el discriminante es mayor que 0 (dos raíces reales), igual a 0 (una raíz real) o menor que 0 (raíces complejas), y muestra las raíces en la pantalla. Se agrego lcd.cls()
para limpiar la pantalla LCD, luego lcd.printf("No tiene raices");
que imprime el mensaje y el wait_us(3500000)
el tiempo de espera que se le da al mensaje
void processKeyRaiz(char key) {
if (recordingRaiz) {
if (key == '*') {
inputBufferRaiz[bufferIndexRaiz] = '\0'; // Null-terminate the string
printf("Coeficiente %c: %s\n", 'a' + coefficientIndex, inputBufferRaiz);
lcd.cls();
lcd.printf("Coeficiente %c: %s\n", 'a' + coefficientIndex, inputBufferRaiz);
wait_us(200000);
// Interpretar '#' como signo negativo al inicio
int coefficientValue;
if (inputBufferRaiz[0] == '#') {
if (sscanf(inputBufferRaiz + 1, "%d", &coefficientValue) == 1) {
coefficientValue = -coefficientValue;
}
} else {
if (sscanf(inputBufferRaiz, "%d", &coefficientValue) != 1) {
printf("Entrada invalida. Por favor, ingrese un numero valido.\n");
lcd.cls();
lcd.printf("Entrada invalida");
wait_us(500000);
bufferIndexRaiz = 0;
return;
}
}
coefficients[coefficientIndex] = coefficientValue;
coefficientIndex++;
if (coefficientIndex < 3) {
//lcd.cls();
//lcd.printf("Ingrese coeficiente: ");
printf("Por favor, ingrese el coeficiente %c: ", 'a' + coefficientIndex);
lcd.cls();
lcd.printf("Ingrese el coeficiente %c: ", 'a' + coefficientIndex);
wait_us(500000);
bufferIndexRaiz = 0;
} else {
printf("Coeficientes: a=%d, b=%d, c=%d\n", coefficients[0], coefficients[1], coefficients[2]);
lcd.cls();
lcd.printf("Coeficientes:");
wait_us(200000);
lcd.locate(0,1);
lcd.printf("a=%d, b=%d, c=%d\n", coefficients[0], coefficients[1], coefficients[2]);
wait_us(3500000);
// Calcula las raíces
calculateRoots(coefficients[0], coefficients[1], coefficients[2]);
coefficientIndex = 0;
recordingRaiz = false;
}
} else {
inputBufferRaiz[bufferIndexRaiz++] = key;
}
} else {
if (key == '*') {
recordingRaiz = true;
printf("Por favor, ingrese el coeficiente %c: ", 'a' + coefficientIndex);
lcd.cls();
lcd.printf("Ingrese el coeficiente %c: ", 'a' + coefficientIndex);
wait_us(3500000);
bufferIndexRaiz = 0;
}
}
}
void processKey(char key) {
: Inicia la definición de la funciónprocessKey
que toma un carácterkey
como argumento.if (recording) {
: Verifica si estamos en modo de grabación. Sirecording
es true, significa que el usuario está ingresando un coeficiente.if (key == '*') {
: Comprobación si el usuario ha presionado el asterisco *, lo que indica que ha terminado de ingresar el coeficiente actual.inputBuffer[bufferIndex] = '\0';
: Establece el carácter nulo ('\0') al final del búferinputBuffer
para formar una cadena de caracteres válida.printf("Coeficiente %c: %s\n", 'a' + coefficientIndex, inputBuffer);
: Muestra en pantalla el coeficiente ingresado hasta el momento y su etiqueta ('a', 'b' o 'c').lcd.cls();
: Limpiamos la pantalla LCDlcd.printf("Coeficiente %c: %s\n", 'a' + coefficientIndex, inputBufferRaiz);
: Muestra en la LCD el coeficiente ingresado hasta el momento y su etiqueta ('a','b','c').wait_us(200000);
: Es ekl tiempo de espera que se le da al mensajeint coefficientValue;
: Declara una variablecoefficientValue
para almacenar el valor del coeficiente.if (inputBuffer[0] == '#') {
: Comprueba si el primer carácter eninputBuffer
es #, lo que indica que el usuario está ingresando un número negativo.if (sscanf(inputBuffer + 1, "%d", &coefficientValue) == 1) {
: Utilizasscanf
para analizar la parte de la cadena de caracteres después del '#' y extraer un número entero. Si la conversión tiene éxito (retorna 1), se asigna acoefficientValue
.coefficientValue = -coefficientValue;
: Si el usuario ingresó '#' al principio, se interpreta como un número negativo y se cambia el signo decoefficientValue
a negativo.} else {
: Si no se ingresó '#' al principio, se realiza el análisis normal de la cadena de caracteres.if (sscanf(inputBuffer, "%d", &coefficientValue) != 1) {
: Utiliza sscanf para analizar toda la cadena de caracteres y extraer un número entero. Si la conversión no tiene éxito, muestra un mensaje de "Entrada inválida" y reinicia el búfer y el proceso de entrada.coefficients[coefficientIndex] = coefficientValue;
: Almacena el valor del coeficiente en el arreglocoefficients
en la posición correspondiente.coefficientIndex++;
: Incrementa el índice del coeficiente para pasar al siguiente coeficiente.if (coefficientIndex < 3) {
: Verifica si todavía hay más coeficientes por ingresar. Si es así, solicita al usuario que ingrese el próximo coeficiente y reinicia el búfer para la nueva entrada.} else {
: Si se han ingresado todos los coeficientes, muestra un mensaje con los coeficientes ingresados, calcula las raíces llamando a calculateRoots, reinicia el índice del coeficiente y sale del modo de grabación.} else {
: Si el usuario no ha presionado '*', significa que está ingresando dígitos del coeficiente actual.inputBuffer[bufferIndex++] = key;
: Almacena el dígito ingresado en el búfer y aumenta el índice del búfer.}
: Cierra el bloque if que maneja el caso en que se presiona '*' para finalizar el coeficiente actual.} else {
: Si no estamos en modo de grabación, significa que el usuario ha presionado '*' para iniciar un nuevo coeficiente.if (key == '*') {
: Comprueba si el usuario ha presionado '*', lo que indica el inicio de la grabación de un nuevo coeficiente.recording = true;
: Cambia recording a true para entrar en modo de grabación.printf("Por favor, ingrese el coeficiente %c: ", 'a' + coefficientIndex);
: Muestra un mensaje solicitando al usuario que ingrese el primer coeficiente ('a', 'b' o 'c').}lcd.cls();
: Limpiamos la pantalla LCDlcd.printf("Ingrese el coeficiente %c: ", 'a' + coefficientIndex);
: Muestra un mensaje en la LCD solicitando al usuario que ingrese el primer coeficiente ('a', 'b' o 'c').wait_us(3500000);
: Es el tiempo de espera que se le da al mensajebufferIndex = 0;
: Reinicia el índice del búfer para recopilar la nueva entrada.}
: Cierra el bloque `
En sintesis processKey
maneja la entrada del usuario para que pueda ingresar coeficientes uno por uno, verificar la validez de la entrada y calcular las raíces una vez que todos los coeficientes han sido ingresados correctamente.
void llamarCalculateRoots(){
printf("Ingrese los coeficientes del polinomio de grado 2.\n");
lcd.cls();
lcd.printf("Ingrese coefts del polinomio");
wait_us(3500000);
while (true) {
for (int i = 0; i < numRows; i++) {
rowPins[i] = 0;
for (int j = 0; j < numCols; j++) {
if (!colPins[j]) {
processKeyRaiz(keyMap[i][j]);
ThisThread::sleep_for(500ms); // Evita lecturas múltiples mientras la tecla está presionada
}
}
rowPins[i] = 1;
}
}
}
En la función llamarCalculateRoots
, el programa muestra en la LCD el mensaje "Ingrese los coefts del polinomio". Luego, entramos en un bucle infinito que escanea las teclas del teclado matricial. Para cada fila y columna, llamamos a processKey
para procesar las teclas presionadas y evitar lecturas múltiples mientras una tecla está presionada.
Este es el método que se llama en el main para la Función de raices de un polinomio de grado 2.
int main() {
darMensaje();
// printf("Elija una opcion: ");
int eleccion = darEleccion();
switch (eleccion) {
case 1:
llamarCalculateRoots();
break;
case 2:
showColors();
break;
case 3:
mostrarNotas();
break;
default:
printf("Programa terminado.\n");
lcd.cls();
lcd.printf("Programa terminado.");
wait_us(3500000);
break;
}
printf("Programa terminado.\n");
lcd.cls();
lcd.printf("Programa terminado.");
wait_us(3500000);
return 0;
}
Primero se llama al metodo darMensaje();
Luego le preguntamos al usaurio que opción desea ejecutar y guardamos en la variable eleccción el número que representa la elecciónd el usuario, esté valor lo da la función darEleccion();
.
int darEleccion(){
int eleccion = -1;
// Leer la elección del usuario desde el teclado de membrana
while (eleccion < 0 || eleccion > 3) {
for (int i = 0; i < numRows; i++) {
rowPins[i] = 0;
for (int j = 0; j < numCols; j++) {
if (!colPins[j]) {
char keyPressed = keyMap[i][j];
if (keyPressed >= '0' && keyPressed <= '3') {
eleccion = keyPressed - '0';
} else if (keyPressed == '*') {
break;
}
ThisThread::sleep_for(500ms);
}
}
if (eleccion >= 0 && eleccion <= 3) {
break;
}
rowPins[i] = 1;
}
}
return eleccion;
}
int eleccion = -1;
Inicializa la variable eleccion
a -1. Esta variable se utilizará para almacenar la elección del usuario.
while (eleccion < 0 || eleccion > 3) {
Este bucle se ejecutará continuamente hasta que se ingrese una elección válida (un número entre 0 y 3).
for (int i = 0; i < numRows; i++) {
Este bucle exterior itera a través de las filas del teclado de membrana.
for (int i = 0; i < numRows; i++) {
Este bucle exterior itera a través de las filas del teclado de membrana.
rowPins[i] = 0;
Apaga la fila actual del teclado de membrana.
for (int j = 0; j < numCols; j++) {
Este bucle interior itera a través de las columnas del teclado de membrana.
if (!colPins[j]) {
Verifica si una columna está activada (cuando colPins[j] es igual a 0), lo que indica que una tecla en esa posición ha sido presionada.
char keyPressed = keyMap[i][j];
Obtiene el carácter asociado a la tecla presionada en el teclado de membrana.
if (keyPressed >= '0' && keyPressed <= '3') {
Comprueba si el carácter presionado es un número entre '0' y '3'.
eleccion = keyPressed - '0';
Si se presiona un número válido, convierte ese carácter en un valor numérico y lo almacena en la variable eleccion.
else if (keyPressed == '*') {
Si se presiona la tecla '*', significa que el usuario quiere cancelar la elección y salir del bucle.
break;
Sale del bucle interior tan pronto como se haya procesado una tecla.
ThisThread::sleep_for(500ms);
Espera durante un corto período para evitar lecturas múltiples mientras la tecla está presionada.
if (eleccion >= 0 && eleccion <= 3) {
Comprueba si se ha ingresado una elección válida (un número entre 0 y 3).
break;
Si se ingresó una elección válida, sale del bucle exterior.
rowPins[i] = 1;
Enciende nuevamente la fila del teclado de membrana para la siguiente iteración.
En resumen, este código permite al usuario seleccionar un número entre 0 y 3 en un teclado de membrana. Tan pronto como se ingresa una elección válida o se presiona la tecla '*', el bucle se detiene y la elección se almacena en la variable eleccion.
Luego se ejecutan la opción seleccionada utilizando una sentencia switch:
switch (eleccion) {
case 1:
llamarCalculateRoots();
break;
case 2:
showColors();
break;
case 3:
mostrarNotas();
break;
default:
printf("Programa terminado.\n");
lcd.cls();
lcd.printf("Programa terminado.");
wait_us(3500000);
break;
}
- Cuando el programa se esté ejecutando, deberías ver que el programa está esperando una entrada del usuario.
- Presiona la tecla * en el teclado matricial. Esto iniciará la grabación de un número.
- Luego de presionar *, puedes ingresar un número de 0 a 10 utilizando las teclas numéricas en el teclado matricial. Por ejemplo, si deseas ingresar el número 7, presiona 7, y así sucesivamente.
- Después de ingresar el número, presiona nuevamente la tecla * para finalizar la grabación del número.
- El programa tomará el número ingresado, lo convertirá en una nota alfanumérica según los rangos especificados y mostrará la letra correspondiente en la salida estándar.
- Por ejemplo, si ingresaste el número 7, el programa debería mostrar "Nota alfanumérica: D" en la salida estándar.
- Puedes repetir el proceso para ingresar y convertir otros números tantas veces como desees. nota: Si ingresas un número fuera del rango válido (0 a 10), el programa indicará que el valor de nota no es válido.
- Cuando inicia el programa, verás el mensaje inicial en la pantalla: "Ingrese los coeficientes del polinomio de grado 2."
- Presiona el botón *. La pantalla mostrará: "Por favor, ingrese el coeficiente a:" Ingresa el valor del coeficiente 'a' como un número entero. Por ejemplo, si 'a' es igual a 1, presiona los botones 1 y luego presiona * para confirmar.
- Después de ingresar 'a', la pantalla mostrará: "Por favor, ingrese el coeficiente b:" Ingresa el valor del coeficiente 'b' de la misma manera que ingresaste 'a'. Por ejemplo, si 'b' es igual a 1, presiona los botones 1 y luego presiona * para confirmar.
- Luego de ingresar 'b', la pantalla mostrará: "Por favor, ingrese el coeficiente c:" Ingresa el valor del coeficiente 'c' de la misma manera que ingresaste 'a' y 'b'. Por ejemplo, si 'c' es igual a -6, presiona los botones # y despues el 6 y luego presiona * para confirmar.
- Una vez que ingresaste 'a', 'b' y 'c', el programa mostrará un mensaje en pantalla con los coeficientes que ingresaste. Por ejemplo: "Coeficientes ingresados: a=1, b=1, c=-6".
- Luego de mostrar los coeficientes ingresados, el programa calculará automáticamente las raíces del polinomio de grado 2 utilizando la fórmula cuadrática.
- Se presiona la tecla "2" para acceder a esta función.
- Se preseiona la tecla "*" para confirmar.
- Una vez presionala la tecla "*" se introduce el valor que va a corresponder al LED RED.
- Se Se preseiona la tecla "*" para confirmar.
- Se introduce el valor que va a corresponder al LED GREEN.
- Se Se preseiona la tecla "*" para confirmar.
- Se introduce el valor que va a corresponder al LED BLUE.
- Se Se preseiona la tecla "*" para confirmar.
- Listo! ya podrás ver el color en la tarjeta