Go Down

Topic: Communication RS232 (programmation) (Read 10010 times) previous topic - next topic

rhum187

Je viens de rentrer dans la 4ème dimensions... ^^

Non, pas encore, malheureusement, il y a un problème que je n'arrive pas à résoudre.

Je fais communiquer deux Arduino. Avec le premier j'envoie ça :

Code: [Select]

  Serial.print('M'); // Permet l'identification des commandes moteurs par le programme robot
  Serial.write(ZONE); // Permet le débogage des conditions à l'aide du VI
  Serial.write((int)PWM1);
  Serial.write((int)PWM2);
  Serial.write((int)PWM3);
  Serial.write((int)PWM4);


et avec le deuxième je veux lire la valeur des PWM donc j'ai écrit (avec l'aide de Skywodd ;)) :
Code: [Select]

byte PWM_MOT[4]; // Tableau de 6 octets
int n_octet = 4;
int pin_PWM_A = 10;
int pin_PWM_B = 9;
int pin_PWM_C = 6;
int pin_PWM_D = 5;

void setup()
{
  Serial.begin(9600); // Paramétrage de la vitesse de la liaison série
}

/*********************** DEBUT DE LA BOUCLE PRINCIPALE ********************************************/
void loop()
{
  if(Serial.available()>0)
  {
    if(Serial.read()!='M')
    {
     delay(50);
    }
    else
    {
      for(int n=1; n<=n_octet; n++)
      {
        while(Serial.available() < 1);
        PWM_MOT[n]=Serial.read();
      }
    }
    //analogWrite(pin_PWM_A, PWM_MOT[1]);
    //analogWrite(pin_PWM_B, PWM_MOT[2]);
    //analogWrite(pin_PWM_C, PWM_MOT[3]);
    //analogWrite(pin_PWM_D, PWM_MOT[4]);
   
    //Serial.print(PWM_MOT[0]);
    Serial.print(PWM_MOT[1]);
    Serial.print(PWM_MOT[2]);
    Serial.print(PWM_MOT[3]);
    Serial.print(PWM_MOT[4]);
    //Serial.print(PWM_MOT[5]);
   
    Serial.println();
   
  }
  else
  {
    analogWrite(pin_PWM_A, 0);
    analogWrite(pin_PWM_B, 0);
    analogWrite(pin_PWM_C, 0);
    analogWrite(pin_PWM_D, 0);
  }
 
  Serial.flush();
  delay(50);
}


Et je vous joins les deux screen XCTU qui m'ont permis de constater que il y avait +1 sur la PWM4 alors que je n'ai rien fait pour... enfin je pense
COM11 : Arduino qui envoit les infos
COM13 : Arduino qui reçoit et qui les (ré)affichent

skywodd


Ben je me posais la question justement...

Je pense que le composant auquel je les envoie s'en moque un peu...

Ça n'as aucune réelle importance, dans le pire des cas cela ne joue que sur le sifflement / grésillement résiduelle du moteur en sortie (si tu utilise un moteur).
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

rhum187

Oui je pense aussi.

Par contre ma différence de 1, même si ce n'est que 1 me perturbe un peu plus...

skywodd


Par contre ma différence de 1, même si ce n'est que 1 me perturbe un peu plus...

Rooo! Je sort le fusil et les cartouches si tu ne vois pas tes erreurs ;)

Erreur 1 :
Prototype :
Code: [Select]
Serial.write(uint8_t);

Ton code :
Code: [Select]
Serial.write((int)PWM4);

Note : uint8_t = 1 octet non signé (0 ~ 255), int = 2 octets signé (-32767 ~ 32767)

--

Erreur 2 :
Déclaration :
Code: [Select]
byte PWM_MOT[4]; // Tableau de 6 octets
(hummm 6 tu est sûr ;))

Ton code ensuite :
Code: [Select]
//Serial.print(PWM_MOT[0]);
    Serial.print(PWM_MOT[1]); // <-
    Serial.print(PWM_MOT[2]);
    Serial.print(PWM_MOT[3]);
    Serial.print(PWM_MOT[4]); // <-
    //Serial.print(PWM_MOT[5]);


Note : en C/C++ les tableaux commencent à 0 et se terminent à taille_max - 1, exemple int[2] -> int[0], int[1]

--

Erreur 3 :
Déclaration :
Code: [Select]
byte PWM_MOT[4];
int n_octet = 4;


Ton code :
Code: [Select]
for(int n=1; n<=n_octet; n++) // -> n = 1, n = 2, n = 3, n = 4
{
  while(Serial.available() < 1);
  PWM_MOT[n]=Serial.read(); // <-
}


Voir note plus haut.
--

Erreur 4 :

Tu envois 6 octets mais tu en lit seulement 4 (+ 1 pour le if) ;)

--

Correction :

Envoi :
Code: [Select]
Serial.write((uint8_t)'M'); // Permet l'identification des commandes moteurs par le programme robot
Serial.write((uint8_t)ZONE); // Permet le débogage des conditions à l'aide du VI
Serial.write((uint8_t)PWM1);
Serial.write((uint8_t)PWM2);
Serial.write((uint8_t)PWM3);
Serial.write((uint8_t)PWM4);


Réception :
Code: [Select]
const byte NB_OCTETS = 5;
const byte PIN_PWM_A = 10;
const byte PIN_PWM_B = 9;
const byte PIN_PWM_C = 6;
const byte PIN_PWM_D = 5;

byte PWM_MOT[NB_OCTETS];

void setup() {
  Serial.begin(9600); // Paramétrage de la vitesse de la liaison série
}

/*********************** DEBUT DE LA BOUCLE PRINCIPALE ********************************************/
void loop() {
 
  if(Serial.available() > 0) {
   
    if(Serial.read() != 'M') {
      delay(50);
    }
    else {

      for(int n = 0; n < NB_OCTETS; ++n) {
        while(Serial.available() < 1);
        PWM_MOT[n] = Serial.read();
      }

      //analogWrite(PIN_PWM_A, PWM_MOT[1]);
      //analogWrite(PIN_PWM_B, PWM_MOT[2]);
      //analogWrite(PIN_PWM_C, PWM_MOT[3]);
      //analogWrite(PIN_PWM_D, PWM_MOT[4]);

      Serial.print(PWM_MOT[0]);
      Serial.print(PWM_MOT[1]);
      Serial.print(PWM_MOT[2]);
      Serial.print(PWM_MOT[3]);
      Serial.print(PWM_MOT[4]);
      Serial.println();
    }
  }
  else {
   
    analogWrite(PIN_PWM_A, 0);
    analogWrite(PIN_PWM_B, 0);
    analogWrite(PIN_PWM_C, 0);
    analogWrite(PIN_PWM_D, 0);
  }

  // Serial.flush(); // Pas de flush() quand on ne sait pas ce que ça signifie ;)
  delay(50);
}
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

rhum187

Quote
Pas de flush() quand on ne sait pas ce que ça signifie ;)


Heu, pour moi je vidais le buffer de lecture à chaque fois que j'ai terminé mais je me suis rendu compte que je mettre ou pas n'avais aucun effet...

Ca a du te faire pas mal de boulot alors merci pour ton temps je regarde ça et je te fais un retour avant 19h (si mon chef me sort pas une réunion surprise du chapeau...)

skywodd


Heu, pour moi je vidais le buffer de lecture à chaque fois que j'ai terminé mais je me suis rendu compte que je mettre ou pas n'avais aucun effet...

Justement tu as tout faux ;)
Depuis arduino 1.0 Serial.flush() bloque le programme jusqu'à ce que toute les données en Tx soit émise.

Pour vider le buffer entrant il faut faire une boucle de ce genre :
Code: [Select]
while(Serial.available() > 0) Serial.read();


Ca a du te faire pas mal de boulot alors merci pour ton temps je regarde ça et je te fais un retour avant 19h (si mon chef me sort pas une réunion surprise du chapeau...)

Bof juste 5 minutes entre deux bricolages 8)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

rhum187

Quote
Depuis arduino 1.0


Je bosse encore sur la 0023

skywodd


Quote
Depuis arduino 1.0


Je bosse encore sur la 0023

Ce qui ne change rien au fait que flush() n'as rien à faire dans ton prog ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

rhum187

Ok,

bon ben écoute sans surprise ça fonctionne beaucoup mieux avec les uint8_t

Quote
(hummm 6 tu est sûr )


Non bien sur mais je n'avais pas maj mon commentaire... ça reste une erreur me dirais mes profs...  XD

Quote
(+ 1 pour le if)


tu voulais dire le :

Code: [Select]
while(Serial.available() < 1);

que tu m'as fait rajouté... ;)

Code: [Select]
while(Serial.available() > 0) Serial.read();
Ha ok, le fait de faire un read vide le buffer si je comprends bien !




rhum187

Code: [Select]
const byte NB_OCTETS = 5;
const byte PIN_PWM_A = 10;
const byte PIN_PWM_B = 9;
const byte PIN_PWM_C = 6;
const byte PIN_PWM_D = 5;


Et une petite question au passage : pourquoi avoir choisi de déclarer ça en const byte ?

Ma supposition : const veut dire que ça ne bouge pas (c'est bien le propre d'une constante)
byte car un octet suffit pour coder ces valeurs

J'ai bon ? j'ai bon ? :)

skywodd


Ma supposition : const veut dire que ça ne bouge pas (c'est bien le propre d'une constante)
byte car un octet suffit pour coder ces valeurs

J'ai bon ? j'ai bon ? :)

C'est ça.

Const = constante = qui ne change pas (si on tente de changer la valeur d'un const = erreur de compilation)
byte = 1 octet = économie de ram vu que l'on stocke juste un nombre avec pour valeur max 255.
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

rhum187

Parfait ben plus qu'à faire les deux modifs pour juste afficher les 4 PWM et ça devrait être bon avec qqch du style :

Code: [Select]
const byte NB_OCTETS = 4;
.
.
.
byte PWM_MOT[NB_OCTETS-1];
.
.
.
for(int n = 2; n < NB_OCTETS+2; ++n)
      {
        while(Serial.available() < 1);
        PWM_MOT[n] = Serial.read();
      }


skywodd

Alors voyons, chevrotine pour gros gibier ou cartouches, hummm ... :smiley-mr-green:

Code: [Select]
for(int n = 2; n < NB_OCTETS+2; ++n) // n = 2, n = 3, n = 4, n = 5
{
  while(Serial.available() < 1);
  PWM_MOT[n] = Serial.read();
}

Les tableaux en C/C++ commencent à zéro !
(Souligné, gras, surligné, je peut pas faire plus lisible ;))

Correction :
Code: [Select]
Serial.read();  // Laisse de côté l'octet "ZONE" (est-ce bien utile de l'envoyer du coup ? Pour moi non ;))
for(byte n = 0; n < NB_OCTETS - 1; ++n)  {
  while(Serial.available() < 1);
  PWM_MOT[n] = Serial.read();
}
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

rhum187

Quote
Alors voyons, chevrotine pour gros gibier ou cartouches, hummm


hahaha, c'était une blague... !

J'espère que tu ne penses pas que je serais capable de faire ça... :smiley-eek-blue:

skywodd


hahaha, c'était une blague... !

J'espère que tu ne penses pas que je serais capable de faire ça... :smiley-eek-blue:

cf :
Quote
Rooo! Je sort le fusil et les cartouches si tu ne vois pas tes erreurs

Humour ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Go Up