analyse de trame de 27 octets

Bonjour ArduinoTeam

Je travail sur un projet de communication numérique, et j'essaye d'envoyer 27 octets sur le port série chaque 90 ms dont le 'entête est de valeur 255, avec un débit de 4800 baud.

de l'autre coté le récepteur est une carte arduino uno, je veux savoir comment je peux stocker les 27 octetsdans un tableau une fois je reçois le premier byte qui est de valeur 255,??

quelqu'un a une idée svp ??!!!! :)

Il y a un peut un manque de motivation.

Ecrire une valeur dans un tableau n'est pas compliqué, incrémenter l'index d'un tableau non plus, comparé une valeur non plus.

Ah Non ne dis pas ça ... j'ai déjà essayé pas mal de solution mais je trouve toujours un décalage au niveau de la trame reçu, comme celui la par exemple

#include "TimerOne.h"

boolean readyToRead = false;

void setup() {
  Serial.begin(4800);// put your setup code here, to run once:
  //Serial.setTimeout(100);
}

void loop() {
 Serial.flush();

  //unsigned long duree = micros();
  int duree = micros();

  boolean bitArray[200];
  boolean datar[208];  
  int i = 0;
  byte received;
  while (Serial.available() > 0 && !readyToRead)
  {
    byte b = Serial.read();
    delayMicroseconds(100);
    if (b == 255)
    {
      readyToRead = true;

    }
  }
  if (readyToRead)
  {
    while ( (Serial.available() > 0 ) && (i < 25))
    { // esayer avec 26
     
      received = Serial.read();
      delayMicroseconds(100);
      
      //Serial.print(received, HEX);
      //Serial.print(" ");

      for (int bit = 0; bit <= 7; bit++)
      {
        if (received & (1 << bit)) {
          bitArray[bit + i * 8] = 1; // add true to array
        }
        else {
          bitArray[bit + i * 8] = 0; // add alse to array
        }
        //Serial.print(bitArray[bit + i * 8]);
      }
      i++;

      if ( received == 144)
      {
        readyToRead = false;
        Serial.flush();

      }
    }
  }

Bonjour,

Ton programme m'a l'air super compliqué La méthode suivante devrait fonctionner

void loop() {
  static byte buffer[27];
  if (Serial.available())
  {
    Serial.find(255); // attend l'octet de début
    buffer[0]=255;    // range le premier octet
    Serial.readBytes(buffer+1, sizeof buffer - 1);  // lit les 26 octets suivants
  }
}

Oh! Merci mais une question svpSerial.readBytes(buffer+1, sizeof buffer - 1); qu'est ce qu'elle renvois ??? et j'espère que

   for (int i = 0; i < sizeof(buffer); i++) {
      Serial.print(buffer[i]);
    }

print bien ce que je reçois dans le moniteur série

Oui, ça doit afficher les octets que tu as reçu, mais tu ne dois pas voir grand chose si tu ne sépares pas tes octets à l'affichage.

j'ai essayé avec ça, mais il affiche une sel fois des octets que je n'ai pas envoyé

void setup() {
  Serial.begin(4800);// put your setup code here, to run once:
  //Serial.setTimeout(100);
}

void loop() {
  
   byte buffer[26];
    
  if (Serial.available()>0)
  {
    Serial.find(255); // attend l'octet de début
    buffer[0] = 255;  // range le premier octet
    Serial.readBytes (buffer + 1, sizeof(buffer) - 1); // lit les 26 octets suivants
  }
   for (int i = 0; i < sizeof(buffer); i++) {
      Serial.print( buffer[i]); 
      Serial.print(" ");     
    }
    Serial.print("\n");
  delay(1000);
  
}

L'affichage doit être dans le if {} après la réception

void loop() {
  byte buffer[27];

  if (Serial.available() > 0)
  {
    Serial.find(255); // attend l'octet de début
    buffer[0] = 255;  // range le premier octet
    int nbOctets=Serial.readBytes (buffer + 1, sizeof(buffer) - 1); // lit les 26 octets suivants
    
    for (int i = 0; i < nbOctets+1; i++) {
      Serial.print( buffer[i]);
      Serial.print(" ");
    }
    Serial.print("\n");
  }
  delay(1000);
}

buffer doit avoir 27 octets et non 26 j'ai amélioré un peu le programme en testant le nombre d'octets reçus

Est ce que t'as jamais essayer ça ??!! parceque ça n'a pas marché pour moi :(

Il est important de comprendre que Serial.find(255) n'attend qu'une seconde par défaut - le timeout peut être réglé Dans le setup avec un appel à setTimeout()

donc il serait bien de faire

If (Serial.find(255)) {...} Plutôt que de croire aveuglément qu'on a bien reçu 255 une fois que l'appel à la fonction retourne.

De même

Serial.readBytes (buffer + 1, sizeof(buffer) - 1);

Peut retourner avant d'avoir lu les 26 octets si timeout

Le mieux c'est vraiment d'avoir un index x (initialisé à 0), et un booléen de début de trame qui indiquera si on a reçu le premier 255 (initialisé à faux)

créer un boucle générale infinie qui contient: si une donnée est dispo sur la ligne série On lit 1 caractère (byte) Si on a déjà reçu 255 (test du booléen) rajouter le caractère au buffer en position x, passer à x+1, si x vaut 26 alors on a tout reçu on fait un break; pour sortir de la boucle infinie Sinon on n'a pas encore reçu 255 alors on teste si le caractère reçu vaut 255 et si oui on met le booléen vrai pour dire que c'est bon on a reçu 255, on met x à 0 et sinon on ne fait rien et on retourne à la boucle infinie en attente du prochain charactere

L'amélioration suivante de cet algorithme c'est de rajouter la gestion d'un temps d'attente max éventuellement au début de la boucle infinie et faire un break si le temps max est atteint avec bien sûr un booléen supplémentaire qui dira qu'on n'a pas tout reçu alors que si on a bien tout reçu on le met à vrai

Voilà - reste plus qu'à coder

Vous essayez?

Bonjour,

Apparement Serial.find() n'a pas l'air de fonctionner avec des caractères >127. Je te propose le code suivant en remplacement:

void loop() {
  static byte buffer[27];
  
  if (Serial.available() > 0)
  {
    byte octet=Serial.read();
    if (octet==255)
    {
      buffer[0] = 255;  // range le premier octet
      int nbOctets = Serial.readBytes(buffer + 1, sizeof buffer - 1); // lit les 26 octets suivants

      for (int i = 0; i < nbOctets+1; i++) {
        Serial.print(buffer[i]);
        Serial.print(" ");
      }
        Serial.print("\n");
    }
  }
}

Merci J-M-L, c'est presque le même algorithme que j'ai essayé avant de poster mon problème, mais l'idée de kamill a l'aire qu'elle donne des bonnes résultats aussi sauf que dès fois je reçois une trame correcte dès fois non, pour moi je veux faire la transmission chaque 100 ms, voilà ce qu'il m'affiche

255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 trame correcte 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 trame correcte 255 137 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 trame fausse 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 144 92 12 201 144 255 137 168 176 trame fausse 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 trame correcte 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 168 176 219 14 165 12 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 165 12 232 154 153 43 32 255 137 168 176 219 14 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 255 137 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 255 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 255 137 168 176 219 14 165 12 232 154 255 137 168 176 219 14 165 12 232 154 153 43 32 31 255 137 168 176 219 14 165 12 232 154 153 43 255 137 168 176 219 14 165 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 43 32 31 80 116 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 80 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144

Est ce que c'est un problème de synchronisation parce que j’envoie la même trameà chaque fois qui commence par 255 et finit par 144

255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144

les communications séries sont asynchrones par nature. utiliser Serial.readBytes comme le propose Kamill pour lire d'un coup les 26 octets arrivant ensuite est séduisante mais dépendante du timeout implicite de la fonction Serial.readBytes qui est de 1 seconde. Si pour une raison ou pour une autre les 26 chars n'arrivent pas en une seconde, votre trame sera incomplète. si en plus vous n'avez pas vidé le buffer et que vous l'imprimez en entier (pas ce que Kamill fait cependant, je ne sais pas si c'est le code que vous utilisez) alors vous allez imprimer des données que vous n'avez pas vraiment reçu. il faut donc penser à remettre le buffer à zéro.

je pense que gérer manuellement 1 par 1 les octets quand ils arrivent va vous donner plus de contrôle sur ce qu'il se passe.

à quelle vitesse envoyez vous la trame? est-ce que les 2 ports séries sont bien calés sur la même vitesse en BAUD? au début je vois que vous utiliser 4800 comme vitesse de communication

à 4800 bauds vous envoyez environ 480 characters par seconde donc en 100ms vous pouvez envoyer 48 octets environ. ça peut sembler suffisant puisque vous n'envoyez que 27 éléments mais ensuite votre programme imprime

255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144

soit 95 caractères. c'est bufferisé et ça peut répondre vite comme ça peut attendre si le buffer d'entrée est plein - et comme vous lisez à 480 caractères par seconde mais écrivez ça 10 fois par seconde (puisque vous envoyez une trame toutes les 100ms) vous essayez de mettre dans le buffer 950 caractères par seconde... le Serial.print devient alors en fait bloquant et vous commencez à accumuler du retard pour revenir lire les 27 éléments suivants car le buffer d'entrée se remplit (et overflow possible) en attendant.

quel outil utilisez vous pour envoyer votre trame? pouvez vous passer à 115200 bauds la fois côté émetteur et récepteur juste pour voir ce que ça donne ou vérifiez les octets dans votre programme et n'imprimez que OK si c'est bien la bonne trame reçue pour ne pas surcharger le buffer

Exactement t'as raison J-M-L lorsque je passe à un débit élevé je trouve la bonne trame à chaque fois

255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144

c'est le code de kamill que j'ai utilisé

mais pour le cas de mon application je dois pas dépasser 4800 baud :/ est ce qu'il y a une solution ?

oui exactement lorsque j’augmente le debit je trouve des bonne résultat !

par contre mois j'envoie 26 octets à un debit de 4800 bit/s ce qui donne le temps de transmission est de 26x8/4800 =43,33 ms .

à l’émission

Serial.write((unsigned byte)255);

  for (int i = 0; i < 25; i++)
  {

  Serial.write((unsigned byte)pac[i]);
  
  }

sinon si je veux transmettre pendant ces 43 ms les 26 octets chaque 100 ms qu'est ce qu'il faut ajouter à ce programme ?

medeloualidi: 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 trame correcte 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 trame correcte 255 137 31 80 116 133 176 122 46 153 144 92 12 201 144 255 137 168 176 219 14 165 12 232 154 153 trame fausse 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 144 92 12 201 144 255 137 168 176 trame fausse 255 137 168 176 219 14 165 12 232 154 153 43 32 31 80 116 133 176 122 46 153 144 92 12 201 144 trame correcte

Tu envoie toujours la même chose ? Si c'est le cas, je pense que ce n'est pas un problème du programme de réception, mais plutot un problème de transmission (parasites, problème de niveau, problème de baudrate...)

C'est quoi l'émetteur?

kamill: Tu envoie toujours la même chose ? Si c'est le cas, je pense que ce n'est pas un problème du programme de réception, mais plutot un problème de transmission (parasites, problème de niveau, problème de baudrate...)

C'est quoi l'émetteur?

l’émetteur c'est un diode IR pilotée par une carte arduino et je ne dois pas dépasser 4800 baud sinon la diode va être grillée

pepe: L'envoi d'un octet est toujours accompagné d'un bit de start et d'un bit de stop, ce qui fait 10 bits au total. Donc l'envoi de 26 octets prend au moins 10x26/4800 = 54,17 ms.

Le code que tu indiques mets les 26 octets dans le tampon. L'envoi de ces octets est ensuite réalisé pratiquement sans attente. La période d'envoi des trames de 100 ms ne dépend que du reste du programme.

Mais si la perte des octets persiste alors que les trames sont envoyées toutes les 100 ms, alors c'est à la réception que le problème doit être réglé.

pourquoi 10x26 .. t'as ajouté les 2 bits de RS232 c'est ça ?