From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Discussions au sujet de NI LabVIEW

annuler
Affichage des résultats de 
Rechercher plutôt 
Vouliez-vous dire : 

Problème pour isoler des messages depuis un rs232

Résolu !
Accéder à la solution

Bonjour à tous,

 

Je cherche actuellement à lire un ensemble de messages que je reçois en RS232. Il existe plusieurs types de messages différents (et qui comportent des données différentes) et c'est pourquoi je cherche dans un premier temps à isoler les 8 premiers octets de chaque message afin d'en déduire le contenu (avec le protocole du RS232, je sais par exemple que le 5ème octet de chaque message me renvoie le type du message considéré).

 

Le problème se situe en amont : je n'arrive pas à isoler proprement mes différents messages, certains sont perdus et d'autres n'apparaissent jamais en sortie de mon "visa read".

 

J'ai fait plusieurs essais en jouant sur les différents paramètres : rien n'y fait. Certains messages n'apparaissent simplement jamais, alors que je sais pertinemment qu'ils se trouvent son sur mon RS232.

 

Avez-vous des idées pour que je puisse isoler, en sortie de mon "visa read", mes messages les uns après les autres sans trop en perdre ? Je vous mets mon diagramme en pj.

 

Pour plus de précisions :

  • mon baudrate est de 115200 // bits de données : 8 // 1 bit start et 1 bit stop
  • j'ai environ 10types de messages différents, reçu à des fréquences différentes (entre 1 et 30 par seconde suivant les types de messages).
  • quelque soit le type de message :
    • les 8 premiers octets du message sont des octets d'initialisation
    • ils sont suivis de n octets de data (fonction du type de message)
    • et enfin 4 octets sur lesquels je retrouve un CRC32.

 

Je vous remercie d'avance pour votre aide !

Tout télécharger
0 Compliments
Message 1 sur 8
2 411 Visites

Prière d'indiquer le lien vers le protocole de l'appareil émettant les messages.

 

Selon votre code, ces messages ne comportent pas de caractère de terminaison. En est-il bien ainsi ? Est-il possible d'activer cette fonctionnalité ?

 

Avec un caractère de terminaison, ce découpement des messages serait très simple à mettre en oeuvre. Sinon, il faudra procéder d'une autre manière. Ce qui est certain est que votre méthode actuelle ne peut pas fonctionner.

0 Compliments
Message 2 sur 8
2 376 Visites

Effectivement, je n'ai pas de caractère de terminaison, et je n'ai pas la main dessus (j'ai mis le protocole du périphérique en pj)

En revanche toutes mes trames commencent par les octets 0x05 0x02, est-ce que je pourrai éventuellement m'en servir comme une sorte de caractère de terminaison ?

 

Est-ce qu'au final vous pensez qu'il est tout de même possible d'isoler les messages dans le buffer de lecture ?

 

Merci !

0 Compliments
Message 3 sur 8
2 366 Visites
Solution
Accepté par l'auteur du sujet squale16

Oui bien sûr mais il faut procéder autrement en n'effectuant pas le découpage lors de la lecture mais après.

J'utiliserais une structure du type Producer/Consumer avec :

  • une boucle de lecture du port série (= producer)
  • et une boucle de traitement des données (= consumer)

 

Dans le Producer :

  • avant d'entrer dans la boucle de lecture, configurer et démarrer le port puis vider le contenu du buffer pour effacer d'éventuels messages qui s'y trouvent
  • lire périodiquement les données présentes sur le port selon le nombre retourné par la propriété VISA "Number of Bytes at Serial Port"
  • on lira donc inévitablement des messages incomplets et peut-être même plusieurs à la fois
  • transmettre ces données au Consumer
  • après avoir quitté la boucle de lecture, fermer le port

Dans le Consumer :

  • ajouter les données reçues au tableau de celles à traiter
  • extraire les messages en procédant un par un :
    • rechercher 0x05 0x02 = début du message
    • le début étant trouvé, vérifier si l'octet définissant le type est déjà présent
    • si oui en extraire le type et le nombre d'octets du message
    • le nombre d'octets étant connus, vérifier si le message est complet
    • si oui, l'extaire et le supprimer du tableau des octets restants (vérifier le CRC pour ne tenir compte du message que s'il est correct ne serait pas une mauvaise idée)
    • poursuivre avec tous les messages complets
  • pour la toute première itération du Consumer, virer les éventuels octets avant le premier 0x05 0x02. Comme le démarrage de l'application n'est pas synchronisé avec l'émetteur, il pourrait être réalisé au milieu de l'envoi d'un message qui serait alors partiel et à ignorer. 

Assez clair ?

0 Compliments
Message 4 sur 8
2 353 Visites

Je vous remercie pour votre réponse !

 

Ça me parait clair, j'essaie ça et je vous tiens au courant 🙂

0 Compliments
Message 5 sur 8
2 339 Visites

Si les messages comportaient un caractère de terminaison (valeur strictement réservée qui n'apparaît jamais dans les données utiles), la tâche serait plus simple.

Il suffirait alors de configurer et d'activer cette fonctionnalité dans VISA et puis, pour la lecture, de définir un nombre d'octets supérieur à celui du plus long message envoyé par l'appareil. La fonction de lecture VISA s'arrêterait dès que le caractère de terminaison apparaît, en retournant par conséquent un message et en laissant les éventuels caractères restants dans le buffer du port série.

0 Compliments
Message 6 sur 8
2 333 Visites

Je vous ai écouté à la lettre (en faisant deux boucles, producer/consumer) et tout fonctionne parfaitement. Merci !

0 Compliments
Message 7 sur 8
2 312 Visites

BRAVO d'y être arrivé !

A mon humble avis, cette architecture est vraiment la bonne car elle sépare la lecture du traitement.

0 Compliments
Message 8 sur 8
2 301 Visites