2010-05-24 5 views
1

Je suis assez nouveau pour les communications série, mais je voudrais conseiller sur la meilleure façon de parvenir à une application robuste qui parle et écoute un périphérique série.Recherche de bonnes pratiques pour l'écriture d'une application de communication de périphérique série

J'ai réussi à faire usage de System.IO.SerialPort, et avec succès connecté à, envoyé des données et reçu de mon appareil. La façon dont les choses fonctionnent est ceci.

Mon application se connecte au port Com et ouvre le port .... Je connecte ensuite mon appareil au port COM, et il détecte une connexion au PC, donc envoie un peu de texte. c'est vraiment juste des informations de copyright, ainsi que la version du firmware. Je ne fais rien avec ça, sauf l'afficher dans ma fenêtre 'activité'.

Le périphérique attend ensuite.

Je peux alors interroger des informations, mais en envoyant une commande telle que 'QUERY PARAMETER1'. Il répond alors avec quelque chose comme:

'QUERY PARAMETER1 \ r \ n \ r \ n76767 \ r \ n \ r \ n'

Je transformons cela. Je peux ensuite le mettre à jour en envoyant 'SET PARAMETER1 12345', et il répondra avec 'QUERY PARAMETER1 \ r \ n12345 \ r \ n \ r \ n'.

Tout à fait basique. Donc, ce que j'ai fait est créé une classe de communication. cet appel est appelé dans son propre thread, et renvoie les données au formulaire principal ... et me permet également d'envoyer des messages.

L'envoi de données est facile. Recieving est un peu plus compliqué. J'ai employé l'utilisation de l'événement de datarecieved, et quand jamais les données entrent, je fais écho cela à mon écran. Mon problème est le suivant:

Lorsque j'expédie une commande, j'ai l'impression d'être très louche dans ma gestion. Ce que je fais est, disons que j'envoie 'QUERY PARAMETER1'. J'envoie la commande à l'appareil, puis je mets 'PARAMETER1' dans une variable globale, et je fais un Thread.Sleep (100).

Sur les données reçues, j'ai alors un peu de logique qui vérifie les données entrantes, et voit si la chaîne CONTIENT la valeur dans la variable globale. Comme la réponse peut être 'QUERY PARAMETER1 \ r \ n76767 \ r \ n \ r \ n', elle voit qu'elle contient mon paramètre, analyse la chaîne et retourne la valeur que je cherche, mais en la plaçant dans une autre variable globale.

Ma méthode d'envoi dormait pendant 100ms. Il se réveille ensuite et vérifie la variable globale retournée. S'il a des données ... alors je suis content et je traite les données. Le problème est ... si le sommeil est trop court .. il échouera. Et je pense que c'est floconneux .. mettre des choses dans les variables .. puis attendre ...

L'autre option est d'utiliser ReadLine à la place, mais c'est très bloquant. Donc, je supprime la méthode de données reçues, et au lieu ... il suffit d'envoyer les données ... puis appelez ReadLine(). Cela peut me donner de meilleurs résultats. Il n'y a pas de temps, sauf lorsque nous nous connectons initialement, que les données proviennent de l'appareil, sans que je le demande. Donc, peut-être ReadLine sera plus simple et plus sûr? Est-ce connu comme «Blocage» lit? Aussi, puis-je définir un délai d'expiration?

J'espère que quelqu'un peut me guider.

Répondre

1

Eh bien, Thread.Sleep() bloque aussi. Bien pire, en fait, parce que vous devez spécifier un temps de sommeil toujours sûr, même si la machine est sous forte charge. En utilisant ReadLine() est toujours mieux, il sera plus rapide et il ne peut pas échouer. Notez que votre exemple ne nécessite pas que le code client attende une réponse. Il peut simplement supposer que la commande était efficace. Tout ce dont vous avez besoin est un événement d'erreur pour signaler que quelque chose s'est mal passé.

S'il existe une commande qui nécessite le code client pour obtenir la réponse que vous devriez offrir l'option d'attendre ainsi que le résultat asynchrone. Cela donne les options de code client: l'attente est lente mais facile, async est difficile à programmer. C'est un modèle très courant dans le framework .NET, le nom de la méthode asynchrone commence par "Begin". Vérifiez le MSDN Library article à ce sujet.

Vous devez également envisager de fournir des notifications asynchrones sur le thread que le code client préfère. La propriété SynchronizingObject est a good pattern pour cela.

0

Si vous faites toutes vos lectures sur un fil de fond, alors je ne vois aucun problème à utiliser ReadLine. C'est la solution la plus simple et la plus robuste.

Vous pouvez utiliser la propriété ReadTimeout pour définir le délai d'attente des opérations de lecture.