2010-02-09 7 views
1

Je pourrais juste avoir le bug le plus étrange que vous avez entendu aujourd'hui.bug dans la communication de port série

J'ai cette méthode (très longue) à l'intérieur d'un thread, qui envoie des données formatées à un affichage à LED RS232.

Il devrait afficher quelque chose comme ça

TITLE 
SUBTITLE 1 
ELEMENT 1 
ELEMENT 2 
SUBTITLE 2 
ELEMENT 1 
ELEMENT 2 
ELEMENT 3 
bien

, chacun sur son propre message.

J'appelle Thread.Sleep (N) après chacun des messages (donc chaque message est affiché N fois).

  • N étant le nombre de secondes

Ok, tout va bien jusqu'à présent. La chose est que si (10 <= N <= 20) je reçois la sortie suivante:

TITLE 
TITLE 
TITLE 
TITLE 
TITLE 
TITLE 
TITLE 
TITLE 

je peux entendre le bip quand j'envoie le message. J'ai même installé un moniteur de port série, pour vérifier si les informations que j'envoyais étaient les mêmes.

Donc pour résumer:

L'écriture sur le port série fonctionne après avoir dormi le fil pour n = < 9 ou n> = 20. Tout entre produira une sortie erronée, comme si la sortie a été mise en mémoire cache ou quelque chose

Qu'est-ce que cela peut être?

Mise à jour

  • Ok, je sais System.Threading.Sleep prend miliseconds comme arguments. Il suffit de multiplier le nombre par 1000.
  • Chaque fois que l'affichage LED reçoit un nouveau message bien formaté, il émet un bip. J'aurais dû clarifier cela.

Voici un extrait (cela envoie le premier titre)

  using (var ld = new LedScreen(COM)) 
      {      
       ld.AddEffect(LedScreen.Effects.Snow); 
       ld.AddText(LedScreen.Colors.Red, titulos[ThreadControl.Fase]); 
       ld.AddEffect(LedScreen.Effects.DSnow); 
       ld.Write(); 
      } 

      //Console.WriteLine(titulos[ThreadControl.Fase]); 
      //esperamos N tiempo (titulo) 
      Thread.Sleep(TiempoTitulo); 

J'ai écrit la classe LedScreen. La méthode d'écriture est celle-ci:

public void Write() 
    { 
     //caracteres de terminacion 
     buffer.AddRange(new byte[] { 0xBF, 0xB1 }); 
     try 
     { 
      if (!sp.IsOpen) sp.Open(); 
      sp.Write(buffer.ToArray(), 0, buffer.Count); 
     } 
     finally 
     { 
      sp.Close(); 
     } 
    } 

Mise à jour 2

J'ai finalement eu à travailler

Avant chaque écriture sur le port série, je vous envoie (fix laid, mais meh.) un message "vide" sans délai. Cela efface l'écran avant d'envoyer le message. Hourra! et cela fonctionne pour peu importe combien de secondes je dors le fil

+0

Pouvez-vous publier un extrait de code entourant le sommeil et l'envoi du message série? –

+0

Il existe un problème connu avec le composant de communication série depuis .NET 2.0 ... on espérait qu'il serait traité dans .NET 3.5 mais non ... – t0mm13b

+2

Il n'y a rien dans votre question qui permettrait à quiconque de diagnostiquer quel est le problème pourrait être. Découvrez ce que signifie "bip". SerialPort ne bip pas. –

Répondre

1

Tout d'abord, pouvez-vous s'il vous plaît préciser le temps de sommeil du fil? System.Threading.Thread.Sleep() prend un argument millisecondes, pas un argument 'secondes'.

Ensuite, savez-vous que le port série write() réussit?(Un retard codé en dur de 10-20 msec est pas toujours assez longtemps.)

Pour éviter dépassement, je fais quelque chose comme:

public bool Send(byte[] bytes) 
    { 
     try 
     { 
      serialPort.Write(bytes, 0, bytes.Length); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      // log or note the error: can be TimeoutException or InvalidOperationException, etc 
      return false; 
     } 
    } 
1

Il y a plusieurs choses qui pourraient avoir une incidence sur votre situation, et non le moins dont est déjà mentionné "vous parlez secondes, mais Sleep() prend un argument de millisecondes, pas secondes" problème.

Vous devez également vérifier la durée entre les caractères envoyés. Contrôle de flux aussi. Paramètres du port série (débit en bauds, etc ...). Et vous devez savoir quelle est la tolérance de votre appareil. La perte de données sur une transmission série signifie généralement que vous surchargez l'appareil à l'autre extrémité.

1

Connaissez-vous l'algorithme de détection de fin de message (EOM) de l'appareil? Il se peut que l'appareil utilise un délai d'attente intra-caractères. Cela pourrait expliquer pourquoi cela fonctionne avec N> 20, si aucun nouveau caractère n'apparaissait dans le tampon à ce moment-là, alors le périphérique pourrait décider que le message était terminé et afficher le tampon. Si vous placez le code ASCII 10 à la fin des messages, il se peut que vous décidiez que le reste du message défile à la fin de l'affichage d'une ligne et ne l'affiche pas.

Cela n'expliquerait pas le fonctionnement de N < 9, cependant. Peut-être que si les données arrivent sans aucun retard du tout l'appareil l'interprète comme un script à afficher en série? L'indication que c'est le cas est si la vitesse à laquelle les messages s'affichent ne varie pas pour N = 0 à 9, mais elle varie pour tous les N> 20. Si N est en millisecondes, vous ne pourrez peut-être pas le confirmer.