[TUTORIEL] Breakout Joystick analogique

Forum dédié aux produits Sparkfun

[TUTORIEL] Breakout Joystick analogique

Message non lude Laetitia » Mar 23 Juil 2013 15:45

Bonjour,

Aujourd'hui nous allons apprendre à nous servir d'un joystick analogique, du même type que celui des manettes de PS2. J'ai choisi celui de Sparkfun car il est facile à mettre en oeuvre grâce à son breakout. Le montage sera composé de 4 LEDs, disposées comme les points cardinaux, qui s'allumeront plus ou moins en fonction de la position du joystick.

- MATÉRIEL -

- Arduino Uno (x1)
- Joystick + Breakout (x1)
- LEDs 10 mm (x4)
- Résistances 150 Ohms (x4)

- SCHÉMA DU MONTAGE -

Schéma_joystick.png
Schéma_joystick.png (120.55 Kio) Vu 1890 fois

- EXPLICATIONS -

La position du joystick est connue grâce aux deux potentiomètres inclus dans celui-ci : un pour l'axe horizontal (noté HORZ sur le breakout) et un pour l'axe vertical (VERT). Ceux-ci, une fois passés par le convertisseur analogique-numérique, vont nous indiquer une valeur comprise entre 0 et 1023, image de la tension correspondant à la position du joystick ; sachant que sur l'axe horizontal "0" correspond à la position la plus à droite, et sur l'axe horizontal il correspond à la position la plus basse.

Nous allons commander les LEDs en PWM pour pouvoir jouer sur l'intensité de leur allumage en fonction de la position du joystick, d'où les branchements sur les pins 3, 5, 6 et 9. Le rapport cyclique de la PWM étant exprimé non pas en pourcentage mais en nombre compris entre 0 et 255, il nous est facile de convertir la valeur en entrée avec un simple map() : si l'on place la pleine échelle entre -255 et 255, la position centrale correspond bien à 0.
Plus d'infos sur le fonctionnement de la PWM de l'Arduino ? C'est ici !

Lorsque l'on déplace le joystick sur la partie positive de l'échelle, il suffit de récupérer la valeur en entrée pour la réinjecter sur la commande de la LED. Quand il est en position centrale, les deux LEDs sont éteintes. Et lorsqu'on se trouve dans la partie négative, on récupère la valeur absolue (sans le signe -), pour pouvoir la renvoyer à la LED concernée. Il n'y a plus qu'à reproduire la procédure sur l'autre axe !

Le bouton poussoir du joystick est relié à la pin D2 de l'Arduino, en cas d'appui il servira à allumer toutes les LEDs en même temps. Rien de bien difficile à ce niveau-là, juste un rappel sur le fait qu'un digitalWrite(pin, HIGH) équivaut à un analogWrite(pin, 255) et qu'on peut utiliser les deux indifféremment. Il faut néanmoins activer sa résistance de tirage, et savoir qu'il sera actif à l'état bas.

- CODE -

Code: Tout sélectionner
/*
  Tutoriel : Breakout Joystick analogique
  Allumage de LEDs d'intensité variable en fonction de la position du joystick
*/

// Déclaration de variables (branchements effectués)
int HAUT = 3;    // LED jaune > D3
int DROITE = 5;  // LED rouge > D5
int BAS = 6;     // LED verte > D6
int GAUCHE = 9;  // LED bleue > D9
int VERT = 0;    // axe vertical > A0
int HORZ = 1;    // axe horizontal > A1
int SEL = 2;     // bouton poussoir > D2

void setup()
{
  // Configuration des LEDs en sorties
  pinMode(HAUT, OUTPUT);
  pinMode(DROITE, OUTPUT);
  pinMode(BAS, OUTPUT);
  pinMode(GAUCHE, OUTPUT);
 
  // Configuration du bouton poussoir en entrée
  // (les broches Ax sont automatiquement configurées en entrée)
  pinMode(SEL, INPUT);
  // Activation de la résistance de tirage
  digitalWrite(SEL, HIGH);
}

void loop()
{
  // Récupération des données en entrée
  int vert = analogRead(VERT);
  int horz = analogRead(HORZ);
  int sel = digitalRead(SEL);
 
  // Affichage successif sur les deux axes (voir fonctions ci-dessous)
  vertical(vert);
  horizontal(horz);
 
  // Appui sur le bouton (actif à l'état BAS)
  if (sel == 0)
  {
    // Allumer toutes les LEDs (voir ci-dessous)
    all();
  }
}

// Fonction gérant les LEDs "HAUT" et "BAS"
void vertical(int posV)
{
  // Variable interne : changement d'échelle pour avoir la position centrale à 0
  posV = map(posV, 0, 1023, -255, 255);
  // Si la valeur trouvée est négative alors on va vers le bas
  if (posV < 0)
  {
    // On éteint la LED "HAUT"
    analogWrite(HAUT, 0);
    // ...et on récupère la valeur absolue qu'on envoie sur la LED "BAS"
    analogWrite(BAS, abs(posV));
  }
  // Sinon c'est qu'on va vers le haut
  else
  {
    // On éteint la LED "BAS"
    analogWrite(BAS, 0);
    // ...et on renvoie la valeur (déjà positive) sur la LED "HAUT"
    analogWrite(HAUT, posV);
  }
}

// Fonction gérant les LEDs "GAUCHE" et "DROITE"
void horizontal(int posH)
{
  // Variable interne : changement d'échelle pour avoir la position centrale à 0
  posH = map(posH, 0, 1023, -255, 255);
  // Si la valeur trouvée est négative alors on va vers la droite
  if (posH < 0)
  {
    // On éteint la LED "GAUCHE"
    analogWrite(GAUCHE, 0);
    // ...et on récupère la valeur absolue qu'on envoie sur la LED "DROITE"
    analogWrite(DROITE, abs(posH));
  }
  // Sinon c'est qu'on va vers la gauche
  else
  {
    // On éteint la LED "DROITE"
    analogWrite(DROITE, 0);
    // ...et on renvoie la valeur (déjà positive) sur la LED "GAUCHE"
    analogWrite(GAUCHE, posH);
  }
}

// Fonction gérant l'appui sur le bouton poussoir
void all(void)
{
  // On alume toutes les LEDs
  digitalWrite(HAUT, HIGH);
  digitalWrite(BAS, HIGH);
  digitalWrite(GAUCHE, HIGH);
  digitalWrite(DROITE, HIGH);
}


- VIDÉO -



- NOTE -

Une fois le montage effectué, vous vous êtes peut-être aperçus qu'avec le joystick en position centrale vous aviez des LEDs qui s'allumaient ? C'est dû à la tolérance de fabrication des potentiomètres du joystick : ils ne sont pas parfaits et en position centrale on ne mesure pas forcément exactement 50% de la tension d'alimentation... Il est possible de corriger ça dans le code, en modifiant l'échelle. Il suffit parfois de très peu !
Quand j'ai fait mon montage, je me suis aperçue que les LEDs "BAS" et "DROITE" s'allumaient trop tôt, donc que le "0" était décalé dans le négatif... j'ai dû modifier les lignes suivantes :

Code: Tout sélectionner
posV = map(posV, 0, 1023, -250, 255);

Code: Tout sélectionner
posH = map(posH, 0, 1023, -242, 255);

C'est tout pour aujourd'hui ! J'espère que ce tutoriel vous aura plu, et bonne bidouille en attendant le prochain !
"If it's itchy, scratch it !" - "DIY or die"

RTFM (À lire avant de poster) - ANDb (Arduino Noob Database)
Avatar de l’utilisateur
Laetitia
 
Messages: 296
Inscription: Mar 7 Aoû 2012 15:07
Localisation: Toulouse

Retourner vers Sparkfun

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité

cron