Ps2 controller exploitation des données joysticks

Bonjour à tous, et merci d'être là pour aider les bizus de mon genre qui ont des projets plein la tête mais pas le niveau pour les réaliser.

Le projet final est de contrôler le model réduit d'une excavatrice,(7 moteurs au total)
à l'aide d'une manette de PS2 via nrf24l01. Aujourd'hui je cherche déjà à faire fonctionner en mode "filaire".

Aucun suspense tout est dans le titre.

Alors voilà la manette et la lecture des boutons et joysticks fonctionne sans problème (visuel sur moniteur série)
mais lorsque je veux faire fonctionner les commandes via les joysticks rien ne se passe.
il s'agit très probablement d'un problème de code (je suis loin d'être un expert), si quelqu'un peut me guider pour trouvé mon erreur (ou mes erreurs).
Voici le code avec lequel je fais mes test : c'est un code produit par Jml que j'ai adapté à mes besoin.

#include <PS2X_lib.h> /* PS2 Controller Library http://www.billporter.info/2010/06/05/playstation-2-controller-arduino-library-v1-0/ */
PS2X ps2x; /* on crée l'instance du controleur */

// information http://www.rhydolabz.com/wiki/?p=12663

// Connecter de gauche à droite en regardant le connecteur
// ----------------------
// Data --> pin 12
// Command --> pin 11
// NC
// ----------------------
// GND --> GND
// Power --> 3.3V
// Attention --> Pin 10
// ----------------------
// Clock --> pin 13
// NC
// NC
// ----------------------         Mega          Uno
#define chenilleGenB        2    //   3   pmw
#define chenilleGin3        24   //   2
#define chenilleGin4        22   //   4
const byte dataPin = 14;
const byte commandPin = 15;
const byte attentionPin = 16;
const byte clockPin = 17;

static int PRX = 127, PRY = 128, PLX = 127, PLY = 128;
int RX , RY , LX , LY ;
int valLY;



void avanceChenilleGauche(){

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

void reculChenilleGauche(){

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

void setup() {
  
   pinMode(chenilleGenB, OUTPUT);   //pmw
   pinMode(chenilleGin3, OUTPUT);
   pinMode(chenilleGin4, OUTPUT);
   
   digitalWrite(chenilleGin3, 0);
   digitalWrite(chenilleGin4, 0);
  
  
  Serial.begin(115200);

  /* config_gamepad(clock, command, attention, data, Pressures?, Rumble?) */
  ps2x.config_gamepad(clockPin, commandPin, attentionPin, dataPin, true, true); // gardez true, true à la fin même si pas de moteurs

  if (ps2x.readType() == 1) Serial.println(F("DualShock"));
  else {
    Serial.print(F("Manette Absente - code "));
    Serial.println(ps2x.readType());
    while (true); // on meurt ici, éventuellement enlever si vous avez un autre code manette
  }

  ps2x.read_gamepad(); // initialisation des valeurs
  delay(50);
  ps2x.read_gamepad();  /* initialise les états */
}


void loop() {
  static uint32_t chrono = 0;
  const uint32_t periode = 20ul; // la manette est assez sensible, il ne faut pas lui demander les infos trop souvent. 15ms ou 20ms ça fonctionne pour moi

  if (millis() - chrono >= periode) {
    
    

    chrono += periode;

    ps2x.read_gamepad();   /* on lit l'état de la manette */

    LX = ps2x.Analog(PSS_LX);          /* joystick de gauche X*/
    LY = ps2x.Analog(PSS_LY);          /* joystick de gauche Y */
    RX = ps2x.Analog(PSS_RX);          /* joystick de droite X */
    RY = ps2x.Analog(PSS_RY);          /* joystick de droite Y */
    
    si une des coordonnées des joystick a changé alors on imprime les nouvelles coordonnées
   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);  
      
      LY = map(valLY,0,255,0,1024);   //je mets la valeur du potentiometre aux proportions la sortie pmw
      
      if(valLY>140)                  
      {  
      avanceChenilleGauche();
      }
    
    else
  {
    digitalWrite(chenilleGin4, 0);  
  }
      
      
      if(valLY<113)
      {
       reculChenilleGauche();
     }
       
     else
  {
    digitalWrite(chenilleGin3, 0);  
  }  
  

/*

    // if (ps2x.NewButtonState()) {}  /* vrai s'il y a un changement d'état, si on ne veut pas lire l'état à la main  

    // ButtonPressed(unsigned int) vrai si le bouton VIENT d'être appuyé (depuis la dernière lecture de config)
    if (ps2x.ButtonPressed(PSB_START))     Serial.println(F("START APPUI"));
    if (ps2x.ButtonPressed(PSB_SELECT))    Serial.println(F("SELECT APPUI"));
    if (ps2x.ButtonPressed(PSB_PAD_UP))    Serial.println(F("HAUT APPUI"));
    if (ps2x.ButtonPressed(PSB_PAD_RIGHT)) Serial.println(F("DROIT APPUI"));
    if (ps2x.ButtonPressed(PSB_PAD_LEFT))  Serial.println(F("GAUCHE APPUI"));
    if (ps2x.ButtonPressed(PSB_PAD_DOWN))  Serial.println(F("BAS APPUI"));
    if (ps2x.ButtonPressed(PSB_L1))        Serial.println(F("GAUCHE 1 APPUI"));
    if (ps2x.ButtonPressed(PSB_R1))        Serial.println(F("DROITE 1 APPUI"));
    if (ps2x.ButtonPressed(PSB_L2))        Serial.println(F("GAUCHE 2 APPUI"));
    if (ps2x.ButtonPressed(PSB_R2))        Serial.println(F("DROITE 2 APPUI"));
    if (ps2x.ButtonPressed(PSB_GREEN))     Serial.println(F("Triangle APPUI"));
    if (ps2x.ButtonPressed(PSB_BLUE))      Serial.println(F("X APPUI"));
    if (ps2x.ButtonPressed(PSB_RED))       Serial.println(F("Cercle APPUI"));
    if (ps2x.ButtonPressed(PSB_PINK))      Serial.println(F("Carre APPUI"));

    // Button(uint16_t); vrai si le bouton est tenu enfoncé
    if (ps2x.Button(PSB_START))     Serial.println(F("START"));
    if (ps2x.Button(PSB_SELECT))    Serial.println(F("SELECT"));
    if (ps2x.Button(PSB_PAD_UP))    Serial.println(F("HAUT"));
    if (ps2x.Button(PSB_PAD_RIGHT)) Serial.println(F("DROITE"));
    if (ps2x.Button(PSB_PAD_LEFT))  Serial.println(F("GAUCHE"));
    if (ps2x.Button(PSB_PAD_DOWN))  Serial.println(F("BAS"));
    if (ps2x.Button(PSB_L1)) Serial.println(F("GAUCHE 1"));
    if (ps2x.Button(PSB_R1))Serial.println(F("DROITE 1"));
    if (ps2x.Button(PSB_L2))Serial.println(F("GAUCHE 2"));
    if (ps2x.Button(PSB_R2))Serial.println(F("DROITE 2"));
    if (ps2x.Button(PSB_GREEN))     Serial.println(F("Triangle"));
    if (ps2x.Button(PSB_BLUE))      Serial.println(F("X"));
    if (ps2x.Button(PSB_RED))       Serial.println(F("Cercle"));
    if (ps2x.Button(PSB_PINK))      Serial.println(F("Carre"));

    // ButtonReleased(unsigned int) vrai si le bouton VIENT d'être relâché (depuis la dernière lecture de config)
    if (ps2x.ButtonReleased(PSB_START))     Serial.println(F("START RELACHE"));
    if (ps2x.ButtonReleased(PSB_SELECT))    Serial.println(F("SELECT RELACHE"));
    if (ps2x.ButtonReleased(PSB_PAD_UP))    Serial.println(F("HAUT RELACHE"));
    if (ps2x.ButtonReleased(PSB_PAD_RIGHT)) Serial.println(F("DROITE RELACHE"));
    if (ps2x.ButtonReleased(PSB_PAD_LEFT))  Serial.println(F("GAUCHE RELACHE"));
    if (ps2x.ButtonReleased(PSB_PAD_DOWN))  Serial.println(F("BAS RELACHE"));
    if (ps2x.ButtonReleased(PSB_L1))        Serial.println(F("GAUCHE 1 RELACHE"));
    if (ps2x.ButtonReleased(PSB_R1))        Serial.println(F("DROITE 1 RELACHE"));
    if (ps2x.ButtonReleased(PSB_L2))        Serial.println(F("GAUCHE 2 RELACHE"));
    if (ps2x.ButtonReleased(PSB_R2))        Serial.println(F("DROITE 2 RELACHE"));
    if (ps2x.ButtonReleased(PSB_GREEN))     Serial.println(F("Triangle RELACHE"));
    if (ps2x.ButtonReleased(PSB_BLUE))      Serial.println(F("X RELACHE"));
    if (ps2x.ButtonReleased(PSB_RED))       Serial.println(F("Cercle RELACHE"));
    if (ps2x.ButtonReleased(PSB_PINK))      Serial.println(F("Carre RELACHE"));*/
  }
}

Post déplacé dans la partie francophone

Vous avez quoi comme arduino? Essayez avec 255 au lieu de 1024

j'utilise un Mega2560 pour les test ,et un Uno pour le montage final.

à vrai dire normalement c'est valLY qui devrai se trouver là.
Mais avant de demander de l'aide j'ai retourné ce code dans tous les sens.
Ce qui m'a permis de m'apercevoir que le module XY160d (non-officiel) que j'utilisais ne fonctionne pas correctement, les entrées enA et enB ne fonctionnent pas, peut importe la valeur saisie de -1024 à 1024 (toutes testée par tranche de 100) le moteur tourne à pleine vitesse.

Bref, changement de module, reprise des bases avec un simple potentiomètre, test de fonctionnement ok.
je refais le montage avec la manette et me voilà à demander de l'aide à la communauté.

je viens de rééssayer avec 255 à la place de 1024, même résultat. :frowning_face:

La fonction analogWrite prend une valeur entre 0 et 255 et il faut bien sûr être sur une pin PWM ( ce qui est le can pour la pin D2 sur une mega mais pas pour une UNO)

BOARD PWM PINS PWM FREQUENCY
Uno, Nano, Mini 3, 5, 6, 9, 10, 11 490 Hz (pins 5 and 6: 980 Hz)
Mega 2 - 13, 44 - 46 490 Hz (pins 4 and 13: 980 Hz)

Postez un schéma complet du montage avec une description de tous les composants impliqués

j'ai installé fritzing pour un résultat plus propre et plus clair qu'un croquis papier.

le module de puissance ne correspond pas à celui que j'utilise, les résistances sur le schéma ne sont pas calibrées (mais pour le raccordement j'ai bien suivi les instructions données par Bill Porter)

ici le module que j'utilise

ici le module que je n'utilise plus

Bonjour m122

Il existe du "tout fait"
image
Je l'ai essayé avec la bibliothèque PS2X_lib.h et cet exemple.

Cordialement
jpbbricole

bonjour jpbbricole,
j'ai vu ce type de produit, mais mon but étant plus d'apprendre que de faire du fonctionnel.
Je préfère tout "créer" de A à Z, comme l'excavatrice qui sera commandée avec cette manette.


il y a 3 moteurs d'essuie glace (1 pour chaque chenille et 1 pour la rotation tourelle)
et 3 moteurs de lève vitres pour les mouvements du bras,du balancier et du godet.
(je peux publier d'autres photos sur demande)

ici avec un rotofil à la place du godet. (juste pour dire à ma femme je ne peux pas "chérie je doit tondre la pelouse" :grin:

1 Like

pour palier les éventuelles erreurs de câblage, je me suis procuré un shield enfichable sur le Uno.
uniquement pour les tests avec moteurs de faible puissance.
Et pas d'amélioration, je ne peux toujours pas commander les moteurs via les joysticks

Bonjour m122

Je comprends tout à fait :+1:
Ta machine est magnifique!
Tu pourras passer le rotofil, assis dans un fauteuil!

Cordialement
jpbbricole

Bonsoir m122

J'ai essayé ton code, il fonctionne très bien, dans la console j'ai:

DualShock
255 ,6 ,0 ,99
255 ,44 ,0 ,128
255 ,90 ,0 ,128
255 ,128 ,0 ,128
255 ,128 ,0 ,205
255 ,128 ,0 ,255
255 ,255 ,127 ,255
248 ,255 ,127 ,255
156 ,255 ,127 ,255
127 ,255 ,127 ,255
127 ,255 ,182 ,255
0 ,245 ,255 ,196
0 ,179 ,255 ,158
0 ,128 ,255 ,128
0 ,128 ,255 ,98
0 ,121 ,255 ,54
0 ,77 ,255 ,20
0 ,39 ,255 ,0
44 ,0 ,127 ,0
78 ,0 ,127 ,0
127 ,0 ,127 ,0
163 ,0 ,127 ,0
255 ,0 ,127 ,0
255 ,0 ,93 ,0
255 ,0 ,21 ,0
255 ,2 ,0 ,0
255 ,49 ,0 ,3
255 ,94 ,0 ,91
255 ,128 ,0 ,128
255 ,128 ,0 ,255
255 ,189 ,0 ,255
255 ,247 ,34 ,255
255 ,255 ,101 ,255
255 ,255 ,127 ,255
224 ,255 ,127 ,255
158 ,255 ,127 ,255
0 ,255 ,255 ,229
0 ,255 ,255 ,199
0 ,255 ,255 ,128
0 ,248 ,255 ,128
0 ,128 ,255 ,128
0 ,128 ,255 ,118
0 ,96 ,255 ,80
0 ,69 ,255 ,49
0 ,37 ,255 ,19
0 ,0 ,255 ,0
0 ,0 ,249 ,0
127 ,128 ,127 ,128

en tournant les joystick.
Avec ce brochage:

const byte dataPin = 12 ;//14;
const byte commandPin = 11; //15;
const byte attentionPin = 10; //16;
const byte clockPin = 13; //17;

Qui est préférable au tiens, du fait que la version finale sera sur UNO, tu n'aura rien à changer.

La version complète que j'ai testé:

#include <PS2X_lib.h> /* PS2 Controller Library http://www.billporter.info/2010/06/05/playstation-2-controller-arduino-library-v1-0/ */
PS2X ps2x; /* on crée l'instance du controleur */

// information http://www.rhydolabz.com/wiki/?p=12663

// Connecter de gauche à droite en regardant le connecteur
// ----------------------
// Data --> pin 12
// Command --> pin 11
// NC
// ----------------------
// GND --> GND
// Power --> 3.3V
// Attention --> Pin 10
// ----------------------
// Clock --> pin 13
// NC
// NC
// ----------------------         Mega          Uno
#define chenilleGenB        2    //   3   pmw
#define chenilleGin3        24   //   2
#define chenilleGin4        22   //   4
const byte dataPin = 12 ;//14;
const byte commandPin = 11; //15;
const byte attentionPin = 10; //16;
const byte clockPin = 13; //17;

static int PRX = 127, PRY = 128, PLX = 127, PLY = 128;
int RX , RY , LX , LY ;
int valLY;



void avanceChenilleGauche(int vitessePWM)
{
	Serial.print("avanceChenilleGauche vitesse\t"); Serial.println(vitessePWM);

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

void reculChenilleGauche(int vitessePWM)
{
	Serial.print("reculChenilleGauche vitesse\t"); Serial.println(vitessePWM);

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

void setup() 
{
  
   pinMode(chenilleGenB, OUTPUT);   //pmw
   pinMode(chenilleGin3, OUTPUT);
   pinMode(chenilleGin4, OUTPUT);
   
   digitalWrite(chenilleGin3, 0);
   digitalWrite(chenilleGin4, 0);
  
  
	Serial.begin(115200);

	/* config_gamepad(clock, command, attention, data, Pressures?, Rumble?) */
	ps2x.config_gamepad(clockPin, commandPin, attentionPin, dataPin, true, true); // gardez true, true à la fin même si pas de moteurs

	if (ps2x.readType() == 1) 
	{
		Serial.println(F("DualShock"));
	}
	else 
	{
		Serial.print(F("Manette Absente - code "));
		Serial.println(ps2x.readType());
		while (true); // on meurt ici, éventuellement enlever si vous avez un autre code manette
	}

	ps2x.read_gamepad(); // initialisation des valeurs
	delay(50);
	ps2x.read_gamepad();  /* initialise les états */
}


void loop() 
{
	static uint32_t chrono = 0;
	const uint32_t periode = 20ul; // la manette est assez sensible, il ne faut pas lui demander les infos trop souvent. 15ms ou 20ms ça fonctionne pour moi

	if (millis() - chrono >= periode) 
	{
		chrono += periode;

		ps2x.read_gamepad();   /* on lit l'état de la manette */

		LX = ps2x.Analog(PSS_LX);          /* joystick de gauche X*/
		LY = ps2x.Analog(PSS_LY);          /* joystick de gauche Y */
		RX = ps2x.Analog(PSS_RX);          /* joystick de droite X */
		RY = ps2x.Analog(PSS_RY);          /* joystick de droite Y */
    
		//si une des coordonnées des joystick a changé alors on imprime les nouvelles coordonnées
		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);  
      
		if(LY>140)                  
		{  
			LY = map(LY,140,255,0,255);
			avanceChenilleGauche(LY);
		}
		else
		{
			digitalWrite(chenilleGin4, 0);  
		}
		
		if(LY<113)
		{
			LY = map(LY,113,0,0,255);
			reculChenilleGauche(LY);
		}
		else
		{
			digitalWrite(chenilleGin3, 0);
		}
	}
      
  

/*

    // if (ps2x.NewButtonState()) {}  /* vrai s'il y a un changement d'état, si on ne veut pas lire l'état à la main  

    // ButtonPressed(unsigned int) vrai si le bouton VIENT d'être appuyé (depuis la dernière lecture de config)
    if (ps2x.ButtonPressed(PSB_START))     Serial.println(F("START APPUI"));
    if (ps2x.ButtonPressed(PSB_SELECT))    Serial.println(F("SELECT APPUI"));
    if (ps2x.ButtonPressed(PSB_PAD_UP))    Serial.println(F("HAUT APPUI"));
    if (ps2x.ButtonPressed(PSB_PAD_RIGHT)) Serial.println(F("DROIT APPUI"));
    if (ps2x.ButtonPressed(PSB_PAD_LEFT))  Serial.println(F("GAUCHE APPUI"));
    if (ps2x.ButtonPressed(PSB_PAD_DOWN))  Serial.println(F("BAS APPUI"));
    if (ps2x.ButtonPressed(PSB_L1))        Serial.println(F("GAUCHE 1 APPUI"));
    if (ps2x.ButtonPressed(PSB_R1))        Serial.println(F("DROITE 1 APPUI"));
    if (ps2x.ButtonPressed(PSB_L2))        Serial.println(F("GAUCHE 2 APPUI"));
    if (ps2x.ButtonPressed(PSB_R2))        Serial.println(F("DROITE 2 APPUI"));
    if (ps2x.ButtonPressed(PSB_GREEN))     Serial.println(F("Triangle APPUI"));
    if (ps2x.ButtonPressed(PSB_BLUE))      Serial.println(F("X APPUI"));
    if (ps2x.ButtonPressed(PSB_RED))       Serial.println(F("Cercle APPUI"));
    if (ps2x.ButtonPressed(PSB_PINK))      Serial.println(F("Carre APPUI"));

    // Button(uint16_t); vrai si le bouton est tenu enfoncé
    if (ps2x.Button(PSB_START))     Serial.println(F("START"));
    if (ps2x.Button(PSB_SELECT))    Serial.println(F("SELECT"));
    if (ps2x.Button(PSB_PAD_UP))    Serial.println(F("HAUT"));
    if (ps2x.Button(PSB_PAD_RIGHT)) Serial.println(F("DROITE"));
    if (ps2x.Button(PSB_PAD_LEFT))  Serial.println(F("GAUCHE"));
    if (ps2x.Button(PSB_PAD_DOWN))  Serial.println(F("BAS"));
    if (ps2x.Button(PSB_L1)) Serial.println(F("GAUCHE 1"));
    if (ps2x.Button(PSB_R1))Serial.println(F("DROITE 1"));
    if (ps2x.Button(PSB_L2))Serial.println(F("GAUCHE 2"));
    if (ps2x.Button(PSB_R2))Serial.println(F("DROITE 2"));
    if (ps2x.Button(PSB_GREEN))     Serial.println(F("Triangle"));
    if (ps2x.Button(PSB_BLUE))      Serial.println(F("X"));
    if (ps2x.Button(PSB_RED))       Serial.println(F("Cercle"));
    if (ps2x.Button(PSB_PINK))      Serial.println(F("Carre"));

    // ButtonReleased(unsigned int) vrai si le bouton VIENT d'être relâché (depuis la dernière lecture de config)
    if (ps2x.ButtonReleased(PSB_START))     Serial.println(F("START RELACHE"));
    if (ps2x.ButtonReleased(PSB_SELECT))    Serial.println(F("SELECT RELACHE"));
    if (ps2x.ButtonReleased(PSB_PAD_UP))    Serial.println(F("HAUT RELACHE"));
    if (ps2x.ButtonReleased(PSB_PAD_RIGHT)) Serial.println(F("DROITE RELACHE"));
    if (ps2x.ButtonReleased(PSB_PAD_LEFT))  Serial.println(F("GAUCHE RELACHE"));
    if (ps2x.ButtonReleased(PSB_PAD_DOWN))  Serial.println(F("BAS RELACHE"));
    if (ps2x.ButtonReleased(PSB_L1))        Serial.println(F("GAUCHE 1 RELACHE"));
    if (ps2x.ButtonReleased(PSB_R1))        Serial.println(F("DROITE 1 RELACHE"));
    if (ps2x.ButtonReleased(PSB_L2))        Serial.println(F("GAUCHE 2 RELACHE"));
    if (ps2x.ButtonReleased(PSB_R2))        Serial.println(F("DROITE 2 RELACHE"));
    if (ps2x.ButtonReleased(PSB_GREEN))     Serial.println(F("Triangle RELACHE"));
    if (ps2x.ButtonReleased(PSB_BLUE))      Serial.println(F("X RELACHE"));
    if (ps2x.ButtonReleased(PSB_RED))       Serial.println(F("Cercle RELACHE"));
    if (ps2x.ButtonReleased(PSB_PINK))      Serial.println(F("Carre RELACHE"));*/
  }
}

Cordialement
jpbbricole

merci !

c'est exactement l'idée.

c'est ça qu'il me manquait ! tous les cours et tutos que j'ai suivi laissent les parenthèses vides.
je vient de tester , c'est bon il y à de la vie !!! le moteur tourne et accélère en fonction du joystick.

UN TRES GRAND MERCI A TOI.

je code le reste (mode filaire) et le poste dès que possible

cependant la version finale sera sur Mega car chaque moteur à besoin de 3 bornes dont 1 PWM,
et j'ai 7 moteurs à contrôler, soit 21 bornes + 4 pour la manette en filaire (et 5 lorsque le nrf24l01 sera opérationnel.

Bonsoir m122

Je me réjouis de voire ça!

A+
jpbbricole

Voici le code quasi final du projet, code assez long et pas vraiment optimisé (du tout) mais ça j,ai pas encore le niveau. Je suis déjà content de ne pas avoir eu d'erreur de compilation. :kissing_smiling_eyes:

Cependant j'ai un petit souci je pense dû à un problème de map dès que la valeur d'un joystick se rapproche des 192 le moteur s'arrête et dès que la valeur dépasse les 192 le moteur tourne en sens inverse ( avec contrôle de la vitesse sur la plage des 200 à 255).

Quelques petits changements point de vue commande afin d'améliorer la maniabilité du robot.

R1/R2 marche avant/arrière chenille droite
L1/L2 marche avant/arrière chenille gauche
RY montée/descente bras principal
RX inclinaison du godet (rotofil)
LY montée/descente du balancier(bras secondaire)
LX rotation de la tourelle
Croix (bleu) mise en marche du rotofil (3 vitesses)
Carré (violet) arrêt du rotofil

#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         4    //       pwm
#define tourelleIn1         30
#define tourelleIn2         32
#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 vitesseLX){

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

void tourelleTourneGauche(int vitesseLX){

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

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 vitesseRX){

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

void godetFerme(int vitesseRX){

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

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,140,255,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,140,255,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,140,255,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,140,255,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) ;
}

et les balises de code... :frowning: (pas des Blockquote)

Merci d'éditer votre post pour rajouter les balises de de code, c'est quasiment illisible tel quel:

  • sélectionner la partie du texte qui correspond au code
  • appuyez sur l'icône </> dans la barre d'outils pour indiquer que c'est du code

(Assurez vous aussi d'indenter le code correctement dans l'IDE avant de le copier pour le coller ici. Cela se fait en pressant ctrlT sur PC ou cmdT sur un Mac)

autant pour moi désolé, besoin d'un peu de temps pour prise en main.

pas de souci, merci d'avoir corrigé

pour map() quand vous faites par exemple LY = map(LY,113,0,0,255); si LY n'est pas entre 113 et 0 alors le LY résultant de l'appel de map() ne sera pas enter 0 et 255. map() fait juste une fonction affine entre les 2 points donnés et si votre point pour le calcul est en dehors des 2 bornes alors le résultat est lui aussi en dehors des bornes

sur le moniteur série la valeur des joysticks est bien de 0 à 255,
avec une imprécision joystick relaché de 115 à 138 (manette usée)
je comprends votre explication de map() mais je ne comprend pas pourquoi ce problème n'est présent que dans les valeurs supérieur à 140 ? la plage < 113 fonctionne parfaitement

Bonjour

Je plussoie m122, dans le programme il est dit:

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

Donc le map() fonctionnera, donc "dans les cordes".

Cordialement
jpbbricole