Question

J'ai écrit une application simple en C # 2.0 à l'aide de la classe Serialport .Net Framework 2.0 pour communiquer avec une carte contrôleur via COM1.

Un problème est survenu récemment où les octets renvoyés par la méthode Read sont incorrects. Il a renvoyé la bonne quantité d'octets, seules les valeurs étaient incorrectes. Une application similaire écrite dans Delphi a néanmoins renvoyé les valeurs correctes.

J'ai utilisé Portmon pour consigner l'activité sur le port série. des deux applications, comparé les deux journaux et là où quelques (apparemment) mineurs paramètres différents et j'ai essayé d'imiter l'application Delphi aussi étroitement que possible, mais en vain.

Alors, qu'est-ce qui pourrait affecter les valeurs d'octet renvoyées par la méthode Read?

La plupart des paramètres entre les deux applications sont identiques.

Voici une liste des lignes qui diffèrent dans le journal Portmon:

Application Delphi:

  

IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF: dc   ERR: 0 BRK: 0 EVT: 0 XON: 11 XOFF: 13
  IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake: 0   Remplacez: 0 XonLimit: 256    XoffLimit: 256 IOCTL_SERIAL_SET_TIMEOUTS Série 0 SUCCESS RI: -1    RM: 100 RC: 1000 WM: 100 WC: 1000 IOCTL_SERIAL_SET_WAIT_MASK Serial0 Masque SUCCESS:   RXCHAR RXFLAG TXEMPTY CTS DSR RLSD   BRK ERR RING RX80FULL

Application C #:

  

IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF: 1a   ERR: 0 BRK: 0 EVT: 1a XON: 11 XOFF: 13   IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake: 0   Remplacez: 0 XonLimit: 1024    XoffLimit: 1024 IOCTL_SERIAL_SET_TIMEOUTS Série 0 SUCCESS RI: -1    RM: -1 RC: 1000 WM: 0 WC: 1000 IOCTL_SERIAL_SET_WAIT_MASK Serial0 Masque SUCCESS:   RXCHAR RXFLAG CTS DSR RLSD BRK ERR   BAGUE

MISE À JOUR:

Les octets renvoyés étaient les suivants: 91, 1, 1, 3, 48, 48, 50, 69, 66, 51, 70, 55, 52, 93 (14 octets). La dernière valeur étant une simple somme de contrôle.

Les valeurs incorrectes renvoyées sont les suivantes: 91, 241, 254, 252, 242, 146, 42, 201, 51, 70, 55, 52, 93 (13 octets).

Comme vous pouvez le voir, les cinq premiers octets renvoyés correspondent.

L'événement ErrorReceived indique qu'une erreur de cadrage s'est produite, ce qui peut expliquer les valeurs incorrectes. Mais la question est de savoir pourquoi SerialPort rencontrerait une erreur de cadrage alors que l’application Delphi ne le fait apparemment pas.

Était-ce utile?

La solution

Eh bien, il semble que le problème ait été résolu (du moins pour le moment).

Apparemment, une erreur de cadrage a entraîné le retour de valeurs incorrectes. J'ai écrit une application VB6 à l'aide du contrôle MSComm, qui a bien fonctionné, et comparé les fichiers journaux générés par Portmon.

J'ai relevé les différences suivantes

Application VB6:

  

IOCTL_SERIAL_SET_HANDFLOW Serial0   SUCCESS Agiter: 1 Remplacer: 0   XonLimit: 256 XoffLimit: 256

Application C #:

  

IOCTL_SERIAL_SET_HANDFLOW Serial0   SUCCESS Agiter: 0 Remplacer: 0   XonLimit: 1024 XoffLimit: 1024

Jouer avec les paramètres que j'ai trouvés si je les ai mis _serialPort.DtrEnable = true l'application C # génère l'entrée de journal suivante:

  

IOCTL_SERIAL_SET_HANDFLOW Serial0   SUCCESS Agiter: 1 Remplacer: 0   XonLimit: 1024 XoffLimit: 1024

Cela semblait empêcher l'erreur de cadrage et l'application semblait fonctionner correctement.

Autres conseils

Avez-vous vérifié les paramètres pour le nombre de bits de données, les bits d'arrêt et la parité?

Le bit de parité est une sorte de mécanisme de détection d'erreur. Par exemple: si vous envoyez en utilisant 7 bits de données et un bit de parité, le huitième bit sera utilisé pour détecter les erreurs d'inversion de bits. Si le destinataire attend 8 bits de données et aucun bit de parité, le résultat sera tronqué.

Malheureusement, vous n’avez pas mentionné le type de différence que vous obtenez. Est-ce un caractère occasionnel différent ou toutes vos données entrantes sont-elles corrompues? Notez que les caractères lus via la fonction SerialPort.Read peuvent être modifiés par le système en raison du paramètre SerialPort.Encoding . Ce paramètre affecte l'interprétation du texte entrant comme il s'agissait d'un texte ASCII, Unicode, UTF8 ou de tout autre schéma de codage utilisé par Windows pour la conversion "d'octet brut" en "texte lisible".

Si vous lisez dans un tableau d'octets (ex: SerialPort.Read), vous devez obtenir exactement les octets que vous voyez sur PortMon.

Si vous convertissez des caractères (SerialPort.ReadLine ou SerialPort.ReadChar), les données seront alors codées à l'aide du codage actuel (propriété SerialPort.Encoding), ce qui explique les différences constatées.

Si vous voulez voir des caractères avec les mêmes valeurs binaires que les octets sur le câble, utilisez le codage Latin-1 qui convient, comme décrit dans la section cet article .

Exemple:

SerialPort.Encoding = Encoding.GetEncoding("Latin1")
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top