Ps2 controller exploitation des données joysticks

C’était un exemple général (tiré de son code) pour expliquer que map() ne contraint pas la valeur entre 2 bornes.

Prenez alors l’autre exemple qui sera peut être plus parlant


if(RX>140)                  
    {  
      RX = map(RX,140,255,0,255);
      tourelleTourneDroite(RX);
    }

Si RX depasse 255 en entrée (il vient du analogRead ça pourrait être 1023 par exemple) alors map() va sortir des bornes [0,255]

Il y a une fonction constrain() qui peut être utile

Bonjour J-M-L

Contraindre une valeur entre 2 bornes n'a jamais été le rôle de map(), il y a constrain() pour ça.

Cordialement
jpbbricole

Oui comme dit ci dessus - mais c’est une erreur courante que l’on voit donc ça vaut le coup de le mentionner

donc je devrai inscrire quelque chose comme ça?

if(LY>140)                  
    {  
      LY = map(LY,140,255,0,255);
      LY = constrain(LY,0 ,255);
      balancierMonte(LY);
    }

Précision du comportement des moteurs,
lorsque je "pousse" le joystick fonctionnement normal de l'arrêt jusqu'à vitesse max en avant
lorsque je "tire' le joystick le moteur démarre en vitesse max en arrière puis ralentit jusqu'à l'arrêt
à l'approche de la valeur 192, puis au delà des 192 jusqu'au 255 redémarrage progressif jusqu'à vitesse max en avant

en inversant les valeurs dans map() j'obtient un fonctionnement normal, seulement la vitesse max est moins élevée( de pas grand chose comme bridé à 90% / 95% environ) en arrière qu'en avant.(pas important pour mon usage) mais je voudrais comprendre.

if(LY>140)                  
    {  
      **LY = map(LY,0,140,0,255);**
      balancierMonte(LY);
    }
    else
    {
      digitalWrite(balancierIn2, 0);  
    }

    if(LY<113)
    {
      LY = map(LY,113,0,0,255);
      balancierDescend(LY);
    }
    else
    {
      digitalWrite(balancierIn1, 0);
    }

Bonsoir m122

Non, tu n'as rien à changer, c'est juste tel que c'est dans ton programme.

Cordialement
jpbbricole

Bonsoir m122

Ca c'est pas possible vu que la valeur ne peut que "monter" > 140 alors que ta plage "descend" , 0,140

Cordialement
jpbbricole

bonsoir Jpbbricole

ce que tu me propose est pour inversé le sens de rotation?
car en inversant les valeurs dans la fonction map() ça fonctionne.
Hors mi petite différence de vitesse max.

Là je rencontre un autre problème lorsque je bouge le joystick R dans le sens X c'est le moteur LX qui s'active :upside_down_face:

J'ai effacé le texte, j'ai vu ma c......e!

Imprimez les valeurs lues avant de faire le map() puis après
On verra ce que vous obtenez

il n'y à que celui qui ne dit rien qui ne se trompe pas !

pour l'inversion de mes commande LX et RX je n'y comprends rien câblage vérifié plusieurs fois !
attribution de nouvelles bornes y compris PWM ...

pour map() je suis d'accord avec vous, c'est suite à une erreur de frappe que ça à fonctionné.

les valeurs des joysticks sont déjà "mappées" par la librairie (je pense) car déjà de 0 à 255 et pas de 0 à 1024 comme un joystick seul comme ceux des packs de démarrage.

Bonsoir m122

Je viens de vérifier, les manettes analogiques vont pour X de 0 à 255 de gauche à droite et pour Y de 0 à 255 de haut en bas.

Cordialement
jpbbricole

Ah oui j’avais oublié qu’on n’avait qu’un octet en valeur de sortie de la bibliothèque

Un petit complément

f(LY>140) on descend le levier map(LY,140,255,0,255)
if(LY<113) on monte le levier map(LY,113,0,0,255)

Vous pouvez reposter le code tel qu’il est maintenant et préciser exactement les alimentations et confirmer les connexions des pins?

les pins utilisés sont ceux définis en début de code
les commandes du bras, du balancier fonctionnent avec respectivement LY et RY
JE VIENS DE VOIR QUE JE NE FAIS JAMAIS APPEL AUX FONCTIONS "GODET" DANS LE CODE
la carte mega2560 est alimentée par le port usb
la manette est alimentée par la sortie 3.3v du mega2560
le module de puisance DBH-12V est alimenté uniquement par une vieille alim de labo(seul les ground sont relié entres eux)

#include <PS2X_lib.h>  //for v1.6


//                         Mega       Uno

#define PS2_DAT             14   //   8      
#define PS2_CMD             15   //   11  
#define PS2_SEL             16   //   10  
#define PS2_CLK             17   //   12 
#define chenilleDenA        2    //   3   pwm
#define chenilleDin1        22   //   2
#define chenilleDin2        24   //   4
#define chenilleGenB        3    //   5   pwm
#define chenilleGin3        26   //   6
#define chenilleGin4        28   //   7
#define tourelleEnA         11   //       pwm
#define tourelleIn1         31
#define tourelleIn2         33
#define brasEnB             5    //       pwm
#define brasIn3             34
#define brasIn4             36
#define balancierEnA        6    //       pwm
#define balancierIn1        38
#define balancierIn2        40
#define godetEnB            9    //       pwm
#define godetIn3            42
#define godetIn4            44
#define rotofilEnA          10    //       pwm
#define rotofilIn1          46
#define rotofilIn2          48     /* je pourais économisé 1 voire 2 bornes car pas besoin des 2 sens de rotation, 
                                        mais peut etre par la suite remplacer le rotofil par autre chose */



/*
module nrf24l01
 
 #define MOSI                51 
 #define MISO                50
 #define SCK                 52
 #define CS                  8    //pwm
 #define CE                  7
 */


#define pressures   true
#define rumble      true

PS2X ps2x; 


int error = 0;
byte type = 0;
byte vibrate = 0;
static int PRX = 127, PRY = 128, PLX = 127, PLY = 128;
int RX , RY , LX , LY ;
int nbrPushBtnX = 0;      // pour la vitesse du rotofil



void avanceChenilleGauche(){

  digitalWrite(chenilleGin3, 0);
  digitalWrite(chenilleGin4, 1);
  analogWrite(chenilleGenB,255);
}

void reculChenilleGauche(){

  digitalWrite(chenilleGin3, 1);
  digitalWrite(chenilleGin4, 0);
  analogWrite(chenilleGenB,255);
}

void avanceChenilleDroite(){

  digitalWrite(chenilleDin1, 0);
  digitalWrite(chenilleDin2, 1); 
  analogWrite(chenilleDenA,255);
}

void reculChenilleDroite(){

  digitalWrite(chenilleDin1, 1);
  digitalWrite(chenilleDin2, 0);
  analogWrite(chenilleDenA,255);
}

void tourelleTourneDroite(int vitesseRX){

  digitalWrite(tourelleIn1, 0);
  digitalWrite(tourelleIn2, 1);
  analogWrite(tourelleEnA,vitesseRX);
}

void tourelleTourneGauche(int vitesseRX){

  digitalWrite(tourelleIn1, 1);
  digitalWrite(tourelleIn2, 0);
  analogWrite(tourelleEnA,vitesseRX);
}

void brasMonte(int vitesseRY){

  digitalWrite(brasIn3, 0);
  digitalWrite(brasIn4, 1);
  analogWrite(brasEnB, vitesseRY);
}

void brasDescend(int vitesseRY){

  digitalWrite(brasIn3, 1);
  digitalWrite(brasIn4, 0);
  analogWrite(brasEnB, vitesseRY);
}

void balancierMonte(int vitesseLY){

  digitalWrite(balancierIn1, 0);
  digitalWrite(balancierIn2, 1);
  analogWrite(balancierEnA, vitesseLY);
}

void balancierDescend(int vitesseLY){

  digitalWrite(balancierIn1, 1);
  digitalWrite(balancierIn2, 0);
  analogWrite(balancierEnA, vitesseLY);
}

void godetOuvre(int vitesseLX){

  digitalWrite(godetIn3, 0);
  digitalWrite(godetIn4, 1);
  analogWrite(godetEnB, vitesseLX);
}

void godetFerme(int vitesseLX){

  digitalWrite(godetIn3, 1);
  digitalWrite(godetIn4, 0);
  analogWrite(godetEnB, vitesseLX);
}

void rotofilVitesse1(){   
  
  digitalWrite(rotofilIn1, 1);
  digitalWrite(rotofilIn2, 0);
  analogWrite(rotofilEnA, 128);
}

void rotofilVitesse2(){
  
  digitalWrite(rotofilIn1, 1);
  digitalWrite(rotofilIn2, 0);
  analogWrite(rotofilEnA, 192);
}

void rotofilVitesse3(){
  
  digitalWrite(rotofilIn1, 1);
  digitalWrite(rotofilIn2, 0);
  analogWrite(rotofilEnA, 255);
}

void rotofilArret(){
  
  digitalWrite(rotofilIn1, 0);
  digitalWrite(rotofilIn2, 0);
  analogWrite(rotofilEnA, 0);
}

void setup(){


  pinMode(chenilleDenA, OUTPUT);   //pwm
  pinMode(chenilleDin1, OUTPUT);
  pinMode(chenilleDin2, OUTPUT);
  pinMode(chenilleGenB, OUTPUT);   //pwm
  pinMode(chenilleGin3, OUTPUT);
  pinMode(chenilleGin4, OUTPUT);
  pinMode(tourelleEnA, OUTPUT);    // pwm
  pinMode(tourelleIn1, OUTPUT);           
  pinMode(tourelleIn2, OUTPUT);             
  pinMode(brasEnB, OUTPUT);        // pwm
  pinMode(brasIn3, OUTPUT);                     
  pinMode(brasIn4, OUTPUT);                      
  pinMode(balancierEnA, OUTPUT);   // pwm
  pinMode(balancierIn1, OUTPUT);         
  pinMode(balancierIn2 , OUTPUT);         
  pinMode(godetEnB, OUTPUT);       // pwm
  pinMode(godetIn3, OUTPUT);                 
  pinMode(godetIn4, OUTPUT);            
  pinMode(rotofilEnA, OUTPUT);     // pwm
  pinMode(rotofilIn1, OUTPUT);
  pinMode(rotofilIn2, OUTPUT);


  digitalWrite(chenilleDin1, 0);
  digitalWrite(chenilleDin2, 0);
  digitalWrite(chenilleGin3, 0);
  digitalWrite(chenilleGin4, 0);
  digitalWrite(tourelleIn1, 0);          
  digitalWrite(tourelleIn2, 0);             
  digitalWrite(brasIn3, 0);                     
  digitalWrite(brasIn4, 0);                      
  digitalWrite(balancierIn1, 0);          
  digitalWrite(balancierIn2 , 0);           
  digitalWrite(godetIn3, 0);                  
  digitalWrite(godetIn4, 0);             
  digitalWrite(rotofilIn1, 0);
  digitalWrite(rotofilIn2, 0);


  Serial.begin(115200);

  delay(300);  //added delay to give wireless ps2 module some time to startup, before configuring it

  //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************

  //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
  error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);

  if(error == 0){
    Serial.print("Found Controller, configured successful ");
    Serial.print("pressures = ");
    if (pressures)
      Serial.println("true ");
    else
      Serial.println("false");
    Serial.print("rumble = ");
    if (rumble)
      Serial.println("true)");
    else
      Serial.println("false");
    Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
    Serial.println("holding L1 or R1 will print out the analog stick values.");
    Serial.println("Note: Go to www.billporter.info for updates and to report bugs.");
  }  
  else if(error == 1)
    Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");

  else if(error == 2)
    Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");

  else if(error == 3)
    Serial.println("Controller refusing to enter Pressures mode, may not support it. ");

  //  Serial.print(ps2x.Analog(1), HEX);

  type = ps2x.readType(); 
  switch(type) {
  case 0:
    Serial.print("Unknown Controller type found ");
    break;
  case 1:
    Serial.print("DualShock Controller found ");
    break;
  case 2:
    Serial.print("GuitarHero Controller found ");
    break;
  case 3:
    Serial.print("Wireless Sony DualShock Controller found ");
    break;
  }
}

void loop() {
  /* You must Read Gamepad to get new values and set vibration values
   ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
   if you don't enable the rumble, use ps2x.read_gamepad(); with no values
   You should call this at least once a second
   */
  if(error == 1) //skip loop if no controller found
    return; 

  if(type == 2){ //Guitar Hero Controller
    ps2x.read_gamepad();          //read controller 

    if(ps2x.ButtonPressed(GREEN_FRET))
      Serial.println("Green Fret Pressed");
    if(ps2x.ButtonPressed(RED_FRET))
      Serial.println("Red Fret Pressed");
    if(ps2x.ButtonPressed(YELLOW_FRET))
      Serial.println("Yellow Fret Pressed");
    if(ps2x.ButtonPressed(BLUE_FRET))
      Serial.println("Blue Fret Pressed");
    if(ps2x.ButtonPressed(ORANGE_FRET))
      Serial.println("Orange Fret Pressed"); 

    if(ps2x.ButtonPressed(STAR_POWER))
      Serial.println("Star Power Command");

    if(ps2x.Button(UP_STRUM))          //will be TRUE as long as button is pressed
      Serial.println("Up Strum");
    if(ps2x.Button(DOWN_STRUM))
      Serial.println("DOWN Strum");

    if(ps2x.Button(PSB_START))         //will be TRUE as long as button is pressed
      Serial.println("Start is being held");
    if(ps2x.Button(PSB_SELECT))
      Serial.println("Select is being held");

    if(ps2x.Button(ORANGE_FRET)) {     // print stick value IF TRUE
      Serial.print("Wammy Bar Position:");
      Serial.println(ps2x.Analog(WHAMMY_BAR), DEC); 
    } 
  }
  else { //DualShock Controller
    ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed



    if(ps2x.Button(PSB_START)) {        //will be TRUE as long as button is pressed
      Serial.println("Start is being held");
    }
    if(ps2x.Button(PSB_SELECT)){
      Serial.println("Select is being held"); 
    }     

    if(ps2x.Button(PSB_PAD_UP)) {      //will be TRUE as long as button is pressed
      Serial.print("Up held this hard: ");
      Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
    }
    if(ps2x.Button(PSB_PAD_RIGHT)){
      Serial.print("Right held this hard: ");
      Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC);
    }
    if(ps2x.Button(PSB_PAD_LEFT)){
      Serial.print("LEFT held this hard: ");
      Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC);
    }
    if(ps2x.Button(PSB_PAD_DOWN)){
      Serial.print("DOWN held this hard: ");
      Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
    }   

    vibrate = ps2x.Analog(PSAB_CROSS);  //this will set the large motor vibrate speed based on how hard you press the blue (X) button
    if (ps2x.NewButtonState()) {        //will be TRUE if any button changes state (on to off, or off to on)
      if(ps2x.Button(PSB_L3))
        Serial.println("L3 pressed");
      if(ps2x.Button(PSB_R3))
        Serial.println("R3 pressed");
      if(ps2x.Button(PSB_L2))
        Serial.println("L2 pressed");
      if(ps2x.Button(PSB_L1))
        Serial.println("L1 pressed");
      if(ps2x.Button(PSB_TRIANGLE))
        Serial.println("Triangle pressed");        
    }

    if(ps2x.ButtonPressed(PSB_CIRCLE))               //will be TRUE if button was JUST pressed
      Serial.println("Circle just pressed");
    if(ps2x.NewButtonState(PSB_CROSS))               //will be TRUE if button was JUST pressed OR released
      Serial.println("X just changed");
    if(ps2x.ButtonReleased(PSB_SQUARE))              //will be TRUE if button was JUST released
      Serial.println("Square just released");     

   LY = ps2x.Analog(PSS_LY);
   LX = ps2x.Analog(PSS_LX);
   RY = ps2x.Analog(PSS_RY);
   RX = ps2x.Analog(PSS_RX);



    if ((LX != PLX) || (LY != PLY) || (RX != PRX) || (RY != PRY)) 
    {  
      PLX = LX;
      PLY = LY;
      PRX = RX;
      PRY = RY;


      Serial.print(LX);    
      Serial.print(F(" ,"));
      Serial.print(LY);    
      Serial.print(F(" ,"));
      Serial.print(RX);    
      Serial.print(F(" ,"));
      Serial.println(RY);  

    }

    ps2x.read_gamepad();



    if(LY>140)                  
    {  
      LY = map(LY,0,140,0,255);
      balancierMonte(LY);
    }
    else
    {
      digitalWrite(balancierIn2, 0);  
    }

    if(LY<113)
    {
      LY = map(LY,113,0,0,255);
      balancierDescend(LY);
    }
    else
    {
      digitalWrite(balancierIn1, 0);
    }



    if(RY>140)                  
    {  
      RY = map(RY,0,140,0,255);
      brasMonte(RY);
    }
    else
    {
      digitalWrite(brasIn4, 0);  
    }

    if(RY<113)
    {
      RY = map(RY,113,0,0,255);
      brasDescend(RY);
    }
    else
    {
      digitalWrite(brasIn3, 0);
    }


    if(LX>140)                  
    {  
      LX = map(LX,0,140,0,255);
      tourelleTourneDroite(LX);
    }
    else
    {
      digitalWrite(tourelleIn2, 0);  
    }

    if(LX<113)
    {
      LX= map(LX,113,0,0,255);
      tourelleTourneGauche(LX);
    }
    else
    {
      digitalWrite(tourelleIn1, 0);
    }

    if(RX>140)                  
    {  
      RX = map(RX,0,140,0,255);
      tourelleTourneDroite(RX);
    }
    else
    {
      digitalWrite(tourelleIn2, 0);  
    }

    if(RX<113)
    {
      RX= map(RX,113,0,0,255);
      tourelleTourneGauche(RX);
    }
    else
    {
      digitalWrite(tourelleIn1, 0);
    }





    if (ps2x.Button(PSB_L1)&& !ps2x.Button(PSB_L2))
    {
      Serial.println("L1 pressed");
      avanceChenilleGauche();
    }

    else
    {
      digitalWrite(chenilleGin4, 0);  
    }

    if (ps2x.Button(PSB_R1)&& !ps2x.Button(PSB_R2))
    {
      Serial.println("R1 pressed");
      avanceChenilleDroite();

    }

    else
    {    
      digitalWrite(chenilleDin2, 0);   
    }

    if (ps2x.Button(PSB_L2) && !ps2x.Button(PSB_L1))
    {
      Serial.println("L2 pressed");
      reculChenilleGauche();
    }

    else
    {
      digitalWrite(chenilleGin3, 0);  
    }

    if (ps2x.Button(PSB_R2)&& !ps2x.Button(PSB_R1))
    {
      Serial.println("R2 pressed");
      reculChenilleDroite();
    }

    else
    {
      digitalWrite(chenilleDin1, 0);  
    }
    
    
    if (ps2x.Button(PSB_CROSS))
    { 
      nbrPushBtnX = nbrPushBtnX +1;
    }
    
    if (nbrPushBtnX >= 3)
    {
      nbrPushBtnX == 3;
    }
    
    if (ps2x.Button(PSB_SQUARE))
    {
      nbrPushBtnX == 0;
    }

    if (nbrPushBtnX == 1)
    {
      rotofilVitesse1();
    }

    if (nbrPushBtnX == 2)
    {
      rotofilVitesse2();
    }

    if (nbrPushBtnX == 3)
    {
      rotofilVitesse3();
    }
    
    if (nbrPushBtnX == 0)
    {
      rotofilArret();
    }


  }

  delay(50) ;
}

Bonsoir m122

A mon avis, tu as 2 erreurs

    if(LY>140)                  
    {  
      //LY = map(LY,0,140,0,255);
      LY = map(LY, 140,255,0,255);
      balancierMonte(LY);
    }
 
    if(RY>140)                  
    {  
      //RY = map(RY,140, 255,0,255);
      RY = map(RY,140, 255,0,255);
      brasMonte(RY);
    }

Comme indiqué ici.

Cordialement
jpbbricole

il y a plein de code qui ne sert à rien, ou je me trompe ?

il y a sans doute un bug de copy/paste dans

 if (nbrPushBtnX >= 3)
    {
      nbrPushBtnX == 3;
    }
    
    if (ps2x.Button(PSB_SQUARE))
    {
      nbrPushBtnX == 0;
    }

je suppose que c'est une affection qu'il faut faire et pas un test

oui c'est vrai il s' agit du code fourni avec la librairie.
il me parait plus pédagogue de savoir comprendre et modifié un code avant de créer de toutes pièces.

je comprends que ça ne s'écrit pas comme cela mais une faute de frappe m'à conduit à ça et c'est ce qui fonctionne. :confused:

cette partie de code n'a pas encore été testée, mais effectivement je vois mes fautes. Quelques symboles = en trop.