Communication RS232 (programmation)

rhum187:
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).

Oui je pense aussi.

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

rhum187:
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 :wink:

Erreur 1 :
Prototype :

Serial.write(uint8_t);

Ton code :

Serial.write((int)PWM4);

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

--

Erreur 2 :
Déclaration :

byte PWM_MOT[4]; // Tableau de 6 octets

(hummm 6 tu est sûr ;))

Ton code ensuite :

//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 :

byte PWM_MOT[4];
int n_octet = 4;

Ton code :

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) :wink:

--

Correction :

Envoi :

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 :

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);
}

Pas de flush() quand on ne sait pas ce que ça signifie :wink:

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...)

rhum187:
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 :wink:
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 :

while(Serial.available() > 0) Serial.read();

rhum187:
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)

Depuis arduino 1.0

Je bosse encore sur la 0023

rhum187:

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 :wink:

Ok,

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

(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

(+ 1 pour le if)

tu voulais dire le :

while(Serial.available() < 1);

que tu m'as fait rajouté... :wink:

while(Serial.available() > 0) Serial.read();

Ha ok, le fait de faire un read vide le buffer si je comprends bien !

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 ? :slight_smile:

rhum187:
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 ? :slight_smile:

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.

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

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();
      }

Alors voyons, chevrotine pour gros gibier ou cartouches, hummm ... :grin:

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 :

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();
}

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... :fearful:

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

J'espère que tu ne penses pas que je serais capable de faire ça... :fearful:

cf :

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

Humour :wink:

Pour vraiment être sûr d'avoir bien compris et un peu pour passer pour un idiot aussi...

Dans le code corrigé que tu m'as donné tu aurais très bien pu écrire

byte PWM_MOT[NB_OCTETS-1]

dans le sens ou tu ne remplis que 5 octets du tableau alors que tu définis un tableau de 6 octets (PWM_MOT[5]) ?

Yep!

Oulala ! Tu as un problème avec les tableaux dites donc :grin:

Lorsque tu définis un tableau, il faut bien distinguer la valeur entre crochet et la manière dont le µC va le gérer.

byte monTableau[6] = {1, 2, 3, 4, 5, 6};

La valeur entre crochet est telle que nous la comptons nous autre humain, il contient bien ici 6 élements (ou 6 cases mémoires).

Je ne rentrerais pas dans le détail du pourquoi, c'est comme çà un point c'est tout :wink:

Par contre, le microcontrolleur comme tout bon microcontroleur, commence à compter à partir de 0,

Reprenons :

byte monTableau[6] = {1, 2, 3, 4, 5, 6}; // comptage pseudo-humain
......................................0, 1, 2, 3, 4, 5 // comptage du microcontrolleur

Ainsi, lorsque tu créés une boucle ou un appel à ce tableau, tu utilises le langage du µC et commences à compter à partir de zero :

monTableau[0] = 1
monTableau[1] = 2
monTableau[2] = 3
monTableau[3] = 4
monTableau[4] = 5
monTableau[5] = 6

A savoir que lorsque tu fabriques un tableau, tu fais appel à la gestion de la mémoire du microcontrolleur et à un moment donné, il faut bien dire à la mémoire que le tableau est fini.
Si tu essayais d'appeler monTableau[12], le compilateur te retournerait une erreur car tu as créé un tableau de 6 cases et pas 13 :wink:

En esperant avoir clarifié un peu la situation XD

@+

Zoroastre.

Parfaitement clair maintenant !

Merci à tous les deux !

Je reviens vous embêter :wink:

Voilà ce que j'ai fait :

const byte PIN_PWM_A = 10;
const byte PIN_PWM_B = 9;
const byte PIN_PWM_C = 6;
const byte PIN_PWM_D = 5;

const byte PIN_COM = 4; // Déclaration de la pin COM de l'arduino
const byte PIN_LED = 2; // Déclaration de la pin LED de l'arduino

const byte NB_OCTETS = 4;
byte PWM_MOT[NB_OCTETS]; // Tableau de NB_OCTETS octets

void setup() 
{
  Serial.begin(9600); // Paramétrage de la vitesse de la liaison série
  while(Serial.available() > 0) Serial.read(); // On vide le buffer de lecture
  pinMode(PIN_COM, OUTPUT); // Paramétrage de la pin COM en sortie
  pinMode(PIN_LED, OUTPUT); // Paramétrage de la pin LED en sortie
}

/*********************** DEBUT DE LA BOUCLE PRINCIPALE ********************************************/
void loop() 
{ 
  digitalWrite(PIN_COM, LOW); // Paramétrage communication filaire
  digitalWrite(PIN_LED, HIGH); // Paramétrage des LEDs à l'état haut
  
  if(Serial.available() > 0) 
  {
    int premier_octet = Serial.read();
    switch (premier_octet)
    {
      case 'M':
        Serial.read(); // On vide le 2ème octet du buffer de lecture correspondant à la zone Nunchunk
        for(int n = 0; n < NB_OCTETS; ++n) // On rempli le tableau d'octets
        {
          while(Serial.available() < 1); // Attente des données entre chaque tour de boucle (programme plus rapide que la com)
          PWM_MOT[n] = Serial.read(); // Stockage des valeurs de PWM dans le tableau
        }

        analogWrite(PIN_PWM_A, PWM_MOT[0]);
        analogWrite(PIN_PWM_B, PWM_MOT[1]);
        analogWrite(PIN_PWM_C, PWM_MOT[2]);
        analogWrite(PIN_PWM_D, PWM_MOT[3]);
      
        Serial.print(PWM_MOT[0]);
        Serial.print(PWM_MOT[1]);
        Serial.print(PWM_MOT[2]);
        Serial.print(PWM_MOT[3]);
        Serial.println();
        break;
        
      default:
        delay(1);
    } 
  }
  else
  {
    analogWrite(PIN_PWM_A, 0);
    analogWrite(PIN_PWM_B, 0);
    analogWrite(PIN_PWM_C, 0);
    analogWrite(PIN_PWM_D, 0);
  }
  delay(50);
}

Mon code fonctionne plutôt bien. Par contre, je me suis amusé à enlever le delay(50) à la fin et là ça ne fonctionne plus comme attendu : j'affiche la zone et les 3 premières PWM... Pourtant en faisant "dérouler le programme dans ma tête" ça ne devrait rien changer...

Je pense avoir compris mon problème de delay :

Je pense que ça vient du programme boitier qui dans ça boucle principale a aussi un delay de 50ms

Je pense qu'il faut que les delay soient identiques dans les deux programmes pour que tout roule correctement.