Skyduino:~#
Articles
arduino, programmation

[Arduino] Utiliser un joystick pour contrôler la direction/vitesse d’un robot

Bonjour tout le monde !

Aujourd’hui je vais vous présenter un morceau de code qui devrait être utile pour beaucoup d’entre vous 😉

Le sujet du jour : utiliser un joystick pour contrôler la direction/vitesse d’un robot.

Le but est simple, réaliser un système permettant de transformer un joystick deux axes tout ce qui a de plus classique, en un contrôleur de vitesse / direction utilisable pour un robot (ou pour tout autre chose).

Tout d’abord le matériel :

1 joystick deux axes,
1 carte arduino,
quelques câbles

Le câblage :

Arduino -> Joystick
GND -> GND
5V -> VCC
A0 -> Horiz (axe X)
A1 -> Vert (axe Y)

Le principe :

Le code est fait pour respecter ce schéma de principe :

L’axe vertical (en valeur inversée) contrôle la vitesse.
Quand le joystick est « au centre » les moteurs sont arrêtés, vers « le haut » la vitesse est au maximum et vers l’avant, vers le bas la vitesse est au maximum et vers l’arrière.

(Ps: Pour l’interprétation des 0 / 1 : C’est une question de point de vue, dans mon cas je travaille sur une sorte d’aéro glisseur, pour tourner à droite il faut couper le moteur droit par exemple)

Le code :

// Définition des broches analogique
#define JOYSTICK_X A0 // X -> droite / gauche
#define JOYSTICK_Y A1 // Y -> vitesse / direction

// Définition des états des moteurs
#define MOTEUR_STOP 0
#define MOTEUR_AVANCE 1
#define MOTEUR_RECULE 2

// Définition de la marge autour du point d'origine (0, 0)
// Permet d'éviter que les moteurs n'oscille entre MOTEUR_AVANCE et MOTEUR_RECULE
#define THRESHOLD 20

// Définition de la valeur maximum pour la vitesse
#define MAX_SPEED 127

// Variables global
// calX : calibration en 0 de l'axe X
// calY : calibration en 0 de l'axe Y
// vitesse : vitesse calculé
// direction : direction calculé
int calX, calY, vitesse, direction;
// coefG : coefficient de vitesse (entre 0 et 1) pour le moteur gauche
// coefD : coefficient de vitesse (entre 0 et 1) pour le moteur droit
float coefG, coefD;

// setup()
void setup() {
  // Initialisation du port série
  Serial.begin(115200);

  // Calibration de la valeur (0, 0) du joystick
  calX = analogRead(JOYSTICK_X);
  calY = analogRead(JOYSTICK_Y);
}

// loop()
void loop() {
  // Calcul des données
  getData(calX, calY, &coefG, &coefD, &vitesse, &direction);

  // Affichage de la vitesse du moteur gauche
  Serial.print("Moteur Gauche : ");
  Serial.println((int)(vitesse * coefG));
  
  // Affichage de la vitesse du moteur droit
  Serial.print("Moteur Droit : ");
  Serial.println((int)(vitesse * coefD));

  // Affichage de la direction des moteurs
  Serial.print("Direction : ");
  if(direction == MOTEUR_AVANCE) // Vers l'avant
    Serial.println("AVANT");
  else if(direction == MOTEUR_RECULE) // Vers l'arriére
    Serial.println("ARRIERE");
  else
    Serial.println("ARRET"); // Aucun mouvement

  // Delai de 500ms pour pouvoir lire la console
  delay(500);
}

// Fonction calculant les divers coefficient de vitesse, la direction, ainsi que la vitesse
void getData(int calX, int calY, float *coefG, float *coefD, int *vitesse, int *direction) {
  // rawX : valeur brute en X du joystick centrée sur calX
  // rawY : valeur brute en Y du joystick centrée sur calY
  int rawX, rawY;
  
  // Mesure des valeurs brute en X et Y
  rawX = analogRead(JOYSTICK_X) - calX;
  rawY = analogRead(JOYSTICK_Y) - calY;

  // Si -THRESHOLD < rawY < THRESHOLD
  if(rawY > -THRESHOLD && rawY < THRESHOLD){
    // Les moteurs sont marqués comme arrétés, et vitesse = 0
    *direction = MOTEUR_STOP;
    *vitesse = 0;
  }  // Si rawY >= 0
  else if(rawY >= 0) {
    // Les moteurs sont marqués en mode "recule"
    *direction = MOTEUR_RECULE;
	// La vitesse est égale à map(rawY) depuis 0 ~ (1023 - calY) vers 0 ~ MAX_SPEED
    *vitesse = map(rawY, 0, 1023 - calY, 0, MAX_SPEED);
  } // Si rawY < 0
  else {
    // Les moteurs sont marqués en mode "recule"
    *direction = MOTEUR_AVANCE;
	// La vitesse est égale à map(rawY) depuis 0 ~ calY vers 0 ~ MAX_SPEED
    *vitesse = map(-rawY, 0, calY, 0, MAX_SPEED);
  }

  // Si rawX < -THRESHOLD alors coefG = -rawX / calX sinon coefG = 1
  *coefG = (rawX < -THRESHOLD) ? -rawX / (float)calX : 1;
  
  // Si rawX > THRESHOLD alors coefD = rawX / calX sinon coefD = 1
  *coefD = (rawX > THRESHOLD) ? rawX / (float)calX : 1;
}

Si on laisse le joystick au centre :
Moteur Droit : 0
Moteur Gauche : 0
Direction : ARRET

Si on place le joystick vers le haut :
Moteur Droit : 127
Moteur Gauche : 127
Direction : AVANT

Si on place le joystick vers le bas :
Moteur Droit : 127
Moteur Gauche : 127
Direction : ARRIÈRE

Et sur les angles :
Moteur Droit : 0
Moteur Gauche : 127
Direction : AVANT

Moteur Droit : 127
Moteur Gauche : 0
Direction : AVANT

Moteur Droit : 0
Moteur Gauche : 127
Direction : ARRIERE

Moteur Droit : 127
Moteur Gauche : 0
Direction : ARRIERE

Enjoy ! 🙂

Discussion

9 réflexions sur “[Arduino] Utiliser un joystick pour contrôler la direction/vitesse d’un robot

  1. Je suppose que c’est pour ton BrossoGlisseur, vivement la vidéo ! 🙂 Quel est le module de transmission entre la commande et le BrossoGlisseur ?

    Publié par Bruno | 27 mars 2012, 18 h 32 min
    • Yep c’est ça 😉
      Pour la vidéo / article il faudra attendre un peu, en ce moment je fait 8h ~ 19h30 c’est pas cool ^^ » »

      Pour la transmission j’utilise un « bête » module 433MHz avec virtualWire.

      Publié par skywodd | 27 mars 2012, 20 h 23 min
    • Bonjour, il faut brancher les moteurs au broches 1 et 2 et a la masse c’est ça ? D’avance merci

      Publié par Benjamin | 15 avril 2019, 14 h 01 min
  2. Bonjour. Travaillant sur un projet de déambulateur fonctionnant à l’energie solaire, y aurait t-il moyen de faire fonctionner ce programme sur un joysick plus grand? Est-il possible de le faire fonctionner à l’énergie solaire? Et de le relier à un moteur?

    Merci.

    Bob Sleig

    Publié par Bob Sleig | 7 décembre 2015, 14 h 46 min
  3. Bonjour auriez vous les références de la cart électronique utilisée et du joystick svp ?

    Publié par LEFEBVRE | 22 janvier 2016, 15 h 50 min
  4. Ce programme est t-il compatible pour ce type de joystick ? http://www.gotronic.fr/art-shield-joystick-dfr0008-19254.htm

    Publié par Derozereuil | 29 février 2016, 15 h 07 min
  5. Bonjour, je travaille sur le même projet, pourriez vous me donner les données d’alimentation qu’il faut utiliser ? Merci bcp 😉

    Publié par Monte Cristaxx | 22 octobre 2018, 9 h 06 min

Rétroliens/Pings

  1. Pingback: Jeudi 25/10/18 : Ready to Play ? • Artilect - 25 octobre 2018

Skyduino devient Carnet du Maker

Le site Carnet du Maker remplace désormais le blog Skyduino pour tout ce qui touche à l'Arduino, l'informatique et au DIY.