Contrôle d'un Moteur Pas à Pas avec un Joystick USB

Salut à tous,

Je vient vers vous car j’aurais besoin d’un conseil au niveau de mon programme Arduino, c’est pour un projet de terminale.
Alors voilà, j’ai utilisé un programme pour contrôler un moteur pas à pas avec un shield “Adafruit Motor Shield V2.3” et un autre pour comprendre le fonctionnement d’un Joystick USB à l’aide d’un shield “USB Host Shield”.
Venu au fait de rassembler ces deux là en un seul programme, je ne trouve pas la façon dont contrôler le moteur pas à pas à l’aide du Joystick …

Ayant reçu des informations en Hexadécimal de la part de mon Joystick (sur Axe X), par exemple la valeur sans bouger le joystick varie de 72 à 80, ou la valeur quand on met le joystick à gauche est de 00 et quand on le met à droite, de FF ; je me suis dit que je pourrais bouger le moteur à l’aide de ces valeurs, quand le joystick ce trouve entre 72 et 80, le moteur ne bougera pas, alors que si il va vers la gauche ou la droite, le moteur bougera de 0.1°/ms ou de 5 pas vers l’avant par exemple.

Je ne suis pas encore sûr de mon idée et je ne saurais pas comment la mettre en oeuvre, j’en fait donc appel à vous, les pros !

Je vous met mon code dans le post si besoin.

Merci d’avance ! :slight_smile:

Edit : J’ai tenter d’ajouter les variables (notamment X) et de faire un “if else” à la fin du programme, mais il veut rien savoir …

uint8_t X, Y, Z1, Z2, Rz;

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "Adafruit_PWMServoDriver.h"

#include <usbhid.h>
#include <hiduniversal.h>
#include <usbhub.h>

#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>
#endif

#include "hidjoystickrptparser.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

USB Usb;
USBHub Hub(&Usb);
HIDUniversal Hid(&Usb);
JoystickEvents JoyEvents;
JoystickReportParser Joy(&JoyEvents);

void setup() {
  Serial.begin(115200);
#if !defined(__MIPSEL__)
        while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
        Serial.println("Start");
        //Serial.println("Stepper test!");

        if (Usb.Init() == -1)
                Serial.println("OSC did not start.");

        //delay(200);

        if (!Hid.SetReportParser(0, &Joy))
                ErrorMessage<uint8_t > (PSTR("SetReportParser"), 1);

                //AFMS.begin(1.6);  // create with the default frequency 1.6KHz
  AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  
  myMotor->setSpeed(150);  // 10 rpm
}

void loop() {
  Usb.Task();
  //Serial.println("Single coil steps");
  //myMotor->step(100, FORWARD, SINGLE); 
  //myMotor->step(0, BACKWARD, SINGLE); 

  //Serial.println("Double coil steps");
  //myMotor->step(100000, FORWARD, DOUBLE); 
  //myMotor->step(100000, BACKWARD, DOUBLE);
  
  //Serial.println("Interleave coil steps");
  //myMotor->step(50, FORWARD, INTERLEAVE); 
  //myMotor->step(300, BACKWARD, INTERLEAVE); 
  
  //Serial.println("Microstep steps");
  //myMotor->step(50, FORWARD, MICROSTEP); 
  //myMotor->step(50, BACKWARD, MICROSTEP);
 if (X == 0)
  {
     myMotor->step(10, FORWARD, INTERLEAVE);
  delay(1);
  }
  else
  {
     myMotor->step(10, BACKWARD, INTERLEAVE);
  delay(1);
  }
}

Bonjour Keonys,

J’ai simplement quelques idées à vous suggérer. Je ne suis pas un spécialiste des joysticks USB, ni du module motor shield en partant, mais moi je ferais quelque chose comme ceci :

D’abord je convertirais les valeurs hexadécimales retournées par le joystick en valeurs numériques afin que ça soit plus compréhensible pour moi. J’aurais ainsi une plage de valeur qui varieraient entre 0 et 255, 127 étant à peu près le centre. Dans votre cas la position centrale varie entre 112 et 128 si j’ai bien compris.

Vous semblez vouloir faire correspondre le déplacement du joystick avec le nombre de pas effectué, moi je suggère plutôt de faire changer la vitesse proportionnellement en fonction de l’écart avec la position centrale. Pour ce faire je ferais varier le temps de délais entre chaque pas du moteur en utilisant une variable. Voir “delay(1);” dans votre code. Ça pourrais devenir par exemple “delay(motorSpeed);” à vous de voir s’il ne conviendrait pas mieux pour vous de modifier cette commande dans votre code que vous utilisez au début : “myMotor->setSpeed(150); // 10 rpm”

Par la suite j’appliquerais la modification en fonction du positionnement du joystick comme je disais plus tôt.
Ex.: Entre 112 et 128 → Rien faire

128 Moteur fonctionne d’avant (Délai calculé ainsi : 256 - Valeur du joystick)
<112 Moteur fonctionne de reculons (Délai calculé ainsi : Valeur du joystick + 1)

Bien sûr il y a toujours moyen d’adapter les équations à vos besoins en appliquant des facteurs.

Ainsi le moteur va répondre immédiatement au joystick en tournant plus ou moins rapidement dans la direction demandé. Il est peut-être possible d’appliquer une logique similaire pour correspondre au nombre de pas du moteur, mais je préférais cette option personnellement.

Bonne chance et bonne continuité,

ST