2010-12-31 4 views
1

J'ai écrit un programme C# pour recevoir des données sur le port COM2. Le débit en bauds est défini sur 115200. L'expéditeur envoie les données à 115200 bps. Mon programme perd quelques octets occasionnellement. J'appelle la méthode ReadByte pour lire les données dans une boucle while(true) à partir du port COM.C# port série données perte

J'ai quelques questions:

  • Lorsque la vitesse de transmission est haute, dois-je attendre de perdre des données? Si oui, pourquoi?
  • Je définis la taille de lecture comme 100 * 1024 * 1024. Est-ce que cela définit la taille de la mémoire tampon du pilote série à 100 * 1024 * 1024?

Toute réflexion sur la façon de déboguer ce problème?

+2

Que faites-vous en dehors de ReadByte dans la boucle while? Combien de temps prend le traitement? –

+0

Après avoir lu l'octet à partir du port série, il serait mis dans un tampon jusqu'à ce que le tampon atteint 12 octets. une fois qu'il atteint 12 octets, il serait comparé aux commandes définies qui prendraient beaucoup moins de temps. – user209293

+1

Vous devez vous assurer que vous utilisez le contrôle de flux si vous ne le faites pas déjà. –

Répondre

3

Lorsque le débit en bauds est élevé, dois-je m'attendre à perdre des données? Si oui, pourquoi?

Pas nécessairement. Cela peut arriver en raison d'une mauvaise connexion physique (trop longue).

Je suis en train de la ReadBuffer taille 100 * 1024 * 1024

Ce devrait être (moyen) plus que suffisant.

Cela dit lire un port, en boucle et lecture octets unique n'est pas la façon la plus efficace.

Vous pouvez brancher à l'événement DataReceived et régler ReceivedBytesThreshold = 12. De cette façon, vous pouvez toujours lire (Tampon, 0, 12)

4

Une taille de réception de tampon de 100 * 1024 * 1024 est énorme! Je doute sérieusement que vous ayez besoin de cette taille, et certainement pas pour le tampon du port série.

Il se pourrait que vous débordait le tampon physique reçoivent du récepteur, de sorte que vous pouvez avoir à regarder dans le contrôle de flux. Cela permettra effectivement à votre récepteur de dire à votre émetteur "Attendez, arrêtez d'envoyer un moment, laissez-moi faire face à ce que j'ai en premier."

Le contrôle de flux matériel est (généralement) utilisé via les broches RTS (Request To Send) et CTS (Clear To Send).

Jetez un oeil à l'article this, qui explique un peu plus à ce sujet.

Personnellement, je recommande de laisser la propriété ReceivedBytesThreshold du port série à sa valeur par défaut de 1, puis de gérer l'événement DataReceived. Qui sait, peut-être que demain vous aurez besoin de lire un message de 20 octets, ou peut-être 5 octets. Peut-être que vous aurez besoin de lire des messages de longueur variable dans le futur? Si vous laissez le seuil à 1, vous pourrez gérer tous les octets qui seront reçus, maintenant et dans le futur.

Ce seuil signifie l'événement se déclenche quand il y a au moins 1 octet dans le tampon. Il y a peut-être plus, et probablement le sera. Notez qu'il ne fait pas signifie nécessairement qu'il se déclenchera pour chaque octet reçu.Pour chaque événement, vous devez vérifier la propriété BytesToRead et lire ceci dans votre propre tampon.

Il vaut la peine de répéter que l'événement PAS nécessairement déclencher pour chaque octet unique reçu.

De même, il est préférable d'en faire le moins possible dans le gestionnaire d'événements DataReceived. Lisez tous les octets reçus dans votre mémoire tampon, et ajoutez peut-être des messages complétés dans une file d'attente pour un traitement ultérieur, mais ne faites rien d'autre.

Notez également que la norme spec maximum de RS232 est une vitesse de transmission de 19200 et une longueur de câble de 50 pieds. Tout ce qui précède est indéfini. Les vitesses plus élevées nécessitent généralement un meilleur câble (capacité inférieure) et des longueurs de câble plus courtes. Assurez-vous qu'il est blindé et ne fonctionne pas à proximité d'autres éléments «bruyants» tels que des moteurs, des onduleurs, des câbles sous tension, etc.

+1

+1 pour recommander le contrôle de flux –

+0

J'ai ajouté un événement de données reçues et j'ai réglé le tri de l'octet de réception sur 1. J'ai observé que les autres threads étaient affectés par cet événement reçu. Cela peut-il arriver? Il y a 4 timers.timer définis qui augmentent les événements de minuterie. Dès que le port série est reçu, les événements du temporisateur ne tirent pas à leurs intervalles définis. Il est décalé de 1 ou 2 secondes. – user209293