Difficulté avec Keyboard.h / Keypad.h

Halzote
jeu, 04/18/2019 - 05:04
Bonjour,
Voici quelques temps l'on m'a aidé à coder une carte Pro-Micro (puce 32u4) pour créer un game pad qui simule 8 touches sur le PC. Ca fait un moment que je l'ai et il fonctionne très bien mais j'ai un nouveau projet qui me demande d'avoir la même chose mais en matriciel pour me permettre de passer de 8 touches à une 40éne.
Donc avant de faire les choses en grand j'essaie de créer un modèle fonctionnel en 3x3 ( si j'y arrive en 3x3 je sais que le procédé sera le même pour du 7x6 ) Mais c'est plus simple et rapide d'effectuer des changements dans du 3x3 ^^ Maintenant que j'y pense j'aurais pu faire du 2x2 ahah.
Mais bref je m'égard. Alors j'ai trouver un code mais impossible de le faire fonctionner. J'ai réussi à corriger quelques erreurs me permettant de vérifier et charger le code dans le carte mais certaines choses m'échappes totalement ( je ne suis pas bon du tout en codage les tutos m'ont permis de comprendre certaines chose mais je suis de ceux qui ont du mal à comprendre si personne ne peut répondre à des questions spécifique, ce que les tutos ne permettent pas :(
Du coup je reviens ici en espérant qu'une ou plusieurs bonne âmes viendront à mon secoure ^^
Donc mon problème c'est que j'ai dû commencé à remplacer les lignes :
Keyboard.press(KEY_A); Et Keyboard.release(KEY_A);
Par :
Keyboard.press('KEY_A'); Et Keyboard.release('KEY_A');
Mais je remarque que je pourrais très bien mettre simplement 'A'
Mais bien entendu quand je veux utiliser des touches comme F2 ou Joy1 et bien ça ne fonctionne pas.
J'ai fait à nouveau vérifier le code de mon ancien projet par le programme et le (KEY_F2) fonctionne toujours alors pourquoi sur ce code ça ne fonctionne pas ?
Il y a d'autres touches que j'aimerais incorporer comme entrer, tab ou ctrl par exemple mais vu que la commande KEY_ bloque je n'y parviens pas.
Voici le code en question :
//Projet Claymore #include <Keypad.h> #include <Keyboard.h> //Dénomination des interrupteurs et mise en place de la grille matriciel const byte ROWS = 4; // Nombre de lignes const byte COLS = 4; // Nombre de colonnes char keys[ROWS][COLS] = { {'A', 'B', 'C'}, {'D', 'E', 'F'}, {'G', 'H', 'I'}, }; // PIN's de connection de la matrice selon les lignes et colones byte rowPins[ROWS] = { 2, 3, 4 }; byte colPins[COLS] = { 5, 6, 7 }; String msg; // Create the Keypad Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // MAIN PROGRAM void setup() { Serial.begin(230400); //Si ne fonctionne pas, remplacer par 9600 msg = ""; } void loop() { //keypad button press detection if (kpd.getKeys()) { for (int i = 0; i < LIST_MAX; i++) // Scan the whole keypad. { if ( kpd.key[i].stateChanged ) // Only find keys that have changed state. { //keypad button press instructions if ( kpd.key[i].kchar == 'A' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press('KEY_A'); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release('KEY_A'); break; case IDLE: msg = " IDLE."; break; } if ( kpd.key[i].kchar == 'B' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press('KEY_B'); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release('KEY_B'); break; case IDLE: msg = " IDLE."; break; } if ( kpd.key[i].kchar == 'C' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press('Key_C'); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release('Key_C'); break; case IDLE: msg = " IDLE."; break; } if ( kpd.key[i].kchar == 'D' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press('D'); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release('D'); break; case IDLE: msg = " IDLE."; break; } if ( kpd.key[i].kchar == 'E' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press('E'); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release('E'); break; case IDLE: msg = " IDLE."; break; } if ( kpd.key[i].kchar == 'F' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press(KEY_CTRL); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release(KEY_CTRL); break; case IDLE: msg = " IDLE."; break; } if ( kpd.key[i].kchar == 'G' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press(KEY_F2); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release(KEY_F2); break; case IDLE: msg = " IDLE."; break; } if ( kpd.key[i].kchar == 'H' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press(KEY_Numpad0); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release(KEY_Numpad0); break; case IDLE: msg = " IDLE."; break; } if ( kpd.key[i].kchar == 'I' ) switch (kpd.key[i].kstate) { case PRESSED: msg = " PRESSED."; Keyboard.press(KEY_Backspace); break; case HOLD: msg = " HOLD."; break; case RELEASED: msg = " RELEASED."; Keyboard.release(KEY_Backspace); break; case IDLE: msg = " IDLE."; break; } Serial.println(); Serial.print("Key "); Serial.print(kpd.key[i].kchar); Serial.println(msg); } } } }
Voilà voilà, j'espère que quelqu'un pourra m'aider à résoudre le grand mystère de ma vie ^^
Sinon merci d'avance pour ceux qui se pencherons au moins dessus :)
En revanche, bonne journée à tous! :D
Walter
jeu, 04/18/2019 - 09:06
Salut,
Il faut regarder ce que tu as dans tes fichiers d'en-tête Keyboard.h et Keypad.h mais a mon avis il ne faut pas faire les modifications que tu as faites.
Si on décompose cette instruction Keyboard.press(KEY_A);
tu as d'une pars l'appel d'une fonction d'instance(Keyboard) press et de l'autre une constante KEY_A.
Il faut vérifier le prototypage de la fonction 'press' et la valeur de la speudo constante.
Il est aussi possible que la fonction press ait plusieurs prototypage.
Mais normalement ta constante de remplacement doit être égale au caractère A
#define KEY_A 'A'
ce qui veut dire que lors de la compilation tout les mots KEY_A seront remplacer par 'A'
Que ta fonction doit avoir le prototypage suivant: void press(char pressChar);
elle prend donc un caractère et non une chaine.
un caractère s'écrit soit avec sa valeur ASCII en décimal(65), binaire ou hexadécimal(0x41), soit avec le caractère entre apostrophe 'A'.
Je n'ai pas vérifié mais je pensais que l'on ne pouvait utiliser l'apostrophe avec plusieurs caractères à l'intérieur, tu n'a pas au moins des warning à la compilation?
si tu met 'KEY_A' ou 'KEY_A', d'une la constante ne sera pas remplacer par sa valeur par le prépocesseur, de deux tu défini une chaîne de caractère.
Il faut alors q'une surcharge de la fonction 'press' corresponde à void press(char* pressChar);
et normalement les caractères 'K' 'E' 'Y" '_' 'A' seront pressés
Donc tout ça pour te dire ce si ca compile pas, il manque sûrement la définition de la constante KEY_A.
Quel est l'affichage de la log avec les instructions suivantes ?
#define KEY_A 'A' //si il y a une erreur de compilation indiquant que KEY_A est non défini
...
Serial.print("Key1:");
Serial.print('KEY_A');
Serial.print(", Key2:");
Serial.print(KEY_A);
Halzote
jeu, 04/18/2019 - 12:22
Merci de ta réponse, je t'avoue je n'ai pas tout compris mais de ce que j'ai cru saisir mon problème reviendrai au même pour les touches fonction (F2, F7, ect) non ? Si il ne comprend pas KEY_F2 lui dire plus haut que KEY_F2 c'est F2 et que là pour lui F2 ça veut ne veut rien dire ça pose problème :/
Mais je vais tester un peu de ce que j'ai saisi et puis l'on ne sait jamais ^^
Encore merci du coup de main c'est toujorus apréciable :D
Halzote
jeu, 04/18/2019 - 12:29
Ca me parle un peu plus par rapport à mon ancien code mais je voulais justement apprendre un petit peu à me servir de ces bibliothèques pour me permettre par la suite d'autres projets semblable un peu plus poussé. Mais si vraiment je n'arrive pas à déboucher sur quelque chose je prendrais note du code que tu m'as envoyé ^^.
Merci beaucoup pour ton temps et ta réponse =)
Halzote
ven, 04/19/2019 - 03:37
Merci beaucoup mais j'ai moins de soucis que vous avec le QWERTY parce que j'ai très peu de différence je suis en QWERTZ ^^ (Clavier Suisse roman ^^)
Je vais essayé tout ça et tenter d'apporter les modifications dont j'ai besoin. Je te remercie pour le temps que tu as passé à m'aider :D
Walter
jeu, 04/18/2019 - 15:58
lol, pourtant c'est normalement parlant à n'importe quel programmeur et obligatoire pour pouvoir espérer produire du code par soit même et ne pas être obligé de déprendre des autres pour changer le code d'une touche.
Je suis très étonné que tu n'y ait rien compris Brosden!!!
Halzote je t'invite à bien comprendre les notions de bases que j'ai évoquées, si toi ou n'importe qui d'ailleurs n'a pas compris, n'hésitez pas à poser des questions.
Il n'y a pas de mauvaise question pour qui veut apprendre.
Pour moi le code que tu as présenté au début doit marcher.
A tu as une erreur ou message ?
Halzote
ven, 04/19/2019 - 03:47
Et bien je suis totalement d'accord avec toi il faudrait que je m'investisse plus pour apprendre le codage mais j'avais même acheter le livre arduino pour les nuls mais au début je me suis ennuyé parce que c'était toutes des choses que j'avais déjà comprises et après j'ai plus rien compris ahah ^^ ( honte à moi je sais :') )
Alors oui j'ai un message d'erreur :
Et merci pour tes encouragements à persévérer ^^
Walter
ven, 04/19/2019 - 12:20
Il n'y a aucune honte à débuter et ce sentir largué, on est tous passer par là.
N'hésite pas à essayer du code et poser des questions si celui-ci ne fait pas ce que tu attends.
De même si tu bute sur un bouquin pose des questions.
Walter
jeu, 04/18/2019 - 23:48
Niveau honte, c'est l'hospital qui se fout de la charité!
le préprocesseur c'est ça
Alors de la chance oui, sûrement!!!
étonnamment moi j'ai une erreur de compilation, je serais currieux de voir ta sortie de compilation
Cela correspond au fait que les aspotrophes sont pour un seul caractére, là tu définie une chaine de caractères KEY_B
Tu peux regarder par là pour avoir un exemple
Un petit programme de test pour montrer la différence et que la macro KEY_A n'est pas remplacé par sa valeur A:
Bien évidement même cause, même effet il y a aussi le warning!
Ba tu demandera au centaine de millier de dèveloppeur C, qui utilise les macro et le préprocesseur tout les jours à quoi ça sert.
Du coup ce qui serait bien c'est que tu applique tes conseilles à toi même et que l'on ne t'entende plus avant un long moment(une dizaine d'année peut être), vue l'étendue de tes connaissances et de ton humilité!!!
Halzote
ven, 04/19/2019 - 09:23
Il ne faut pas s'énerver ^^
Halzote
ven, 04/19/2019 - 09:29
Non aucun soucis de ce coté là j'ai plusieurs Pro Micro du chinois et une Leonardo de chez Keyestudio que j'utilise sur un plateau d'expérimentation. Et j'ai bien configuré le programme pour que ce soit sur Leonardo. Aucune autres cartes n'est branché quand je téléverse donc je ne me trompe pas de port. J'avais eu le tour une fois et depuis je fais attention ^^
Halzote
ven, 04/19/2019 - 10:46
J'ai réglé ça mais ca ne fonctionne pas plus.
Merci de me l'avoir fait remarqué. ^^
Walter
ven, 04/19/2019 - 09:37
Qui , ba moi en fait !!!
Tu prends les autres pour des abrutis, j'en fais de même avec toi, mais tu ne semble pas apprécier d'être de l'autre coté :)
Manque de bol les marco et le prépocesseur ne servent pas à économiser des octets.
Mais pour cela faut il avoir deux sous de jugeote pour le comprendre, comme tu aime si bien le dire.
Bizarrement tu préfère rester sur les règles orthographiques, qui si tu ne l'a pas compris je m'en fou un peu.
Et aucun mot sur le fais que ton programme ne compile pas et indique que 'KEY_A' n'est pas une instruction correcte!!!
Alors je vais te le répéter car je l'ai sûrement déjà dit à une de tes identités parallèles, mon propos n'est pas de donner un tout autre code que celui qui pose problème, pour me faire mousser, mais d'essayer d'aider le demandeur à corriger son problème et de s'améliorer si possible.
Les marco étant un principe de base du C, j'estime qu'il est important pour un développeur comme Halzote, dans comprendre le fonctionnement si il veut être autonome dans ses projets.
Après chacun voit midi à ça porte, mais pour moi les warning c'est MAL :), même si ton programme tombe en marche.
Bisous Brosden ;)
Halzote
ven, 04/19/2019 - 11:09
Je t'envoie plutôt ce qu'il y a d'écrit car le site n'a pas l'air d'aimer les fichiers bloc-note ^^
Voilà j'ai tout réinstallé ce matin, supprimé mes librairies et j'ai réinstallé celles-là.
Walter
ven, 04/19/2019 - 11:08
Halzote,
tu as deux soucis qui ont la même source.
La première est un warning qui t'indique que tu essaye de mettre une chaine de caractéres dans un caractére unique et donc qu'il est tronqué à la valeur d'un 'integer'.
Comme c'est un wanring et que cela à été tronqué pour pouvoir compiler, cela n'empeche pas d'avoir ton binaire, par contre le comportement risque de ne peux être celui que tu attends.
Si ça t'intérresse on peut décortiquer ce qui ce passe vraiment dans ce cas là ?
La deuxième est ton principal problème, c'est que le code utilise une macro 'KEY_CTRL' non définie.
Cette macro fait partie d'une longue liste comme Key_C.
Normalement cette marco doit être définie par Keyboard.h
Le plus simple est de suivre la chaîne d'inclusion de fichier.
Ouvre C:\Users\Halzote\Documents\Arduino\libraries\Keyboard\Keyboard.h
normalement il devrait ressembler à ça
Dans celui-ci dessus tu peux voir que KEY_CTRL n'est pas définie, mais que KEY_LEFT_CTRL et KEY_RIGHT_CTRL le sont par contre.
Que contient le tien?
Que contient celui dans l'autre répertoire ?
E:\Program Files (x86)\Arduino\libraries\Keyboard
Halzote
ven, 04/19/2019 - 11:44
Oui j'ai vu ça il y a 10 minutes ici mais ce que je ne comprend pas du coup c'est que dans l'exemple que j'ai pris et qui était dis qu'il fonctionnait il y avait pas mal de chose qui n'allait pas mais le code datait d'il y a 3 ans, s'en serait la cause ?
Alors j'ai retoucher le code et il fonctionne, les touches maintenues le reste dans mon jeu meme si l'on en presse une autre mais j'ai un derniers soucis c'est pour le '0' ( c'est un zero ) ben ca me met un bête zero alors que j'aimerais que ça reconnaisse que c'est le zero du pavé numerique. ( oui parce que le projet est déstiné à des jeux videos ^^ ) Tu penses que je devrais essayer avec des valeur en hexadécimal pour le coup ?
Voici le code actuellement qui fonctionne bien hormis cette histoire de zero.
Je suis vraiment content que ça fonctionne :D
Walter
ven, 04/19/2019 - 11:57
Cool que ça fonctionne!
Oui je pense que c'est normale que cela mette le 0, ca doit être codeASCII que tu envois.
Il y a cette marco dans keyboard.h :#define KEY_INSERT 0xD1
essaye de remplacer
Halzote
ven, 04/19/2019 - 12:39
KEY_INSERT c'est pas la touche insert ? Celle au-dessus de Delete ?
Walter
ven, 04/19/2019 - 13:59
Ca dépend du nombre de touche de ton clavier et c'est aussi la touche 0 du pavé numérique lorsque le verrou numérique n'est pas activé.
Je n'ai pas vu la liste des 'modifiers' qui normalement sont à associer avec une touche standard, pour provoquer des fonctions supplémentaires, donc je ne sais pas si ils ont prévus les actions supplémentaires.
Donc ça ne coûte rien de tester pour voir ce qu'il se passe.
Walter
ven, 04/19/2019 - 11:40
belle finte, bien essayé, bizarrement ta fenêtre de sortie de compilation ne fait que deux lignes.
Tu as essayé de remonté ta scrollbar ou agrandir ta fenêtre de sortie.
Halzote
ven, 04/19/2019 - 11:50
C'est fait ^^
Walter
ven, 04/19/2019 - 12:15
Oui, il y a assez de ligne, effectivement tu n'a pas de warning chez toi.
Cela prouve t-il que que le préprocesseur ne sert à rien et est superflu ou peut remplacer des marco dans une chaîne ou un caractère seul, non!
Oui il y a plus d'un patron assez stupide pour m'embaucher et ça fait bientôt 20 ans que c'est mon gagne pain. Mais ils devaient être bien moins intelligent que toi :)
D'ailleurs SPY, comme je te l'ai déjà dis, j'ai travaillé en collaboration avec PcSoft, l'éditeur de ton logiciel favori ;)
Aller pour enfoncé le clou et faire mon méaculpa, je suis un gros nul qui ne mérite pas de vivre de mon métier et d'utiliser des outils aussi inutile que le préprocesseur du C.
le lien vers le wiki
Tu est vraiment trop 'intelligent' Brosden, spi, manoé, Wolfram, je doit le reconnaître.
Halzote
ven, 04/19/2019 - 12:09
On commence à avoir pas mal de bla bla je ne vois pas où tu as mis ton code désolé ^^'
C'est sur ce topic où ailleurs ?
Walter
ven, 04/19/2019 - 14:53
Ha ba voilà, c'est plus honnête que de feindre de pas vous connaître ou d'utiliser plusieurs pseudo, vu votre langage, j'aurais dis que vous étiez de la même famille, même propos haineux, condescendant et agressif.
Ha ba je serait content de me coucher moins con ce soir et que tu m'explique en quoi il s'adapte.
Je te rappel que le préprocesseur remplace un mot clé défini au préalable par sa valeur et que tu peux intervenir sur son déroulement par un jeu de commande limité précéder d'un #
As tu essayer le petit code de test que j'ai insérer un peu plus haut ?
Désolé mes je n'ai pas pu m'en empêcher :)

Walter
ven, 04/19/2019 - 21:44
Cela veut il dire que tu ne sais pas m'expliquer en quoi le prépreocesseur s'adapte au librairie?
Ba du coup au contraire si c'est définitif je suis plutôt déçu ;)
Encore manqué je n'ai pas annoncé que tu trichais, difficile de lire entre les lignes quand on est plein de préjugés!
Si mon orthographe ne peut que s'améliorer qu'en dénigrant, insultant et méprisant les autres, je préfère rester un gros con analphabète, mais chacun voit midi à sa porte.
Bonne nuit et gros bisous à toi.
Halzote
sam, 04/20/2019 - 07:16
Voyons, voyons... Les amis... Cessons ces petites querelles et ne perdons pas de vu le plus important. J'suis un mec super cool et ça c'est plutôt exceptionnel non ?! :')
Halzote
sam, 04/20/2019 - 07:29
Alors oui et non, mon code fonctionne mais je met Keyboard.press('a'); au lieu de Keyboard.press('KEY_A'); parce que j'ai remarqué qu'en fait la commande se fout totalement de KEY_ et n'écrit que la dernière lettre ^^
J'utilise les KEY_ pour les touches fonction par exemple mais sans les ' ' et ça fonctionne.
Par contre j'ai encore un problème est pas des moindre c'est que je suis infoutu de comprendre comment mettre le zéro du pavé numérique parce que dès que je met '0' ça le met en zéro du haut du clavier. C'est un peu gênant pour le paramètrage de mes touches sur mon simulateur de vol après ^^.
Walter
sam, 04/20/2019 - 22:26
D'après ce forum, il faut ajouter 0x88 au scan code de la touche que tu veux utiliser.
a priori le scan code de keypad1 est 0x59, donc keypad0 devrait être 0x62( soit 0xEA) ce qui est confirmé par le document suivant.
Si on regarde les sources on peut vérifier que F1 qui possède la valeur 0xC2 correspondant bien au scan code 0x3A + 0x88, on retrouve aussi dans le fichier cpp, le 136(0x88) qui est soustrait pour avoir le scan code des touches considérée comme "non affichable".
https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
Walter
sam, 04/20/2019 - 20:33
Lol, effectivement c'est imparable :)
Halzote
dim, 04/21/2019 - 06:18
Bon eh bien tout à l'air de fonctionné je n'ai plus qu'à finir de le mettre au propre pour mes besoins. J'le posterais une fois mis au propre. Certainement aujourd'hui ou demain.
En tout cas merci beaucoup vous m'avez bien aidé c'est génial merci cent fois :D
Walter
dim, 04/21/2019 - 08:25
Cool, n'hésite pas à poser des questions et à nous partager le résultat.
Halzote
dim, 04/21/2019 - 15:05
Voilà voilà le code comme promis ^^
J'ai juste eu un problème je n'ai pas pu utilisé delete parce que ça maintenait la touche je ne comprend pas pourquoi ça ne le fait pas avec les autres mais j'ai contourné en faisant une petite concession et en utilisant backspace à la place :)
Vous en pensez quoi ?