Problemme sur les commandes recues d'un joystick

Bonsoir a tous. J'espere que vous m'aidez avec ca. Je suis en traint de faire mon projet BAC qui consiste en creer un voiture a 2 moteurs teledirige par un joystick. J'utilise le module RF 433MHZ pour la connexion entre le joystick et la carte arduino.
Dans l'Arduino je recois des commandes comme X= 512 et Y=517 qui varient de 0 a 1023. Le problemme est que j'ai besoin d'un code qui fait disparaitre le X et Y pour utiliser les commandes variantes pour faire fonctionner.
Sur mon code que je n'ai pas finit, on a des intervalles pour diriger les moteurs comme par exemple:

if (Xaxis < 470)
in1 (HIGH)
in2 (LOW)
in3 (HIGH)
in4 (LOW)
Donc le problemme est que il faut un code que fait que les commandes recues du joystick comme X= 512 doit remplacer le Xaxis de mon exemple pour faire fonctionner la voiture.

Le BAC je le passe le 6 ou 7 juin. SVP aidez moi.
Excusez moi des erreurs d'ecriture.

Dans ta boucle for ou tu affiches les bytes reçus, il suffit de tester si ils sont égaux à'x' ou 'y'. Tu sais que le caractère suivant est ':'
Lorsque tu sais l'indice du caractère ':' tu n'as plus qu'à lire les bytes suivants pour calculer la valeur de x ou y

ca serait bien de voir le code entier, entre balise code </>
comment est relié le joystick?

Merci de votre reponse. Lespt je n'ai pas compris ca "Lorsque tu sais l'indice du caractère ':' tu n'as plus qu'à lire les bytes suivants pour calculer la valeur de x ou y". Excuse moi mais je ne suis pas francais.

Voila le code;
<
#include <VirtualWire.h>

void setup()
{
Serial.begin(9600);
Serial.println("Début communication");

vw_setup(2000);

vw_rx_start();

}

void loop()
{
uint8_t msgRecu[VW_MAX_MESSAGE_LEN];
uint8_t longueurMsg = VW_MAX_MESSAGE_LEN;

if (vw_wait_rx_max(200))
{
if (vw_get_message(msgRecu, &longueurMsg))
{
Serial.print("On recoit : ");
for (byte i = 0; i < longueurMsg; i++)
Serial.write(msgRecu*);*

  • Serial.print("\n");*

  • }*

  • }*

  • //on simule le message recu x513*

  • msgRecu[0]="x";*

  • msgRecu[1]="5";*

  • msgRecu[2]="1";*

  • msgRecu[3]="3"; *

  • //decodage*

  • yAxis = msgrecu[4] + msgrecu[5] +msgrecu[6]*

//----------------------------------------------

  • if (yAxis < 470){*

  • //Code moteur marche avant*

  • }*

  • else if (yAxis > 550) {*

  • //Code moteur marche arriere*

  • }*
    //-----------------------------------------------

  • xAxis = msgrecu[4] + msgrecu[5] +msgrecu[6]*
    //-----------------------------------------------

  • if (xAxis < 470) {*

  • //Code moteur droite*

  • }*

  • else if (yAxis > 550) {*

  • //Code moteur marche arriere*

  • }*
    //-----------------------------------------------

//data branche sur la broche 11
>
Mon gros problemme c'est que je ne suis pas un pro sur le codage mais je connais tres bien ce qu'il faut faire
Pour vous expliquer mielleux, je dois stoker la valeur reçue x et y dans des variables Xaxis ey Yaxis. Maiis avant sa, il faut enlever les x: et y: pour utiliser la valeur.
J'ai parle déjà avec mon copain qui travaille sur le joystick 'sa partie) et je lui demande de m'envoyer des commandes comme X512 sans avoir le : entre x et la valeur. Je crois que sa va etre plus facile.
Le prof que on a n'explique pas bien. Merci
Reception commandes du joystick.ino (1.26 KB)

me disais bien sujet bac ou exam.
alors tu vas commencer par lire
REGLES DU FORUM

Bonjour,

Vous vous prenez la tête a vouloir décodé une trame entière.

Si le but est de diriger le robot purement et simplement alors je vous conseille de définir des macros pour chaque mouvements.

Je reçois 1 le robot avance.
Je reçois 2 le robot recule.

//on simule le message recu x513
msgRecu[0]="x";
msgRecu[1]="5";
msgRecu[2]="1";
msgRecu[3]="3";

Sur l'image on voit "x:513", c'est pourquoi je disais de chercher le caractère ":".
Mais si TOUS tes messages sont TOUJOURS de la forme "x:nnn" ou "y:nnn" avec n un nombre entre 0 et 9, il te suffit de reconstruire la valeur de x ou y à partir des 3 chiffres qui sont dans msgrecu[4], msgrecu[5]
et msgrecu[6], par exemple :

xAxis = msgrecu[4]*100 + msgrecu[5]*10 +msgrecu[6];

lesept:
Mais si TOUS tes messages sont TOUJOURS de la forme "x:nnn" ou "y:nnn" avec n un nombre entre 0 et 9, il te suffit de reconstruire la valeur de x ou y à partir des 3 chiffres qui sont dans msgrecu[4], msgrecu[5]
et msgrecu[6], par exemple :

xAxis = msgrecu[4]*100 + msgrecu[5]*10 +msgrecu[6];

Attention il faut soustraire la valeur ASCII de ‘0’ aux caractères reçus si vous prenez cette formule

xAxis = (msgrecu[4]-‘0’)*100 + (msgrecu[5]-‘0’)*10 +(msgrecu[6]-‘0’);

//on simule le message recu x513

msgRecu[0]="x";
msgRecu[1]="5";
msgRecu[2]="1";
msgRecu[3]="3";

ATTENTION ne pas confondre les guillemets (cString) et les apostrophes (caractères):

//on simule le message recu x513
 msgRecu[0]=‘x’;
 msgRecu[1]=‘5’;
 msgRecu[2]=‘1’;
 msgRecu[3]=‘3’;

Merci pour votre réponse a tous.
J'ai quelques questions.
Pourquoi on doit soustraire la valeur ASCII ('0')?
Si les valeur reçues sont de la forme XNNN et pas X:NNN sa change quelque chose sur le code? (Pour moi je crois que le code est le même).

Pouvez vous m'aider a dire si le code est bon car je sens que j'ai un erreur sur le yAxis, sur la partie msgRecu[].

#include <VirtualWire.h>


void setup()
{
Serial.begin(9600);
Serial.println("Début communication");

vw_setup(2000);
    
vw_rx_start();
  
}

void loop()
{
uint8_t msgRecu[VW_MAX_MESSAGE_LEN]; 
uint8_t longueurMsg = VW_MAX_MESSAGE_LEN;

 if (vw_wait_rx_max(200))
{
    if (vw_get_message(msgRecu, &longueurMsg))
    {
        Serial.print("On recoit : ");
        for (byte i = 0; i < longueurMsg; i++)
            Serial.write(msgRecu);
        Serial.print("\n");
    }
}

yAxis = (msgrecu[4]-'0')*100 + (msgrecu[5]-'0')*10 +(msgrecu[6]-'0');
xAxis = (msgrecu[4]-'0')*100 + (msgrecu[5]-'0')*10 +(msgrecu[6]-'0');
  

//intervalles

Merci de répondre aux questions ci dessous:

ismaelely:
Pourquoi on doit soustraire la valeur ASCII ('0')?

votre tableau contient des codes ASCII (un nombre qui représente un symbole de texte)

=> quelle est la valeur en décimal du symbole ‘7’ par exemple en ASCII ?
Connaissant cela si vous multipliez cela par 100, pensez vous obtenir 700 ?
=> maintenant quelle est la valeur du symbole ‘0’ en ASCII ? Et si vous soustrayez cette valeur à celle du symbole ‘7’, combien obtenez vous ? Et combien donc ça fait en multipliant par 100 ?Ré-éssayez avec le symbole ‘3’ ou ‘9’, qu’est-ce que ça donne ?

ismaelely:
Si les valeur reçues sont de la forme XNNN et pas X:NNN sa change quelque chose sur le code? (Pour moi je crois que le code est le même).

Si vous recevez color=blue]XNNN[/color] quel est le caractère en msgrecu[1] et son code ASCII ?
Si vous recevez color=blue]X:NNN[/color] quel est le caractère en msgrecu[1] et son code ASCII ?
=> que pensez vous que votre formule

je sens que j'ai un erreur sur le yAxis

Ben vous avez écrit

yAxis = (msgrecu[4]-'0')*100 + (msgrecu[5]-'0')*10 +(msgrecu[6]-'0');
xAxis = (msgrecu[4]-'0')*100 + (msgrecu[5]-'0')*10 +(msgrecu[6]-'0');

vous voyez une différence entre les deux calculs ? Moi pas... donc xAxis et yAxis auront la même valeur calculée à chaque tour de boucle (que l’on ait reçu ou pas un message)

Que pensez vous imprimer avec ceci ?

for (byte i = 0; i < longueurMsg; i++)
            Serial.write(msgRecu);

Merci pour me repondre.

=> quelle est la valeur en décimal du symbole '7' par exemple en ASCII ?

39+55+39=133

Connaissant cela si vous multipliez cela par 100, pensez vous obtenir 700 ?

133*100=13 300 Donc on obtient 13300 donc non.

=> maintenant quelle est la valeur du symbole '0' en ASCII ?

39+48+39=126

Et si vous soustrayez cette valeur à celle du symbole '7', combien obtenez vous ?

133-126=7
Et combien donc ça fait en multipliant par 100 ?

7*100= 700

Ré-éssayez avec le symbole '3' ou '9', qu'est-ce que ça donne ?

'3'// 39+51+39=129 Donc 129-126=3 Donc 3*100= 300

'9'// 39+57+39=135 Donc 135-126=9 Donc 9*100= 900

Si vous recevez color=blue]XNNN[/color] quel est le caractère en msgrecu[1] et son code ASCII ?

msgrecu[1]= N

Si vous recevez color=blue]X:NNN[/color] quel est le caractère en msgrecu[1] et son code ASCII ?

msgrecu[1]= :

=> que pensez vous que votre formule
Maintenant j'ai vien compris. Ma formule est fausse car les msg recu changent.

Que pensez vous imprimer avec ceci ?

for (byte i = 0; i < longueurMsg; i++)
Serial.write(msgRecu);

CETTE DERNIERE QUESTION JE NE L'AI PAS COMPRIS mais ce que j'ai compris de votre question est que je recois sa: XNNN l YNNN

Merci beaucoup pour cette aide. Maintenant j'ai bien compris sur le code ASCII et les formules.

J'ai trouve un problème sur le code je crois.

//on simule le message recu x513
msgRecu[0]='x';
msgRecu[1]='5';
msgRecu[2]='1';
msgRecu[3]='3';

yAxis = (msgrecu[1]-'0')*100 + (msgrecu[2]-'0')*10 +(msgrecu[3]-'0');
xAxis = (msgrecu[1]-'0')*100 + (msgrecu[2]-'0')*10 +(msgrecu[3]-'0');

Dans cette formule, on voit que il marche avec 3 valeurs XNNN mais si je recois par exemple 1023 (XNNNN), le code ne marchera pas.
Je me bloque ici.

C'est une bonne question et c'est normal que tu sois bloqué. Pour résoudre ce problème, il faut que ton collègue envoie à la fin du message 'x123' un caractère supplémentaire qui indique la fin du message. Ce caractère ne doit pas être pris pour une valeur, et doit être toujours le même. Ce doit être une convention de communication entre vous. C'est un élément de votre protocole de communication.

Supposons que ce caractère soit un "+". Alors tu recevras de messages du genre "x123+y456+'. Lorsque tu reconstruiras tes nombres 123 et 456, tu le feras en t'arrêtant au caractère de fin "+".

Tu peux le faire de différentes façons : je te laisse y réfléchir...

quelle est la valeur en décimal du symbole '7' par exemple en ASCII ?

39+55+39=133

Non :slight_smile:

Les apostrophes ne font pas partie du symbole - je les avais mis juste pour isoler le 7 ...

Donc le code c’est bien 55 et quand vous faites 55 x 100 votre formule ne fait pas 700

Comme les code ascii des chiffres sont consécutifs, si vous soustrayez celui du symbole 0 alors vous obtenez le chiffre associé à ce symbole

Vous devriez formater ce que vous recevez comme une cString (in tableau de caractères avec un 0 à la fin) et vous pouvez utiliser les fonctions C standard telle que stdlib.h ou string.h

Si vous lisez l’anglais ce post est très bien pour comprendre comment gérer une communication série. Serial Input Basics

Mettez un symbole en début de chaîne et un autre à la fin - ça permet de lire simplement la valeur associé et regardez éventuellement la fonction atoi()

En utilisant x: et y: comme des balises, il suffit ensuite de créer un int avec int X=x-'0'

L'acquisition d'un byte entier se fait comme dans ce code:

// EXEMPLE 2
// Reconnaitre une balise et lire un byte

//Servo
#include <Servo.h> // Biblio servo
Servo Serv1; // Le nom du servo est Serv1

//HC05
#include<SoftwareSerial.h> // Appelle la bibliothèque pour créer un port série
#define TxD 2 // HC05 Txd -> Arduino D2
#define RxD 3 // On le déclare mais on ne le connecte pas pour cet exemple
SoftwareSerial BTSerial(TxD, RxD); // On déclare notre nouveau port série
#define BTTemoin 4 // BYTE Permet de lire si on est conncte au HC05

//Autres
#define LedPin 13 // Patte longue sur D13, patte courte sur Grnd

void setup() {
  Serv1.attach(9); // Serv1 est sur le PWM D9
  pinMode(BTTemoin , INPUT); // Entree du temoin de connex du BT
  BTSerial.begin(9600); // On démarre notre nouveau port série
  Serial.begin(9600); // On démarre le port série USB
  pinMode(LedPin, OUTPUT); // Ce pin est une sortie
  Serial.println("Prêt"); // On affiche un message sur le moniteur
  BTWait();
}


void BTWait() { //cette fonction indique quand la connexion a lieu
  Serial.print("Attente de connexion ");
  while (digitalRead(BTTemoin) == LOW) {
    Serial.print(".");
    delay(1000);
  }//fin de while
  Serial.println(" ok!");
}//fin de BTWait


void GetBTData() {
  char c = BTSerial.read(); // Alors on stocke ce qu'il reçoit dans c
  if (c == '<') { // Si c est le caractère '<' balise
    StartBTRead();
  }//fin if <
  else {}
}//fin GetBTData


void StartBTRead() {
  digitalWrite(LedPin, HIGH); // On allume la led
  byte BTCode = BTSerial.parseInt(); // on stocke dans chiffre le premier int qui passe
  Serial.print("Le code saisi est ");
  Serial.println(BTCode);
  digitalWrite(LedPin, LOW); //On eteint la led
  Serv1.write(BTCode); // Positionne Serv1
}//fin StartBTRead()


void loop() {
  if (BTSerial.available()) { // Si port série Bluetooth actif
    GetBTData();
  }//fin if available
  if (digitalRead(BTTemoin) == LOW) { // Si pas de connexion
    Serial.println("Bluetooth perdu");
    BTWait();
  }
 }//fin de boucle

Merci de votre reponse.
Il y a une problemme que je n'ai pas reflechi pendant tout cette periode. Le projet c'est un chariot commande par un joystick a distance. Donc si on a 2 chariots de diferents personnes, il y aura des echanges des commandes, ce que on veut pas que se passe.
Donc ce que je dois faire c'est de nomer le joustick par exemple (CHARIOT1) et puis sur le chariot dire si le message recu= CHARIOT1 donc "la suite du code". Vous en pensez quoi??
Merci de votre reponse

Merci de votre aide. J'ai une autre question.
Mon projet c'est un chariot commande par distance par un joystick.
Donc imaginez que on a 2 chariots (chariot 1, chariot 2) dans la rue et l'utilisateur 1 avec le chariot 1 décide de tourner a droite pendant que l'utilisateur 2 avec le chariot 2 décide de tourner a gauche a même temps.
Donc les chariots vont pas bouger car le chariot 1 reçoit des commandes de l'utilisateur 1 mais aussi les commandes de l'utilisateur 2 et même chose pour le chariot 2.

Donc ce que j'ai pense c'est de nommer sur le code du joystick les joystick comme par exemple (NOM: "CHARIOT1" sur le code du joystick 1 et NOM: "CHARIOT2" sur le code du joystick 1 et puis, par exemple sur le chariot 1, si la commande reçue est égale a CHARIOT1 donc "la suite du code".

Aussi j'avais un problème sur le code avec XNNN et XNNNN. Donc j'ai demande a mon copain de envoyer des valeurs qui vont de à a 999, cet a dire que la valeur maximale sera 999 et pas 1023, comme sa le codage sera plus facile.

Vous en pensez quoi?

Merci de votre aide.

Le codage plus facile c’est pas une bonne idée; le codage doit supporter la qualité de l’experience Produit, et si c’est plus compliqué à coder tant pis;

Pou’ Nommer la cible oui, inclure un numéro de destination est une solution. minimiser cependant les caractères... par exemple en envoyant un truc du genre ““