Projet de gamepad avec Keyboard.h

Portrait de Halzote

Bonjours tout le monde.

Je suis désoler de venir embêter avec mes questions mais je ne connais pas grand chose au codage et en temps normal je parviens à m'en sortir avec des exemples mais là je bloque.

Bon, pour commencer je vais juste expliquer mes intentions.

Je voudrais faire un petit boîtier avec 4 interrupteurs à bascule et 4 boutons poussoir.

Ce boîtier est pour le jeu de simulation spatial Elite Dangerous. 

Les 4 boutons poussoir me serviront simplement de simulation de simple pression de clavier tendis que les 4 interrupteur à bascule devront simuler une touche qui reste enfoncée. Je dis ça par peur de conflit entre les touche ou que l'ordinateur l'interprète comme un "j'appuis, je lâche, j'appuis, ect".

Mon problème c'est que quand j'appuie sur le bouton d'une lettre il va non seulement me prendre une lettre "au hasard" mais si je maintiens il fera sur le bloc note par exemple "fghabcdefghabcdefghabcdefgh" voilà en gros il fait une boucle et je ne sais pas comment la cassée à chaque lettre et surtout est-ce possible que je me serve de plusieurs lettre en même temps ? 


Voici mon code :

#include <Keyboard.h>

//Projet de PAD 8boutons pour Elite Dangerous

const int A = 3;
const int B = 4;
const int C = 5;
const int D = 6;
const int E = 7;
const int F = 8;
const int G = 9;
const int H = 10;
const int PWR = 2; //Allumer et enteindre le PAD
const int led = 12; //Sers de témoin ON/OFF
boolean flag = true;

void setup()

{
  pinMode (A, INPUT);
  pinMode (B, INPUT);
  pinMode (C, INPUT);
  pinMode (D, INPUT);
  pinMode (E, INPUT);
  pinMode (F, INPUT);
  pinMode (G, INPUT);
  pinMode (H, INPUT);
  pinMode (PWR, INPUT);
  pinMode (led, OUTPUT);

  Serial.begin(9600);
}

void loop()

{
  if (digitalRead(PWR))
  {
    Keyboard.begin();
    digitalWrite(PWR,HIGH);
    flag = false;
  }

      if (digitalRead(A))
    {
      Keyboard.press('a');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
  
      if (digitalRead(B))
    {
      Keyboard.press('b');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
  
      if (digitalRead(C))
    {
      Keyboard.press('c');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
  
      if (digitalRead(D))
    {
      Keyboard.press('d');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    } 
  
      if (digitalRead(E))
    {
      Keyboard.press('e');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    } 
  
      if (digitalRead(F))
    {
      Keyboard.press('f');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    } 
  
      if (digitalRead(G))
    {
      Keyboard.press('g');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    } 
  
      if (digitalRead(H))
    {
      Keyboard.press('h');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }

  else
  {
    if(!flag)
    {
      Keyboard.end();
      digitalWrite(led, LOW);
      flag = true;
    }
  }
}

J'éspère que quelqu'un saura m'aider mais dans le pire des cas merci quand même ^^'

Bonne journée à tous.

Portrait de brossden

Bonjour Halzote

Tu n'embêtes personne ici ce site existe pour les débutants aussi bien que les programmeurs chevronnés, Tout le monde a été débutant !

Premièrement quel type de carte utilises tu ?

dans un deuxième temps je ne vois pas la ligne :

Keyboard.begin();

dans ton code ( dans le void Setup() )

Et enfin peux tu nous faire un schéma de câblage de tes boutons sur les entrées arduino, C'est très important !

Je ne suis pas chez moi donc je ne peux pas tester mais essaye déjà cela !

Bonne journée à tous

Portrait de brossden

Pas de réponse il faut croire que tu as résolu ton problème !

Portrait de Halzote

Salutation, non pas du tout résolut j'ai vu la réponse dans mon lit juste avant de dormir et je me suis à peine levé ^^'.

Oui j'ai suivi l'exemple qui mettait le Keyboard.begin(); dans le "void loop()" pour que ce soit possible de d'éteindre avec un interrupteur c'est donc une erreur ? 

Pour la carte j'utilise une arduino micro pour sa petite taille mais aussi pour sa 32u4. 

sizzling_turing.png

Pour la voir en grande : http://www.hostpic.org/images/1807102331370114.png

Voici le schéma j'espère qu'il est bien visible et compréhensible je n'ai pas bien l'habitude =3  

Merci de ta réponse c'est vraiment agréable d'être aussi bien reçu :)

Portrait de brossden

Je n'aurais pas le temps les deux jours qui viennent mais vendredi je me pencherai sur ce projet.

Portrait de Halzote

Pas de soucis c'est déjà très gentil de ta pare merci beaucoup :)

Portrait de brossden

Bonjour Halzote

Le problème est tout simple, tu as laissé les pins INPUT libres de potentiel lorsque aucun bouton n'est actif, de se fait ils peuvent passer de HIGH à LOW librement sous l'influence de n'importe quel champs électrique (comme le réseau EDF de ton logement).

Il y a donc deux possibilités l'une seulement soft (programme) et une seconde hard (modif de câblage)

Je vais commencer par la seconde.

Tu vas devoir acquérir si tu n'en a pas déjà 8 résistances de valeurs comprises entre 2.2 K Ohms et 50 K Ohms. Ces résistances devront être positionnées entre chacune des entrées 3,4,5,6,7,8,9 et 10 et la masse (GND) GrouND en anglais ! Cela pour forcer les entrées à l'état bas lorsque aucun bouton n'est activé.

Tu devrais avoir un résultat immédiat.

La première solution soft, pour moi la plus simple et surtout la meilleure, est de modifier le programme comme un peu plus bas.

On va programmer le processeur pour qu'il mette lui même des résistances interne à la puce électronique par la commande

pinMode(x,INPUT_PULLUP);

de ce fait le processeur va passer à l'état HAUT toutes ces entrées car la commande INPUT_PULLDOWN n'éxiste pas !

Tu devras donc passer le commun de tous tes boutons au 0 Volt (GND)

Dans le programme enfin on verifira que les entrées passe à l'état LOW pour simuler une touche !

Voici donc le bon code pour cette solution, mes modifs sont en Gras !

Il va quand même, je pense y avoir un petit problème, mais je te laisse le régler tout seul :o), si vraiment tu ne trouves pas, je te donnerai la solution (indice >>> combinaison de touches !!)

//Projet de PAD 8boutons pour Elite Dangerous

#include <Keyboard.h>
const int A = 3;
const int B = 4;
const int C = 5;
const int D = 6;
const int E = 7;
const int F = 8;
const int G = 9;
const int H = 10;
const int PWR = 2; //Allumer et enteindre le PAD
const int led = 12; //Sers de témoin ON/OFF
boolean flag = true;

void setup()

{
  pinMode (A, INPUT_PULLUP);
  pinMode (B, INPUT_PULLUP);
  pinMode (C, INPUT_PULLUP);
  pinMode (D, INPUT_PULLUP);
  pinMode (E, INPUT_PULLUP);
  pinMode (F, INPUT_PULLUP);
  pinMode (G, INPUT_PULLUP);
  pinMode (H, INPUT_PULLUP);
  pinMode (PWR, INPUT_PULLUP);
 
pinMode (led, OUTPUT);

  Serial.begin(9600);
}

void loop()

{
  if (digitalRead(PWR))
  {
    Keyboard.begin();
    digitalWrite(PWR,HIGH);
    flag = false;
  }

      if (digitalRead(A)==0)
    {
      Keyboard.press('a');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
 
      if (digitalRead(B)==0)
    {
      Keyboard.press('b');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
 
      if (digitalRead(C)==0)
    {
      Keyboard.press('c');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
 
      if (digitalRead(D)==0)
    {
      Keyboard.press('d');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
 
      if (digitalRead(E)==0)
    {
      Keyboard.press('e');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
 
      if (digitalRead(F)==0)
    {
      Keyboard.press('f');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
 
      if (digitalRead(G)==0)
    {
      Keyboard.press('g');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }
 
      if (digitalRead(H)==0)
    {
      Keyboard.press('h');
      delay(100);
      Keyboard.releaseAll();
      delay(100);
    }

  else
  {
    if(!flag)
    {
      Keyboard.end();
      digitalWrite(led, LOW);
      flag = true;
    }
  }
}

Bonne journée à tous

P.S : Attention ce code ne fonctionne qu'avec certaines cartes Arduino les 'Léonardo' par exemple car la bibliothèque "Keyboard.h" n'est pas développée pour les cartes classiques

Portrait de Halzote

Merci Brossden, je n'y arrive pas mais je vais essayer quand même, ce projet est assez important pour moi et puis j'ai déjà commandé tout ce qu'il me fallait ahah :p 

Portrait de brossden

Comment cela tu n'y arrive pas ? Tu n'arrive pas à quoi ?

Tu as commandé quoi de plus ?

Avec la solution Soft tu n'as besoin de rien de plus qu ce que tu as déjà ??

Explique moi mieux ton ou tes problèmes !

Portrait de Halzote

Ahah excuses-moi c'est vrai que mon message prête à confusion.

Pour commencé j'ai juste commandé les composant que je souhaite pour le projet une fois que j'aurais réussi. Comme un boîtier pour l'installer et des interrupteurs à LED ect donc ne t'en fais pas ^^.

Et bien je pense que j'ai mal saisi tes explications parce que que je retombe dans la même boucle en fait et ça refait ABCDEFG ect.

Et je ne sais décidément pas pourquoi je n'arrive pas à se faire allumer la LED témoins. 

Enfin bref j'avoue que je me sens un peu stupide :')

 

Portrait de brossden

Quand j'ai lu ton premier topic je pensais que tu n'avais de problème qu'avec l'affichage aléatoire mais en reprenant tout depuis le début je me suis rendu compte que ce n'était pas le seul problème et j'ai repris complètement le code. Dans la vidéo qui suit remarque bien le câblage de BP qui sont reliés à la masse par des queues de résistances. C'est surtout visible pendant le zoom sur le "Clavier".

Je n'ai pas câblé l'ensemble des boutons poussoirs (BP) car je n'en ai pas plus ! Donc en partant de la droite vers la gauche tu as le BP "a", "b", "c" et "d" puis un bouton Shift (Majuscule) et enfin BP "Marche/Arrêt" 'Toggle' c'est à dire un coup c'est "ON" et autre coup c'est "OFF" et la led confirme ces deux états. le BP Shift peut très bien être remplacé par un interrupteur à deux états stables.

Donc je te propose de regarder la vidéo qui suit et me dire si c'est à peu près ce que tu désires réaliser.j'ai fait cela vite fait ce matin donc pardonne moi le montage.

Du coté droit tu vas voir apparaître la console série qui te permet de vérifier l'état des BP "Marche Arrêt" et "Shift", en haut sur la ligne de commande tu verras le résultat de la simulation d'un clavier. J'espère avoir tous réaliser ce que tu voulais dans ton projet sinon précise moi ce qui ne correspond pas à ce dernier !

DemoGamePad

Si tout correspond à ce que tu veux je te donnerai le code !

P.S. : Après vérification dans la librairie Keyboard.begin() et Keyboard.end() ne servent à rien encore un bug de plus dans ces fameuses librairies dont je préfère me passer car c'est très souvent développé à la petite semaine !!

Portrait de Halzote

Mdr t'es un chef alors c'est exactement ça sauf que le on off du boîtier j'aurais plutôt préféré le mettre avec un bouton  à état mais sinon ouais c'est exactement ça c'est vraiment gentil de ta pare d'avoir pris du temps pour m'aider tu ne te rend pas compte de ce que ça représente pour moi de pouvoir concrétiser mon idée et en plus je vais pouvoir en faire profiter tout les autre pilotes du jeu qui sont comme moi et qui n'y connaissent pas grand chose :D 

(Oui mon but c'est aussi de partager mes idées ^^ ) 
 

Portrait de brossden

Puisque tu ne vois pas de problème en dehors du marche arrêt je te donne le code que tu pourras facilement modifier à ta sauce !

Attention pour écrire un a c'est un q qu'il faut coder c'est à cause du clavier français idem pour le z etc...

Il faut aussi changer le débit du port série !!!

//Projet de PAD 8boutons pour Elite Dangerous

#include <Keyboard.h>
const int A = 3;
const int B = 4;
const int C = 5;
const int D = 6;
const int E = 7;
const int F = 8;
const int G = 9;
const int SHIFT = 10;
const int PWR = 2; //Allumer et enteindre le PAD
const int led = 12; //Sers de témoin ON/OFF
boolean flag = true;

void setup()

{
  Serial.begin(230400);
  pinMode (A, INPUT_PULLUP);
  pinMode (B, INPUT_PULLUP);
  pinMode (C, INPUT_PULLUP);
  pinMode (D, INPUT_PULLUP);
  pinMode (E, INPUT_PULLUP);
  pinMode (F, INPUT_PULLUP);
  pinMode (G, INPUT_PULLUP);
  pinMode (SHIFT, INPUT_PULLUP);
  pinMode (PWR, INPUT_PULLUP);
  pinMode (led, OUTPUT);
  digitalWrite(led, LOW);

  Keyboard.begin();

  //Serial.begin(9600);
}

void loop()

{
  if (digitalRead(PWR) == 0)
  {
    //Serial.println(digitalRead(led));
    if (digitalRead(led) == HIGH) {
      digitalWrite(led, LOW);
      Serial.println("KeyBoard OFF");
    }
    else {
      digitalWrite(led, HIGH);
      Serial.println("KeyBoard ON");
    }
    while (digitalRead(PWR) == 0) {

    }
    delay(10);

  }
  if (digitalRead(led) == HIGH) {
    if (digitalRead(A) == 0)
      KeyPress('q', 'Q');

    if (digitalRead(B) == 0)
      KeyPress('b', 'B');

    if (digitalRead(C) == 0)
      KeyPress('c', 'C');

    if (digitalRead(D) == 0)
      KeyPress('d', 'D');

    if (digitalRead(E) == 0)
      KeyPress('e', 'E');

    if (digitalRead(F) == 0)
      KeyPress('f', 'F');

    if (digitalRead(G) == 0)
      KeyPress('g', 'G');
  }
}
void KeyPress(char Key1, char Key2) {
  if (digitalRead(SHIFT) == 1) {
    Serial.println("Shift OFF");
    Keyboard.press(Key1);
  }
  else {
    Serial.println("Shift ON");
    Keyboard.press(Key2);
  }
  delay(100);
  Keyboard.releaseAll();
  delay(100);
}

Portrait de Halzote

Merci beaucoup ^^ 

Ne t'en fait pas je suis sur un clavier QWERTZ ;)

Quand j'aurais tout réglé je reviendrais pour poster le projet au complet comme ça si d'autres en auront besoin ils pourront en profiter ^^.

Encore merci Brossden <3

Portrait de brossden

Suite à ta demande de faire clignoter des Leds à des fréquences différentes pour certaines et synchro pour d'autres sur des sorties différentes, je t'ai fait un bout de code qui réponds à ta demande, mais je ne vois pas pourquoi utiliser des sorties différentes pour faire clignotes des Leds synchro, il suffit de les mettre sur le même sorties, mais bon ...

On ne peut pas utiliser la commande delay() car le processeur ne progresse plus dans le programme tant que délais fixé en paramètre n'est pas passé. Il faut utiliser une astuce avec millis() qui donne le temps en millisecondes depuis que le programme à été lancé pour la dernière fois !

Fonctionnement : Les Leds bleue et blanche clignotent en opposition toute les 500 ms, les Leds rouge, jaune et verte clignotent en synchro toutes les 1000 ms !

Tout d'abord une vidéo

Le code :

int led1 = 3;
int led2 = 4;
int led3 = 5;
int led4 = 6;
int led5 = 7;
double Time1;
double Time2;
double Time3;
double Time4;

void setup() {
  for (int n = 3; n < 8; n++) { // Boucle pour de n =3 à n inférieur à 8, à chaque boucle ajoute 1 a n
    pinMode(n, OUTPUT); //déclare succéssivement les pins de 1 à 7 comme des sorties
  }// retour à la ligne "for" si n = 8 sort de cette boucle !
  Time1 = millis() + 250;
  Time2 = millis() + 500;
  Time3 = millis() + 500;
  Time4 = millis() + 1000;

}

void loop() {
  if (millis() >= Time1) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    Time1 = millis() + 500;
  }
  if (millis() >= Time2) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    Time2 = millis() + 500;
  }
  if (millis() >= Time3) {
    for ( int n = 5 ; n < 8; n++) {
      digitalWrite(n  , HIGH);// led3, led4, led5
    }
    Time3 = millis() + 1000;
  }
  if (millis() >= Time4) {
    for ( int m = 5 ; m < 8; m++) {
      digitalWrite(m, LOW);// led3, led4, led5
    }
    Time4 = millis() + 1000;
  }
}

Portrait de brossden

Et pour finir le code qui fonctionne comme le désire Halzote selon ces dires :

//Projet de PAD 8boutons pour Elite Dangerous

#include <Keyboard.h>
const int A = 3;
const int B = 4;
const int C = 5;
const int D = 6;
const int F1 = 7;
const int F2 = 8;
const int F3 = 9;
const int F4 = 10;
const int PWR = 2; //Allumer et enteindre le PAD
const int led = 12; //Sers de témoin ON/OFF
void setup(){
  Serial.begin(230400);
  pinMode (A, INPUT_PULLUP);
  pinMode (B, INPUT_PULLUP);
  pinMode (C, INPUT_PULLUP);
  pinMode (D, INPUT_PULLUP);
  pinMode (F1, INPUT_PULLUP);
  pinMode (F2, INPUT_PULLUP);
  pinMode (F3, INPUT_PULLUP);
  pinMode (F4, INPUT_PULLUP);
  pinMode (PWR, INPUT_PULLUP);
  pinMode (led, OUTPUT);
  digitalWrite(led, LOW);
  Keyboard.begin();
}

void loop() {
  if (digitalRead(PWR) == 0)
  {
    digitalWrite(led, HIGH);
  }
  else {
    digitalWrite(led, LOW);
    Keyboard.releaseAll();
  }
  if (digitalRead(led) == HIGH) {
    if (digitalRead(A) == 0)
      KeyPress('a');

    if (digitalRead(B) == 0)
      KeyPress('b');

    if (digitalRead(C) == 0)
      KeyPress('c');

    if (digitalRead(D) == 0)
      KeyPress('d');

    if (digitalRead(F1) == 0)
      Keyboard.press(KEY_F1);
    else
      Keyboard.release(KEY_F1);

    if (digitalRead(F2) == 0)
      Keyboard.press(KEY_F2);
    else
      Keyboard.release(KEY_F2);
      
    if (digitalRead(F3) == 0)
      Keyboard.press(KEY_F3);
    else
      Keyboard.release(KEY_F3);
      
    if (digitalRead(F4) == 0)
      Keyboard.press(KEY_F4);
    else
      Keyboard.release(KEY_F4);

  }
}
void KeyPress(char Key) {
  Keyboard.press(Key);
  delay(100);
  Keyboard.release(Key);
  delay(100);
}

Portrait de Halzote

Encore merci Brossden :D

Portrait de brossden
De rien cela m'éloigne un peu plus d'Alzheimer !! mrd

                  loufoc.jpg

Bonne journée à tous

Portrait de Halzote

Mdr moi ça m'a évité la folie :')

Portrait de brossden

Sincèrement je ne comprends pas tu peux expliquer ?

Portrait de Halzote

Simplement qu'à force de buter sur le même problème ca peut rendre fou ^^

Portrait de brossden

Ah ok bonne journée