/***************************************************************************
* CONTROLADOR DE TECLADO MATRICIAL 4X4
* =================================
*
* OBJETIVO: Generar en binario el número de la tecla presionada y la señal
* DAV activa siempre que se encuentre una tecla presionada. Esta
* misma señal DAV será utilizada para detener el escaneo de los
* renglones.
* Se utiliza el timer 0 para, por medio de interrupciones, hacer
* el escaneo de los renglones con un tiempo de 20ms entre un
* renglón y otro.
*
* ARCHIVO: Teclado_johnson
* AUTOR: Pedro Quintanilla
* FECHA: octubre 2023
***************************************************************************/
int Renglones[] = {13, 12, 14, 27};
int Columnas[] = {26,25,33,32};
byte johnson;
byte col;
byte tecla = 0;
byte salida[] = {23, 22, 21, 19};
hw_timer_t * timer = NULL;
void setup() {
for (byte i=0; i<=3; i++)
pinMode(Renglones[i], OUTPUT);
for (byte i=0; i<=3; i++)
pinMode(Columnas[i], INPUT_PULLUP);
johnson = 0xfe;
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, cnt_johnson, true);
timerAlarmWrite(timer, 20000, true);
timerAlarmEnable(timer);
}
void cnt_johnson(){
byte m,j,i;
johnson = (johnson << 1) | 0x01; // Prepara el siguiente valor del Johnson
if (johnson==0xef) // Límite del Johnson
johnson = 0xfe; // Reinicia Johnson
m = 3; // Número de bits a expulsar por GPIOs
for (i; i<=3; i++){
j = pow(2,m); // MSb primero
digitalWrite(Renglones[i], (johnson & j));
m--;
}
col = 0;
// Leer las columnas y generar un nibble
col = (Columnas[3]<<3) | (Columnas[2]<<2) | (Columnas[1]<<1) | (Columnas[0]);
}
void salidas(byte N, byte b){
byte j, m, i;
m = b -1;
for (i=0; i<b; i++){
j = pow(2,m);
digitalWrite(salida[i], (N & j));
m--;
}
}
void loop() {
bool DAV = !(Columnas[0] & Columnas[1] & Columnas[2] & Columnas[3]);
byte RengCol = (johnson<<4) | col;
if (DAV==1){
timerStop(timer);
switch(RengCol){
case 0b11101110:
tecla = 0;
break;
case 0b11101101:
tecla = 1;
break;
case 0b11101011:
tecla = 2;
break;
case 0b11100111:
tecla = 3;
break;
case 0b11011110:
tecla = 4;
break;
case 0b11011101:
tecla = 5;
break;
case 0b11011011:
tecla = 6;
break;
case 0b11010111:
tecla = 7;
break;
case 0b10111110:
tecla = 8;
break;
case 0b10111101:
tecla = 9;
break;
case 0b10111011:
tecla = 10;
break;
case 0b10110111:
tecla = 11;
break;
case 0b01111110:
tecla = 12;
break;
case 0b01111101:
tecla = 13;
break;
case 0b01111011:
tecla = 14;
break;
case 0b01110111:
tecla = 15;
break;
default:
break;
}
}
else
timerStart(timer);//?????????????????????????????????????????????????????????????
}