Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY

Composants et fournitures

Composant Quantité
Arduino UNO 1
1N4148 – Diode commutation rapide usage général 64
Interrupteur tactile, actionnement par le haut 64
Connecteurs à broches (pin headers) 1
Registre à décalage 74HC595 1

Outils et machines nécessaires

Applications et services en ligne

À propos du projet

Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY

Mise à jour : J'ai amélioré le code, voir « Mise à jour » à la fin.

Je travaille actuellement sur un projet intégrant un clavier, ce qui posait un problème : comment inclure un clavier dans le prototype de carte de développement ? Je ne peux pas utiliser un clavier USB ou un clavier Arduino existant, car le clavier du projet réel est connecté directement au microcontrôleur qui gère toutes les autres fonctions. J'ai donc conçu cette matrice de clavier de prototypage 64 touches basée sur PCB.

Ce PCB ne contient aucun circuit intégré (CI). Les lignes et colonnes de la matrice sont connectées directement aux connecteurs à broches pour que le clavier puisse être branché sur un Arduino ou tout autre microcontrôleur. C'est parfait pour prototyper vos projets qui incluront un clavier intégré.

J'ai inclus un code détaillé et fortement commenté pour faire fonctionner le tout avec toute carte de développement compatible Arduino disposant d'assez de broches I/O – 11 broches sont nécessaires. Le clavier a 64 touches, incluant des modificateurs pour shift, verrouillage majuscules, ctrl, alt, fn et « spécial ». Il y a aussi six touches supplémentaires utilisables comme bon vous semble. Chaque touche peut avoir sa fonction définie individuellement, y compris sa fonction quand un modificateur est actif. À mon avis, c'est beaucoup plus utile que les codes de clavier existants qui limitent sévèrement votre capacité à personnaliser le comportement des touches.

Le code fourni affiche du texte sur le port Série. Cela peut facilement être modifié si vous voulez envoyer le texte ailleurs.

Note sur la taille du programme :

Le code que je fournis est assez volumineux car il n'utilise aucune bibliothèque existante. Je l'ai écrit entièrement from scratch pour permettre la personnalisation complète que je recherchais. Sur un Arduino UNO, cela utilise 9100 octets (28 %) de l'espace de stockage du programme et les variables globales utilisent 394 octets (19 %) de la mémoire dynamique.

Mon code pourrait probablement être plus efficace et il existe certainement des bibliothèques et sketches plus compacts, mais c'est le seul moyen que j'ai trouvé pour offrir une flexibilité totale sur chaque touche avec chaque modificateur. Il prend aussi en compte l'usage réel d'un clavier. Par exemple, avec mon code, appuyer sur Shift alors que Verr. Maj est activé produira une lettre minuscule comme il se doit. Par défaut, maintenir FN enfoncé en appuyant sur ÉCHAP ne fait rien. Mais ce comportement est entièrement personnalisable.

Fournitures :

Étape 1 : Comment fonctionne une matrice de clavier

Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY
Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY

Pourquoi une matrice de clavier est-elle nécessaire ?

Ce clavier a 64 touches. Si vous connectiez chaque bouton directement à votre carte de développement, vous auriez besoin de 64 broches I/O. C'est beaucoup de broches, plus que la plupart des cartes n'en ont. Pour réduire ce nombre à quelque chose de raisonnable, on utilise une matrice de clavier, qui ne nécessite qu'un nombre de broches égal à la racine carrée (arrondie au supérieur) du nombre de touches.

Une matrice de clavier est organisée de façon que chaque interrupteur d'une ligne soit connecté et chaque interrupteur d'une colonne soit connecté. Pour savoir quelles touches sont pressées, on « active » la première ligne, puis on vérifie chaque colonne. Si une colonne particulière est active, on sait que la touche à l'intersection de cette colonne et de la ligne 1 a été pressée. On désactive alors la ligne 1, on active la ligne 2, et on revérifie toutes les colonnes. Après avoir activé toutes les lignes, on recommence simplement à la première ligne.

Comment on scanne la matrice :

Comme nous travaillons avec un microcontrôleur, « activer » signifie mettre cette ligne à LOW ou HIGH. Dans ce cas, on met la ligne à LOW car on utilise les résistances de pull-up intégrées du microcontrôleur sur nos broches d'entrée de colonnes. Sans résistance de pull-up ou pull-down, une broche d'entrée réagirait de façon imprévisible à cause des interférences, ce qui enregistrerait de fausses pressions.

L'ATmega328P utilisé dans l'Arduino UNO n'a pas de résistances de pull-down intégrées, seulement des pull-up. Nous utilisons donc celles-ci. Les résistances de pull-up connectent chaque broche d'entrée à 5V, assurant qu'elles lisent toujours HIGH jusqu'à ce qu'un bouton soit pressé.

Toutes les lignes sont aussi normalement à HIGH, ce qui empêche les broches de colonnes de se connecter aux lignes qu'un bouton soit pressé ou non. Mais quand on veut vérifier une ligne, on peut mettre cette ligne à LOW. Si un bouton de cette ligne est pressé, cela crée un chemin pour que la broche d'entrée soit tirée vers la masse – résultant en cette colonne lisant maintenant LOW.

En résumé : on met une ligne à LOW, puis on vérifie quelles broches de colonnes lisent maintenant LOW. Celles-ci correspondent aux boutons pressés. Ce processus se produit très vite, permettant de scanner tout le clavier plusieurs fois par seconde. Mon code limite cela à 200 fois par seconde, équilibrant performance, rebond et détection de chaque pression.

Diodes, fantômes et n-key rollover :

Les diodes dans le circuit empêchent les pressions de touches non voulues quand certaines combinaisons de boutons sont maintenues. Les diodes ne laissent passer le courant que dans un sens, ce qui empêche le « ghosting » (touches fantômes). Sans diodes, appuyer sur certaines touches pourrait faire enregistrer une autre touche non pressée, le courant passant par les interrupteurs adjacents. C'est illustré dans le graphique simplifié où appuyer sur trois touches adjacentes fait enregistrer la touche du quatrième coin même si elle n'est pas pressée. Les diodes empêchent cela et permettent le « n-key rollover », ce qui signifie qu'on peut appuyer sur autant de touches qu'on veut dans n'importe quelle combinaison sans problème.

Économiser des broches avec un registre à décalage :

Les plus perspicaces auront remarqué que j'ai dit qu'une matrice nécessite un nombre de broches égal à la racine carrée du nombre de touches, mais que mon design n'en nécessite que 11. Ce devrait être 16, non ? Non, car nous utilisons un registre à décalage 74HC595. Ce registre nous permet d'utiliser seulement 3 broches I/O de l'Arduino pour contrôler jusqu'à 8 broches de sortie. Ces 3 broches envoient un octet (8 bits) au registre, qui met ses 8 sorties à HIGH ou LOW. En utilisant le registre à décalage pour les lignes de sortie, on économise 5 broches I/O entières !

« Pourquoi ne pas utiliser un registre à décalage pour les entrées aussi ? » demanderez-vous. La réponse simple est que l'entrée nécessite un autre type de registre à décalage que je n'avais pas sous la main. Mais utiliser un registre pour l'entrée complique aussi la lecture des colonnes et peut causer des problèmes de bruit et de « rebond ». Disons que c'est un casse-tête dont je n'avais pas besoin ici.

schematic.pdf

Étape 2 : Conception du PCB

Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY
Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY
Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY

Conception du schéma

Maintenant que vous comprenez le fonctionnement d'une matrice, mon design de PCB devrait être clair. J'ai conçu le PCB dans KiCAD (désolé les fans d'Eagle) en commençant par le schéma. J'ai simplement placé un symbole de bouton et un symbole de diode, puis copié-collé jusqu'à obtenir ma grille de 64 touches. J'ai ajouté deux symboles de connecteurs 1x8 broches, un pour les lignes et un pour les colonnes. Un côté des boutons était connecté en colonnes, l'autre en lignes.

L'étape suivante était d'assigner des empreintes (footprints) PCB à chacun de ces symboles. La bibliothèque d'empreintes incluse dans KiCAD avait les empreintes nécessaires. Quand vous concevez vos propres PCB, vous devez être très attentif au choix des empreintes, car ce sont elles qui se retrouveront réellement sur votre PCB. Beaucoup de composants ont des empreintes très similaires mais avec des pas légèrement différents. Assurez-vous de choisir celles qui correspondent à vos vrais composants.

Empreintes et numéros de broches

Faites particulièrement attention aux numéros de broches. KiCAD a un problème bizarre où les numéros de broches du symbole schéma de diode ne correspondent pas à ceux de l'empreinte. Cela résulte en des diodes montées à l'envers, ce qui est grave vu leur polarité. Je n'ai pas attrapé cette erreur et ai dû jeter le premier lot de PCB commandés. Pour corriger sur la deuxième révision, j'ai dû créer une empreinte de diode personnalisée avec les numéros de broches inversés.

Routage PCB

Schéma fait et empreintes assignées, je suis passé au routage PCB. Le contour de la carte a été créé dans Autodesk Fusion 360, exporté en DXF, et importé dans KiCAD sur le layer Edge Cuts. La grande majorité du travail ensuite a été d'arranger les boutons pour avoir une disposition proche d'un clavier normal.

Ensuite, toutes les pistes ont été routées. Comme la disposition réelle des boutons ne correspond pas à la matrice nette du schéma, cette partie fut un peu chaotique et j'ai dû utiliser des vias par endroits. Les vias permettent de router une piste d'un layer à l'autre, très utile sur une carte 2 layers avec beaucoup de pistes qui se croisent. Enfin, j'ai ajouté des zones de cuivre, car c'est une bonne pratique.

Fabrication PCB

Avec la carte conçue, j'ai simplement généré tous les layers et les ai mis dans un dossier zip. Ce dossier est fourni ici et peut être téléversé directement chez un fabricant PCB comme JLCPCB.

Lien vers les fichiers Gerber du PCB : https://drive.google.com/file/d/10YriLLtghV0Sb84Wm...

Étape 3 : Assemblage du PCB

Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY

C'est l'étape la plus facile, mais la plus fastidieuse. Soudez simplement tous les composants en place. Ce sont tous des composants traversants, faciles à souder. Faites particulièrement attention à l'orientation des diodes. La marque sur les diodes doit correspondre aux marques sur le PCB.

Dans mon expérience, il était plus facile de maintenir le PCB avec une pince tierce main et de placer toutes les diodes d'abord. Puis retourner la carte et les souder toutes, puis couper les pattes. Ensuite placer tous les boutons et les souder. Puis souder les connecteurs en place. Vous pouvez utiliser des connecteurs mâles ou femelles, c'est à vous de choisir. Si vous utilisez des mâles et les mettez sous la carte, l'espacement est correct pour les enficher directement dans une breadboard.

Étape 4 : Connecter le clavier à votre Arduino

Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY
Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY
Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY

Le câblage a l'air compliqué, mais ce n'est pas si grave si vous faites attention à où tout va.

Huit fils de liaison iront du connecteur de colonnes directement vers les broches Arduino suivantes :

Ensuite, placez le 74HC595 sur votre breadboard en traversant la rainure centrale. Notez l'orientation de la puce ! Le point indique la broche 1.

Regardez le schéma de câblage pour voir où vont les connexions 5V et Masse. Le registre a deux broches connectées à 5V et deux à la Masse.

Seuls trois fils sont nécessaires pour connecter le registre à l'Arduino :

Pour une raison obscure, les broches de sortie du registre sont organisées de façon contre-intuitive. Faites très attention au schéma de brochage du registre quand vous les connectez à vos lignes. Elles sont :

Rien n'est connecté aux broches Arduino 0 ou 1, car elles sont aussi utilisées pour le port Série et causent des conflits.

Étape 5 : Téléverser le code Arduino

Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY

Téléversez le code fourni ici sur votre Arduino. Rien de spécial, téléversez comme n'importe quel projet Arduino.

Tout dans le code est détaillé en commentaires, je n'entrerai pas dans les détails ici. En gros, les broches sont configurées en entrées/sorties. La boucle principale contient juste une fonction timer. Toutes les 5 ms, elle appelle la fonction de scan du clavier. Cette fonction appelle une fonction séparée pour configurer le registre à décalage avant de vérifier les colonnes. Les touches pressées affichent leur valeur sur le port Série.

Si vous voulez changer ce qui est affiché quand vous appuyez sur une touche, modifiez simplement le Serial.print("_"); dans le if correspondant à la condition. Par exemple, vous pouvez définir ce qui s'affiche quand vous maintenez FN et appuyez sur N. Pareil pour chaque autre touche avec chaque modificateur.

Beaucoup de touches ne font rien dans ce code, car il se contente d'afficher sur le Série. Cela veut dire que la touche backspace n'a pas d'effet, car on ne peut pas effacer du moniteur Série – les données ont déjà été reçues. Vous êtes libre de changer cela si vous le souhaitez.

Utiliser le clavier avec vos propres projets

C'est bien d'afficher sur le Série, mais ce n'est pas le but de ce clavier. Son but est le prototypage de projets plus complexes. C'est pour ça qu'il est facile d'en modifier la fonctionnalité. Si, par exemple, vous vouliez afficher le texte tapé sur un écran OLED, vous pourriez simplement remplacer chaque Serial.print( par display.print( ou ce que votre écran nécessite. L'outil Remplacer tout de l'IDE Arduino est parfait pour faire ça en une seule étape rapide.

Merci d'avoir lu et j'espère que ce clavier vous aidera dans vos projets !

ProtoKeyboardV1.1-Shifted.ino

Mise à jour du 30/01/2021 :

Ce nouveau code est entièrement réécrit et performe mieux que l'original. Cela a été fait surtout pour corriger un problème de mon algorithme qui empêchait des caractères d'être entrés à chaque pression de touche. Le code original vérifiait qu'une touche n'était pas la dernière pressée. Cela causait un problème si 2 touches ou plus étaient maintenues, produisant quelque chose comme « fgfgfgfgfgfgfgfgfgfg ». Cela empêchait aussi d'entrer la même touche très vite, comme les deux 'm' dans « bummer ».

Le nouveau code résout ces deux problèmes et est plus élégant. Au lieu de suivre la dernière touche pressée, on vérifie l'état de tout le clavier et on le compare à l'état complet du clavier au tour de boucle précédent. Cela permet à la boucle de tourner beaucoup plus vite, et vous pouvez aussi entrer la même touche très vite. La performance est dramatiquement améliorée. Tous les caractères sont aussi dans des tableaux en haut, pour les trouver et les modifier facilement. Il y a des tableaux indépendants pour chaque modificateur. Le code est aussi beaucoup plus court.

Le seul inconvénient de cette nouvelle approche est qu'elle utilise plus de mémoire dynamique – bien qu'elle utilise significativement moins d'espace programme. Sur un Arduino Uno, cela utilise maintenant : 3532 octets (10 %) de l'espace programme et 605 octets (29 %) de la mémoire dynamique.

En bonus, ce code fonctionne aussi bien sur des microcontrôleurs rapides comme le Cortex-M4 ARM. Le timer d'intervalle pour vérifier le clavier est en microsecondes, donc il performera pareil sur n'importe quelle carte. Vous pouvez aussi ajuster facilement la fréquence de vérification. Par défaut, un tour de boucle toutes les 500 microsecondes. Il faut 8 tours pour vérifier le clavier, soit 4000 microsecondes au total (4 ms, ou 250 fois par seconde) – bien que cela puisse prendre plus longtemps si le micro n'est pas assez rapide.

Code

ProtoKeyboardV1.1-Shifted.ino (Arduino)
No preview (download only).
ProtoKeyboardV1-Bits.ino (Arduino) - Code mis à jour
/* Sketch for Prototyping Keyboard V1.2
 * by Cameron Coward 1/30/21
 *
 * Tested on Arduino Uno. Requires custom PCB
 * and a 74HC595 shift register.
 *
 * More info: https://www.hackster.io/cameroncoward/64-key-prototyping-keyboard-matrix-for-arduino-4c9531 */
const int rowData = 2; // broche Data registre décalage pour lignes
const int rowLatch = 3; // broche Latch registre décalage pour lignes
const int rowClock = 4; // broche Clock registre décalage pour lignes
// broches d'entrée colonnes. Broche 0 et 1 non utilisées (TX/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 = octet requis pour chaque ligne, rowState contiendra touches pressées par ligne
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};

// Codes ASCII touches sans modificateur. Modificateurs = NULL (0), car vérifiés séparément.
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
};

// Codes ASCII touches avec shift pressé ET caps actif
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
};

// Codes ASCII touches avec shift pressé
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
};

// Codes ASCII touches avec ctrl pressé
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
};

// Codes ASCII touches avec spcl pressé
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
};

// Codes ASCII touches avec alt pressé
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
};

// Codes ASCII touches avec fn pressé
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
};

// Codes ASCII touches avec caps actif
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; // dernier temps clavier vérifié
long keyboardInterval = 500; // intervalle vérification clavier (microsecondes)
int rowToCheck = 0; // on vérifie une ligne par boucle checkKeyboard(), combiné avec keyboardInterval
// donne au registre le temps de se mettre à jour entre vérifications de lignes
bool caps = false; // verrouillage majuscules actif ?
bool shift = false; // shift gauche ou droit pressé ?
bool capsShift = false; // shift ET caps actifs ?
bool ctrl = false; // ctrl pressé ?
bool spcl = false; // spcl pressé ?
bool alt = false; // alt pressé ?
bool fn = false; // fn pressé ?

void setup() {
  Serial.begin(9600);
  // configuration toutes broches colonnes en entrées avec pull-up internes
  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);
  // sorties pour contrôler le 74HC595
  pinMode(rowLatch, OUTPUT);
  pinMode(rowClock, OUTPUT);
  pinMode(rowData, OUTPUT);
  updateShiftRegister(B11111111); // registre commence à tout HIGH
}

void loop() {
  mainTimer();
}

void mainTimer() {
  unsigned long currentMicros = micros(); // microsecondes depuis démarrage
  if (currentMicros - previousKeyboardMicros > keyboardInterval) {
    // si temps écoulé depuis dernière vérification dépasse intervalle
    previousKeyboardMicros = currentMicros; // sauvegarder dernier temps
    checkKeyboard(); // vérifier toutes touches et afficher résultats sur Série
  }
}

void updateShiftRegister(byte row) {
  // configure le registre selon l'octet passé
  digitalWrite(rowLatch, LOW); // latch LOW pour écrire octet complet
  shiftOut(rowData, rowClock, MSBFIRST, row); // écrire l'octet
  digitalWrite(rowLatch, HIGH); // latch HIGH pour stabiliser jusqu'au prochain changement
}

void checkKeyboard() {
  // configure registre pour la ligne courante depuis tableau shiftRow[]
  updateShiftRegister(shiftRow[rowToCheck]);
  // Vérifier chaque colonne
  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); }
  // remettre toutes broches registre à HIGH, évite "fuites" vers boucle suivante
  updateShiftRegister(B11111111);
  rowToCheck = rowToCheck + 1; // passer ligne suivante
  // après 8ème ligne, vérifier états (pressions) et recommencer à 1ère ligne
  if (rowToCheck > 7) {
    checkPressedKeys();
    rowToCheck = 0;
  }
}

void checkPressedKeys() {
  // vérifier si l'un des deux shift est pressé
  if (bitRead(rowState[5], 1) | bitRead(rowState[6], 4)) { shift = true; } else { shift = false; }
  // vérifier si l'un des deux ctrl est pressé
  if (bitRead(rowState[6], 5) | bitRead(rowState[7], 3)) { ctrl = true; } else { ctrl = false; }
  // vérifier si l'un des deux spcl est pressé
  if (bitRead(rowState[6], 6) | bitRead(rowState[7], 2)) { spcl = true; } else { spcl = false; }
  // vérifier si l'un des deux alt est pressé
  if (bitRead(rowState[6], 7) | bitRead(rowState[7], 1)) { alt = true; } else { alt = false; }
  // vérifier si FN pressé
  if (bitRead(rowState[7], 4)) { fn = true; } else { fn = false; }
  // vérifier caps actif et shift pressé
  if (shift == true && caps == true) { capsShift = true; } else { capsShift = false; }

  for (int i = 8; i >= 0; i--) { // itérer chaque ligne
    for (int j = 7; j >= 0; j--) { // itérer chaque bit dans la ligne
      bool newBit = bitRead(rowState[i], j); // état actuel du bit
      bool prevBit = bitRead(prevRowState[i], j); // état précédent du bit
      if ((newBit == 1) && (prevBit == 0)) { // n'autorise pression que si état changé à true
        int thisChar = (i * 8) + j; // calculer position dans tableau caractères
        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); // mettre état précédent à true si touche pressée
      } else {
        bitClear(prevRowState[i], j); // mettre état précédent à false si touche relâchée
      }
    }
  }
}

void processKey(char receivedKey) {
  if (receivedKey == 7) { // vérifier fonctions spéciales comme caps (ajouter nouveaux "else if")
    caps = !caps; // basculer caps
  } else {
    Serial.print(receivedKey); // si char ne correspond pas à fonction spéciale, simplement l'afficher
  }
}

Pièces personnalisées et boîtiers

Téléversez le fichier .zip complet chez votre fabricant PCB

keyplots_4xipOSLHzg.zip

Schémas

Processus de fabrication

  1. Panneau de contrôle Arduino Nano pour Flight Simulator 2020 – Affichage LCD et CDI
  2. Panneau commutateurs et LED pour Microsoft Flight Simulator 2020 basé sur Arduino
  3. Transformer votre Clavier MIDI en Tuteur Piano Intelligent avec Arduino, LED et MuseScore
  4. Maîtriser une matrice LED 8×8 avec Arduino Uno : Guide pas à pas
  5. Système de Surveillance Thermique Scolaire : Précis, Temps Réel et Sécurisé
  6. Bibliothèque Arduino efficace pour port E/S 8 bits — Étendez le contrôle numérique
  7. Shield TFT 2,8" haute performance pour Arduino Nano – Écran SPI 320×240
  8. Circuit d'entrée analogique isolée pour Arduino : Protection contre les parasites industriels
  9. Kit de robot de navigation intérieure intelligente pour projets Arduino