Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento

Componentes y suministros

Arduino UNO × 1
1N4148 – Diodo de conmutación rápida de propósito general × 64
Pulsador táctil, accionamiento superior × 64
Headers de pines × 1
Registro de desplazamiento 74HC595 × 1

Herramientas y máquinas necesarias

Aplicaciones y servicios en línea

Sobre el proyecto


Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento

Actualización: He mejorado el código, ver "Actualización" al final.

Actualmente estoy trabajando en un proyecto que tendrá un teclado integrado, lo que presentó un problema: ¿cómo incluyo un teclado en el prototipo de la placa de desarrollo? No puedo usar un teclado USB ni un teclado basado en Arduino existente, porque el teclado en el proyecto real está conectado directamente al microcontrolador que maneja todas las demás funciones. Así que diseñé esta matriz de teclado de 64 teclas para prototipado basada en PCB.

Este PCB no contiene ningún CI (circuito integrado). Las filas y columnas de la matriz del teclado están conectadas directamente a los headers de pines para que el teclado pueda conectarse a un Arduino u otro microcontrolador. Es perfecto para prototipar tus proyectos que incluirán un teclado integrado.

He incluido código detallado y fuertemente comentado para hacer que funcione con cualquier placa de desarrollo compatible con Arduino que tenga suficientes pines I/O disponibles – se requieren 11 pines. El teclado tiene 64 teclas, incluyendo modificadores para shift, mayúsculas (caps), ctrl, alt, fn y "especial". También hay seis teclas adicionales que pueden usarse para lo que quieras. Cada función de cada tecla puede definirse individualmente, incluida la función de cada tecla cuando un modificador está activo. En mi opinión, esto es significativamente más útil que el código de teclado existente que limita severamente tu capacidad para personalizar el comportamiento de las teclas.

El código proporcionado imprime texto en el puerto Serie. Esto puede cambiarse fácilmente si quieres que el texto vaya a otro lugar.

Nota sobre el tamaño del programa:

El código que proporciono es bastante grande, porque no utiliza ninguna librería existente. Escribí este código completamente desde cero para permitir la personalización que requería. En un Arduino UNO, esto usa 9100 bytes (28%) de espacio de almacenamiento del programa y las variables globales usan 394 bytes (19%) de memoria dinámica.

Mi código podría ser más eficiente y ciertamente hay librerías y sketches para teclados más pequeños, pero esta es la única forma que ideé para proporcionar flexibilidad completa sobre cada tecla con cada modificador. También tiene en cuenta el uso real de un teclado. Por ejemplo, con mi código, mantener presionada la tecla Shift mientras Caps Lock está activado resultará en una letra minúscula como debe ser. Por defecto, mantener presionada la tecla FN mientras se pulsa ESC no hará nada. Pero ese comportamiento es completamente personalizable, así que puedes cambiarlo como quieras.

Suministros:

Paso 1: Cómo funciona una matriz de teclado

Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento
Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento

¿Por qué es necesaria una matriz de teclado?

Este teclado tiene 64 teclas. Si conectaras cada botón directamente a tu placa de desarrollo, necesitarías 64 pines I/O. Eso es mucho y más de lo que la mayoría de placas tienen disponibles. Para reducir eso a un número mucho más razonable podemos usar una matriz de teclado, que solo requiere un número de pines igual a la raíz cuadrada (redondeada hacia arriba) del número de teclas.

Una matriz de teclado se configura de modo que cada interruptor de tecla en una fila está conectado y cada interruptor en una columna está conectado. Cuando queremos ver qué teclas se presionan, "activamos" la primera fila y luego comprobamos cada columna. Si una columna en particular está activa, sabemos que la tecla en esa columna y fila 1 ha sido presionada. Luego desactivamos la fila 1 y activamos la fila 2, y comprobamos todas las columnas de nuevo. Después de activar todas las filas, simplemente volvemos a empezar por la primera fila.

Cómo escaneamos la matriz de teclado:

Como trabajamos con un microcontrolador, "activar" significa poner esa fila a LOW o HIGH. En este caso, ponemos la fila a LOW porque usamos las resistencias pull-up internas del microcontrolador en nuestros pines de entrada de columna. Sin una resistencia pull-up o pull-down, un pin de entrada reaccionará de forma impredecible por interferencias, registrando falsas pulsaciones.

El microcontrolador ATmega328P usado en Arduino UNO no tiene resistencias pull-down internas, solo pull-up. Así que usamos esas. Las resistencias pull-up conectan cada pin de entrada a 5V, asegurando que siempre lean HIGH hasta que se presiona un botón.

Todas las filas también están normalmente a HIGH, lo que evita que los pines de columna se conecten a los de fila haya o no un botón presionado. Pero cuando estamos listos para comprobar una fila, podemos poner esa fila a LOW. Si un botón en esa fila está presionado, esto proporciona un camino para que el pin de entrada sea llevado a tierra – resultando en que esa columna ahora lea como LOW.

En resumen: ponemos una fila a LOW y luego comprobamos qué pines de columna ahora leen LOW. Esos corresponden a botones presionados. Este proceso ocurre muy rápido, así que podemos escanear todo el teclado muchas veces por segundo. Mi código limita esto a 200 veces por segundo, equilibrando rendimiento, rebote y asegurando que cada pulsación se detecta.

Diodos, ghosting y n-key rollover:

Los diodos en el circuito evitan pulsaciones no intencionadas cuando se mantienen ciertas combinaciones de botones. Los diodos solo permiten el flujo de corriente en una dirección, lo que previene el ghosting. Si no usáramos diodos, presionar ciertas teclas podría causar que otra tecla no presionada se registrara, ya que la corriente fluye a través de los interruptores adyacentes. Esto se muestra en el gráfico simplificado donde pulsar tres teclas adyacentes hace que la tecla en la cuarta esquina se registre aunque no esté presionada. Los diodos evitan eso y permiten el "n-key rollover", lo que significa que podemos presionar tantas teclas como queramos en cualquier combinación sin problemas.

Ahorro de pines con registro de desplazamiento:

Los más avispados habréis notado que dije que una matriz de teclado requiere un número de pines igual a la raíz cuadrada del número de teclas, pero también dije que mi diseño de teclado solo requiere 11 pines. Deberían ser 16, ¿no? No, porque usamos un registro de desplazamiento 74HC595. Este registro nos permite usar solo tres pines I/O del Arduino para controlar hasta ocho pines de salida. Esos tres pines nos permiten enviar un byte (ocho bits) al registro de desplazamiento, que pone sus ocho pines de salida a HIGH o LOW. Usando el registro de desplazamiento para los pines de salida de fila, ¡ahorramos 5 pines I/O completos!

"¿Por qué no usar un registro de desplazamiento para los pines de entrada también?" preguntaréis. La respuesta más simple es que la entrada requiere un tipo diferente de registro de desplazamiento y no tenía ese tipo a mano. Pero usar un registro de desplazamiento para entrada también complica cómo leemos las columnas y puede causar problemas con ruido y "rebote". Baste decir que es un dolor de cabeza que no necesitaba asumir en este caso.

schematic.pdf

Paso 2: Diseño del PCB

Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento
Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento
Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento

Diseño esquemático

Ahora que entiendes cómo funciona una matriz de teclado, mi diseño de PCB debería ser sencillo. Diseñé el PCB en KiCAD (perdón jueces de Eagle) y empecé con el esquema. Simplemente coloqué un símbolo de botón y un símbolo de diodo, luego copié y pegué hasta tener mi cuadrícula de 64 teclas. Luego añadí dos símbolos de header de pines 1x8, uno para las filas y otro para las columnas. Un lado de los botones se conectaba en columnas y el otro en filas.

El siguiente paso fue asignar footprints (huellas) de PCB a cada uno de esos símbolos esquemáticos. La librería de footprints incluida en KiCAD tenía los footprints necesarios integrados. Cuando diseñas tus propios PCBs, debes tener mucho cuidado al elegir los footprints correctos, porque son los que realmente acabarán en tu PCB. Hay muchos componentes con footprints muy similares, pero con pasos ligeramente diferentes. Asegúrate de elegir los que coincidan con tus componentes reales.

Footprints y números de pin

Presta especial atención a los números de pin. KiCAD tiene un problema extraño donde los números de pin del símbolo esquemático del diodo no coinciden con los del footprint. Esto resulta en diodos colocados al revés, lo cual es un problema grave dada su polaridad. No detecté ese error y tuve que tirar la primera tanda de PCBs que pedí. Para arreglarlo en la segunda revisión, tuve que crear un footprint de diodo personalizado con los números de pin intercambiados.

Layout del PCB

Con el esquema hecho y los footprints asignados, pasé al layout real del PCB. El contorno de la placa se creó en Autodesk Fusion 360, se exportó como DXF y luego se importó a KiCAD en la capa Edge Cuts. La gran mayoría del trabajo después fue simplemente colocar los botones para que tuvieran un layout similar a un teclado normal.

Luego se rutearon todas las pistas. Como el layout real de botones no coincide con la matriz limpia y ordenada del esquema, esta parte se complicó un poco y tuve que recurrir a usar vias en algunos lugares. Las vias permiten rutear una pista de una capa a otra, lo cual es muy útil cuando usas una placa de 2 capas con muchas pistas superpuestas. Finalmente, añadí zonas de cobre relleno, porque es una buena práctica.

Fabricación del PCB

Con la placa diseñada, simplemente generé todas las capas y las añadí a una carpeta zip. Esa carpeta se proporciona aquí y puede subirse directamente a un servicio de fabricación de PCB como JLCPCB.

Aquí está el enlace a los archivos Gerber del PCB: https://drive.google.com/file/d/10YriLLtghV0Sb84Wm...

Paso 3: Montaje del PCB

Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento

Este es el paso más fácil, pero más tedioso de todo el proyecto. Solo suelda todos los componentes en su lugar. Son todos componentes through-hole y fáciles de soldar. Presta especial atención a la orientación de los diodos. La marca en los diodos debe coincidir con las marcas en el PCB.

En mi experiencia, fue más fácil sujetar el PCB con una tercera mano y colocar todos los diodos primero. Luego dar la vuelta a la placa y soldarlos todos, luego recortar las patas. Luego colocar todos los botones y soldarlos. Luego soldar los headers de pines en su lugar. Puedes usar headers hembra o macho, es completamente opcional. Si usas headers macho y los pones debajo de la placa, el espaciado es correcto para enchufarlos directamente en una protoboard.

Paso 4: Conectar el teclado a tu Arduino

Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento
Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento
Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento

El cableado parece complicado, pero realmente no lo es si prestas atención a dónde va todo.

Ocho cables jumpers irán del header de columnas directamente a los siguientes pines de Arduino:

Luego, coloca el registro de desplazamiento 74HC595 en tu protoboard cruzando la separación central. ¡Fíjate en la orientación del chip! El punto indica el Pin 1.

Mira el diagrama de cableado para ver dónde van las conexiones de 5V y Ground. El registro de desplazamiento tiene dos pines conectados a 5V y dos a Ground.

Solo se necesitan tres cables para conectar el registro de desplazamiento al Arduino. Son:

Por alguna razón tonta, los pines de salida del registro de desplazamiento están dispuestos de forma poco intuitiva. Presta especial atención al diagrama de pinout del registro de desplazamiento al conectarlos a tus pines de fila. Son:

Nada está conectado a los pines 0 o 1 de Arduino, porque esos también se usan para el puerto Serie y causan conflictos.

Paso 5: Subir el código a Arduino

Teclado Prototipo de 64 Teclas con Arduino: Matriz con Registros de Desplazamiento

Programa tu Arduino con el código proporcionado aquí. No hay nada especial, solo sube el código como harías con cualquier otro proyecto de Arduino.

Todo en el código tiene comentarios detallados que puedes leer, así que no entraré en mucho detalle aquí. Básicamente, los pines se configuran como entradas y salidas. El loop principal solo contiene una función de temporizador. Cada 5ms, llama a la función para escanear el teclado. Esa función llama a otra función para configurar el registro de desplazamiento antes de comprobar las columnas. Las teclas presionadas imprimen su valor en Serie.

Si quieres cambiar lo que se imprime al pulsar una tecla, solo cambia el Serial.print("_"); en la sentencia if que corresponde a la condición. Por ejemplo, puedes definir qué se imprime cuando mantienes FN y pulsas N. Lo mismo es cierto para cualquier otra tecla con cada modificador.

Muchas teclas no hacen nada en este código, porque solo imprime en Serie. Eso significa que la tecla de retroceso no tiene efecto, porque no puedes borrar del monitor Serie – esos datos ya se han recibido. Sin embargo, eres libre de cambiar eso si quieres.

Usar el teclado con tus propios proyectos

Está bien imprimir en serie, pero ese no es realmente el objetivo de este teclado. El propósito de este teclado es para prototipar proyectos más complejos. Por eso es fácil alterar la funcionalidad. Si, por ejemplo, quisieras imprimir el texto tecleado en una pantalla OLED, simplemente podrías reemplazar cada Serial.print( con display.print( o lo que requiera tu pantalla particular. La herramienta Reemplazar todo del Arduino IDE es genial para reemplazar todos de una vez.

Gracias por leer y espero que este teclado te ayude con tus proyectos.

ProtoKeyboardV1.1-Shifted.ino



Actualización 30/1/21:

Este nuevo código está completamente reescrito y funciona mejor que el original. Se hizo principalmente para solucionar un problema con mi algoritmo que impedía que los caracteres se introdujeran cada vez que se pulsaba una tecla. El código original comprobaba que una tecla en particular no fuera la última tecla pulsada. Esto causaba un problema si se mantenían pulsadas 2 o más teclas, lo que provocaba algo como "fgfgfgfgfgfgfgfgfgfg". También impedía introducir la misma tecla repetidamente muy rápido, como al escribir las dos m en "bummer".

El nuevo código resuelve ambos problemas y es también más elegante. En lugar de rastrear la última tecla pulsada, comprobamos el estado de todo el teclado y lo comparamos con el estado completo del teclado en el loop anterior. Esto significa que el loop puede ejecutarse mucho más rápido, y también puedes introducir la misma tecla una y otra vez muy rápido. El rendimiento mejora drásticamente. Todos los caracteres también están en arrays al principio, así que puedes encontrarlos y cambiarlos fácilmente. Hay arrays independientes para cada modificador. El código también es mucho más corto.

La única desventaja de este nuevo enfoque es que usa más memoria dinámica – aunque usa significativamente menos espacio de programa. En un Arduino Uno, ahora usa: 3532 bytes (10%) de espacio de almacenamiento del programa y 605 bytes (29%) de memoria dinámica.

Como bonificación, este código funciona igual de bien en microcontroladores rápidos como el ARM Cortex-M4. El temporizador de intervalo para comprobar el teclado está en microsegundos, así que funcionará igual en cualquier placa. También puedes ajustar fácilmente la frecuencia con la que se comprueba el teclado. Por defecto, ejecuta un loop cada 500 microsegundos. Se necesitan 8 loops para comprobar el teclado, para un total de 4000 microsegundos (4 milisegundos, o 250 veces por segundo) – aunque puede tardar más si el micro no es lo bastante rápido para ejecutar el código tan rápido.

Código

ProtoKeyboardV1.1-Shifted.ino Arduino
No preview (download only).
ProtoKeyboardV1-Bits.ino Arduino
/* Sketch para Teclado Prototipo V1.2
 * por Cameron Coward 30/1/21
 *
 * Probado en Arduino Uno. Requiere PCB personalizado
 * y registro de desplazamiento 74HC595.
 *
 * Más info: https://www.hackster.io/cameroncoward/64-key-prototyping-keyboard-matrix-for-arduino-4c9531 */
const int rowData = 2; // pin Data registro desplazamiento para filas
const int rowLatch = 3; // pin Latch registro desplazamiento para filas
const int rowClock = 4; // pin Clock registro desplazamiento para filas
// estos son nuestros pines de entrada de columna. Pin 0 y Pin 1 no se usan,
// porque causan problemas (presumiblemente porque son TX y RX)
const int colA = A0;
const int colB = A1;
const int colC = A2;
const int colD = A3;
const int colE = A4;
const int colF = A5;
const int colG = 5;
const int colH = 6;
// shiftRow es el byte requerido del registro desplazamiento para cada fila, rowState contendrá teclas pulsadas para cada fila
const byte shiftRow[] = {B01111111, B10111111, B11011111, B11101111, B11110111, B11111011, B11111101, B11111110};
byte rowState[] = {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000};
byte prevRowState[] = {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000};

// Códigos ASCII para teclas sin modificadores pulsados. Los modificadores son NULL (0),
// porque los comprobaremos por separado y sus valores no deben imprimirse.
const char key[] = {
  0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 0, 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 91, 93, 92, 7, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59, 39, 0, 0, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0
};
// Códigos ASCII para teclas con shift pulsado Y caps activo
const char capsShiftKey[] = {
  0, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 0, 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 123, 125, 124, 7, 97, 115, 100, 102, 103, 104, 106, 107, 108, 58, 22, 0, 0, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0
};
// Códigos ASCII para teclas con shift pulsado.
const char shiftKey[] = {
  0, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 0, 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 123, 125, 124, 7, 65, 83, 68, 70, 71, 72, 74, 75, 76, 58, 22, 0, 0, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0
};
// Códigos ASCII para teclas con ctrl pulsado.
const char ctrlKey[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0
};
// Códigos ASCII para teclas con spcl pulsado.
const char spclKey[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// Códigos ASCII para teclas con alt pulsado.
const char altKey[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// Códigos ASCII para teclas con fn pulsado.
const char fnKey[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// Códigos ASCII para teclas con caps activo
const char capsKey[] = {
  0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 0, 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 91, 93, 92, 7, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59, 39, 0, 0, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0
};

long previousKeyboardMicros = 0; // almacena última vez que se comprobó teclado
long keyboardInterval = 500; // intervalo para comprobar teclado (microsegundos)
int rowToCheck = 0; // Comprobamos una fila por loop de checkKeyboard(), esto combinado con keyboardInterval
// da al registro desplazamiento tiempo para actualizar completamente entre comprobaciones de fila
bool caps = false; // ¿está caps lock activado?
bool shift = false; // ¿está pulsado shift izquierdo o derecho?
bool capsShift = false; // ¿están shift Y caps activos?
bool ctrl = false; // ¿está pulsada tecla ctrl?
bool spcl = false; // ¿está pulsada tecla spcl?
bool alt = false; // ¿está pulsada tecla alt?
bool fn = false; // ¿está pulsada tecla function?

void setup() {
  Serial.begin(9600);
  // configurar todos los pines de columna como entradas con pull-up interno
  pinMode(colA, INPUT_PULLUP);
  pinMode(colB, INPUT_PULLUP);
  pinMode(colC, INPUT_PULLUP);
  pinMode(colD, INPUT_PULLUP);
  pinMode(colE, INPUT_PULLUP);
  pinMode(colF, INPUT_PULLUP);
  pinMode(colG, INPUT_PULLUP);
  pinMode(colH, INPUT_PULLUP);
  // salidas necesarias para controlar registro desplazamiento 74HC595
  pinMode(rowLatch, OUTPUT);
  pinMode(rowClock, OUTPUT);
  pinMode(rowData, OUTPUT);
  updateShiftRegister(B11111111); // asegurar que registro desplazamiento empiece todo HIGH
}

void loop() {
  mainTimer();
}

void mainTimer() {
  unsigned long currentMicros = micros(); // cuántos microsegundos lleva Arduino funcionando?
  if(currentMicros - previousKeyboardMicros > keyboardInterval) {
    // si tiempo transcurrido desde última comprobación supera intervalo
    // guardar última vez que se comprobó teclado
    previousKeyboardMicros = currentMicros;
    checkKeyboard(); // comprobar todas las teclas e imprimir resultados en serie
  }
}

void updateShiftRegister(byte row) {
  // esta función configura el registro desplazamiento según el byte que se le pasó
  digitalWrite(rowLatch, LOW); // poner latch LOW para poder escribir byte completo
  shiftOut(rowData, rowClock, MSBFIRST, row); // escribir ese byte
  digitalWrite(rowLatch, HIGH); // poner latch HIGH para que registro permanezca estable hasta próximo cambio
}

void checkKeyboard() {
  // configurar registro desplazamiento al valor byte de la fila actual, del array shiftRow[]
  updateShiftRegister(shiftRow[rowToCheck]);
  // Comprobar cada columna
  if (digitalRead(colA) == LOW) { bitSet(rowState[rowToCheck], 0); } else { bitClear(rowState[rowToCheck], 0); }
  if (digitalRead(colB) == LOW) { bitSet(rowState[rowToCheck], 1); } else { bitClear(rowState[rowToCheck], 1); }
  if (digitalRead(colC) == LOW) { bitSet(rowState[rowToCheck], 2); } else { bitClear(rowState[rowToCheck], 2); }
  if (digitalRead(colD) == LOW) { bitSet(rowState[rowToCheck], 3); } else { bitClear(rowState[rowToCheck], 3); }
  if (digitalRead(colE) == LOW) { bitSet(rowState[rowToCheck], 4); } else { bitClear(rowState[rowToCheck], 4); }
  if (digitalRead(colF) == LOW) { bitSet(rowState[rowToCheck], 5); } else { bitClear(rowState[rowToCheck], 5); }
  if (digitalRead(colG) == LOW) { bitSet(rowState[rowToCheck], 6); } else { bitClear(rowState[rowToCheck], 6); }
  if (digitalRead(colH) == LOW) { bitSet(rowState[rowToCheck], 7); } else { bitClear(rowState[rowToCheck], 7); }
  // poner todos los pines del registro desplazamiento a HIGH, esto evita que los valores "sangren" al siguiente loop
  updateShiftRegister(B11111111);
  rowToCheck = rowToCheck + 1; // iterar a siguiente fila
  // tras comprobar la 8ª fila, comprobar estados (pulsaciones) y volver a empezar en 1ª fila
  if (rowToCheck > 7) {
    checkPressedKeys();
    rowToCheck = 0;
  }
}

void checkPressedKeys() {
  // comprobar si alguna tecla shift está pulsada
  if (bitRead(rowState[5], 1) | bitRead(rowState[6], 4)) { shift = true; } else { shift = false; }
  // comprobar si alguna tecla ctrl está pulsada
  if (bitRead(rowState[6], 5) | bitRead(rowState[7], 3)) { ctrl = true; } else { ctrl = false; }
  // comprobar si alguna tecla spcl está pulsada
  if (bitRead(rowState[6], 6) | bitRead(rowState[7], 2)) { spcl = true; } else { spcl = false; }
  // comprobar si alguna tecla alt está pulsada
  if (bitRead(rowState[6], 7) | bitRead(rowState[7], 1)) { alt = true; } else { alt = false; }
  // comprobar si tecla FN está pulsada
  if (bitRead(rowState[7], 4)) { fn = true; } else { fn = false; }
  // comprobar si caps activo y shift pulsado
  if (shift == true && caps == true) { capsShift = true; } else { capsShift = false; }

  for (int i = 8; i >= 0; i--) { // iterar cada fila
    for (int j = 7; j >= 0; j--) { // iterar cada bit en esa fila
      bool newBit = bitRead(rowState[i], j); // comprobar estado de ese bit
      bool prevBit = bitRead(prevRowState[i], j); // comprobar estado previo de ese bit
      if ((newBit == 1) && (prevBit == 0)) { // solo permite pulsación si estado cambió a true
        int thisChar = (i * 8) + j; // calcular posición en array char
        if (capsShift == true) { processKey(capsShiftKey[thisChar]); }
        else if (shift == true) { processKey(shiftKey[thisChar]); }
        else if (ctrl == true) { processKey(ctrlKey[thisChar]); }
        else if (alt == true) { processKey(altKey[thisChar]); }
        else if (spcl == true) { processKey(spclKey[thisChar]); }
        else if (fn == true) { processKey(fnKey[thisChar]); }
        else if (caps == true) { processKey(capsKey[thisChar]); }
        else { processKey(key[thisChar]); }
      }
      if (newBit == 1) {
        bitSet(prevRowState[i], j); // poner estado previo bit a true si tecla pulsada
      } else {
        bitClear(prevRowState[i], j); // poner estado previo bit a false si tecla no pulsada, para que pueda pulsarse de nuevo
      }
    }
  }
}

void processKey(char receivedKey) {
  if (receivedKey == 7) { // comprobar funciones especiales igual que caps (añadir nuevos "else if")
    caps = !caps;
  } else {
    Serial.print(receivedKey); // si char no corresponde a función especial, simplemente imprimir ese char
  }
}

Piezas personalizadas y cajas

Sube el archivo .zip completo a tu servicio de fabricación de PCB

keyplots_4xipOSLHzg.zip

Esquemas

Proceso de manufactura

  1. Panel de control para Flight Simulator 2020 con Arduino Nano: Pantallas LCD y CDI
  2. Panel de interruptores y LEDs para Microsoft Flight Simulator 2020 con Arduino
  3. Convierte tu Teclado MIDI en Tutor de Piano Inteligente con Arduino, LEDs y MuseScore
  4. Control de Matriz LED 8×8 con Arduino Uno: Guía Paso a Paso
  5. Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
  6. Librería Eficiente de Puerto I/O de 8 Bits para Arduino – Expande el Control Digital
  7. Pantalla TFT Shield de Alto Rendimiento 2.8” para Arduino Nano – Display SPI 320×240
  8. Circuito de entrada analógica aislada para Arduino
  9. Construye una Calculadora Arduino con Pantalla LCD 16x2 y Teclado
  10. Control Experto de Motores DC: Consejos y Trucos con Controlador PID
  11. Kit de Robot de Navegación Interior Inteligente para Proyectos Arduino