Probleme SerialPort et Conversion

Résolu
getthematrix Messages postés 3 Date d'inscription vendredi 28 mai 2004 Statut Membre Dernière intervention 4 juin 2010 - 2 juin 2010 à 11:02
getthematrix Messages postés 3 Date d'inscription vendredi 28 mai 2004 Statut Membre Dernière intervention 4 juin 2010 - 4 juin 2010 à 16:53
Bonjour à tous,

Pour info, je débute en C#.

Voici mon problème :

Via le port COM je reçois des trames du type : 0x30 0x5C 0x30 0x0F 0x5D 0x99 0x34 0x33 dont je dois calculer le Checksum.
Sous XP pour recevoir correctement ce genre d'octets, j'ai ajouté le code serialPort.Encoding = Encoding.GetEncoding("Latin1");
En effet, car en utilisant la fonction str = serialPort.readline(); la chaine de caractère n'est pas bien décodée car codage sur 7 bits à priori (tout ce qui dépasse 128 n'est pas décodé).

Ensuite pour calculer le checksum je fais comme ceci :

for (int i = 0; i < message.Length - 2; i++)
{ checksum = checksum + System.Convert.ToByte(System.Convert.ToChar(message.Substring(i, 1))); }

Ceci fonctionne correctement.

Par contre, l'application doit aussi fonctionner sous WinCE qui me met une erreur à la ligne serialPort.Encoding Encoding.GetEncoding("Latin1"); car il ne reconnait pas l'encoding. Alors j'ai essayé l'encoding suivant _serialPort.Encoding System.Text.Encoding.Default; mais cela me donne une erreur de conversion sous les deux OS lors du calcul de checksum.

Erreur suivant : An unhandled exception of type 'System.OverflowException' occurred in mscorlib.dll

Additional information: La valeur était trop grande ou trop petite pour un octet non signé.

Cela se produit pour la valeur 0x99 qui est bien décodé grace au System.Text.Encoding.Default mais que je n'arrive pas à convertir. Le problème semble provenir de la convertion en char je pense mais je ne sais pas quelle méthode utiliser ?

Merci d'avance

3 réponses

jul1409 Messages postés 7 Date d'inscription mardi 5 juin 2007 Statut Membre Dernière intervention 3 juin 2010
3 juin 2010 à 16:48
Bonjour,

plusieurs choses ne vont pas dès le départ ...

1 - serialPort.Encoding = Encoding.GetEncoding("Latin1");
Cela ne sert à rien un octet est un octet ... c'est son interprétation par l'os qui va varier d'un pays à l'autre (ex. chine <-> france) mais je ne vais pas m'étaler sur l'encodage de caractères.

2 - la chaine de caractère n'est pas bien décodée car codage sur 7 bits à priori (tout ce qui dépasse 128 n'est pas décodé).
vous écrivez aussi : 0x30 0x5C 0x30 0x0F 0x5D 0x99 0x34 0x33
Si c'est codé sur 7 bits le 0x99 ne peut pas passé parce que 7 bits = 00 à 7F
Donc la trame série doit être codé sur 8 bit! Qu'avez-vous mis comme paramètre serialPort.DataBits ?

De plus, je vous conseille de ne pas utiliser serialPort.ReadLine( ) qui
lit jusqu'à la valeur System.IO.Ports.SerialPort.NewLine dans la mémoire tampon d'entrée.
Je vous conseille d'utiliser ReadByte( ) ou ReadChar( ) et de faire votre calcul de CheckSum à la volée.

Bon courage
3
getthematrix Messages postés 3 Date d'inscription vendredi 28 mai 2004 Statut Membre Dernière intervention 4 juin 2010
3 juin 2010 à 18:51
Bonjour,

merci pour votre réponse.

En fait, je me suis peut être mal expliqué.

- Pour le décodage sur 7 bits : la fonction readline() me renvoie une chaine de caractères dont les caractères supérieur à 0x7F ne sont pas décodés dans le string de sortie de la fonction (alors que serialPort.DataBits=8).

- Pour ce qui est de : serialPort.Encoding = Encoding.GetEncoding("Latin1"); En ajoutant cette ligne, la fonction readline me renvoie bien les caractères supérieurs à 0x7F. Mais cette commande ne fonctionne à priori pas sous winCE.

J'utilise la fonction readline() car les trames que je reçois se finissent toutes par le caractère de fin de ligne "<LF>".

En fait le problème c'est que j'aimerais utiliser Readline() et que cette fonction me décode les octets > 0x7F et ne pas me servir de serialPort.Encoding = Encoding.GetEncoding("Latin1") car celui-ci ne fonctionne pas sous WinCE (par contre il fonctionne très bien sous windows)

merci
3
getthematrix Messages postés 3 Date d'inscription vendredi 28 mai 2004 Statut Membre Dernière intervention 4 juin 2010
4 juin 2010 à 16:53
Bonjour,

j'apporte des éléments d'explication à mon problème pour ce qui tomberait sur le même cas :

http://msdn.microsoft.com/fr-fr/library/system.text.asciiencoding.aspx

- ASCIIEncoding correspond à la page de codes 20127 de Windows.Les caractères ASCII sont limités aux 128 caractères Unicode de plus faible valeur (de U+0000 à U+007F).Pour plus d'informations sur les codages pris en charge par System.Text, consultez Fonctionnement des encodages et Utilisation de l'encodage Unicode

- Les versions antérieures de .NET Framework autorisaient l'usurpation d'adresse en ignorant simplement le 8ème bit.La version actuelle a été modifiée afin que les points de code non-ASCII reviennent pendant le décodage d'octets.

je me suis donc servi de receivedByte=_serialPort.ReadByte(); et je construis ma chaine de caractère au fur et à mesure jusqu'au caractère <LF>.

Voila pour ce que ca interesse !!
3
Rejoignez-nous