2010-08-19 17 views
0

Cette question assez simple cette fois-ci. J'ai une application qui communique avec une autre copie de l'application sur d'autres machines. Une application envoie un flux de données assez constant, l'autre le reçoit.Amélioration d'une connexion SerialPort

Le code pour envoyer des données se présente comme suit (où serialPort est une instance de la classe System.IO.Ports.SerialPorts en C# .Net 2.0):

private void bgDataWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e){ 
    try{ 
     string tempStr = Convert.ToString(String.Format("{0:0.000000}", data)); 
     serialPort.Write(tempStr); // Write "data" out to 6 decimal places 
    } 
    catch (TimeoutException){ } 
    catch (InvalidOperationException err){ // Port is obstructed or closed 
     this.Invoke((MethodInvoker)delegate{ 
      MessageBox.Show(this, "Couldn't send wireless data:\n\n" + 
          err.ToString(), "NanoMETER - Wireless Error (Data)", 
          MessageBoxButtons.OK, MessageBoxIcon.Error); 
      Global.remoteEna = false; 
      serialPort.Close(); 
      usingBT = false; 
     }); 
    } 
} 

Il est appelé une minuterie. Le code réception est encore plus simple:

private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { 
    string buffer = serialPort.ReadExisting(); 
    HandleInput(buffer); 
} 

reçoit les données envoyées et traitées et il est bien beau, mais il y a un peu saccadées indésirables où il est soit de ne pas envoyer de manière fiable des données à un débit constant, ou il est pas ramasser tout . Je ne suis pas sûr si cela peut être corrigé dans mon code, ou si c'est juste la nature d'avoir quelques machines lentes et une connexion bluetooth éventuellement shakey. Aucune suggestion?

+0

pourquoi est-il appelé sur une minuterie? Ne devrait-il pas être déclenché par un événement? – Fosco

+0

Un Bgw DoWork() est appelé à partir d'un minuteur? –

+0

@Fosco: Les données changent constamment en raison d'événements dans la minuterie. Mais je pense que je comprends que vous suggérez qu'il devrait être appelé dès que la valeur des données sera mise à jour. Incidemment, il serait encore sur une minuterie, et probablement ne fait pas beaucoup de différence, mais je comprends la logique. Note: J'adapte un ancien programme VB6 à C# (une langue que je ne connaissais pas il y a 2 mois) pour un stage ... on pourrait donc s'attendre à des WTF. – KChaloux

Répondre

1

Il n'est pas rare que des stagiaires soient affectés à la conversion de l'ancien code vers une nouvelle plate-forme.

Vous pouvez apporter quelques améliorations.

1) La stratégie suivante est bonne lorsque les octets envoyés via le port sont destinés à être interprétés dans des blocs, tels que des commandes. Avez-vous une sorte de protocole? Quelque chose qui dicte le format du message que vous envoyez. Par exemple, un délimiteur spécifique pour indiquer le début et la longueur de la commande à venir. Cela vous permet de déterminer rapidement si la commande n'a été envoyée qu'à moitié ou s'il y a des octets manquants. Mieux encore, ajouter un CRC à la fin.

2) Au lieu de lire sur une minuterie, basez-vous sur les événements marqués par votre objet serialport. Voici un exemple de ce que j'utilise:

//OnReceive event will only fire when at least 9 bytes are in the buffer. 
    serialPort.ReceivedBytesThreshold = 9; 
    //register the event handlers 
    serialPort.DataReceived += new SerialDataReceivedEventHandler(OnReceive); 
    serialPort.PinChanged += new SerialPinChangedEventHandler(OnPinChanged); 

Dans le code ci-dessus, je fixe un seuil de 9, vous devez changer cela à ce qui convient à votre contexte. En outre, l'événement Pinchanged est quelque chose de bien à surveiller, il vous permettra d'identifier rapidement si le câble a été déconnecté. Il y a plus à ce sujet, en ce qui concerne CTSChanged mais vous pouvez le rechercher si vous êtes intéressé. Enfin, si cela ne vous aide pas à aller un peu plus loin, montrez un exemple du problème qui s'est produit pour que le gars puisse vous donner plus d'aide.

+0

Merci pour l'aide. Cela méritait bien sûr la réponse, mais malheureusement, il est arrivé trop tard, j'ai donc manqué de le voir. Le stage avait pris fin au moment où vous avez posté la solution. Merci pour votre contribution, malgré tout. – KChaloux