Se connecter / S'enregistrer
Votre question

Traitement des données d'un port série

Tags :
  • chaine
  • port serie
  • Programmation
Dernière réponse : dans Programmation
3 Mai 2012 14:45:56

Bonjour à tous,

Je rencontre un soucis au niveau de mon port série. Je suis en train de développer une petite application qui me permet de lire les données d'un chronomètre. Voici mon code :

  1. using System;
  2. using System.Text;
  3. using System.Drawing;
  4. using System.IO.Ports;
  5. using System.Windows.Forms;
  6. using System.IO;
  7.  
  8. namespace WindowsFormsApplication1
  9. {
  10. public partial class Form1 : Form
  11. {
  12. private SerialPort sp = new SerialPort();
  13. public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };
  14. private Color[] LogMsgTypeColor = { Color.Blue, Color.Green, Color.Black, Color.Orange, Color.Red };
  15.  
  16. public Form1()
  17. {
  18. InitializeComponent();
  19.  
  20. sp.BaudRate = 9600;
  21. sp.Parity = Parity.None;
  22. sp.StopBits = StopBits.One;
  23. sp.DataBits = 8;
  24. sp.RtsEnable = true;
  25. sp.Handshake = Handshake.None;
  26. sp.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
  27.  
  28. }
  29.  
  30. private void button1_Click(object sender, EventArgs e)
  31. {
  32. bool erreur = false;
  33.  
  34. // Si le port est ouvert, il faut le fermer
  35. if (sp.IsOpen) sp.Close();
  36. else
  37. {
  38. // Réglage paramètre du port
  39. sp.PortName = cmbPortName.Text;
  40.  
  41. try
  42. {
  43. // Ouvrir le port
  44. sp.Open();
  45. }
  46. catch (UnauthorizedAccessException) { erreur = true; }
  47. catch (IOException) { erreur = true; }
  48. catch (ArgumentException) { erreur = true; }
  49.  
  50. if (erreur)
  51. MessageBox.Show("Impossible d'ouvrir le port COM. Très probablement, il est déjà en cours d'utilisation, a été supprimé, ou n'est pas disponible.", "COM Port indisponible", MessageBoxButtons.OK, MessageBoxIcon.Stop);
  52. else
  53. MessageBox.Show("Connexion réussi", "Port disponible");
  54. }
  55. }
  56.  
  57. // Connexion à la fenêtre du terminal
  58. private void Log(LogMsgType msgtype, string msg)
  59. {
  60. rtfTerminal.Invoke(new EventHandler(delegate
  61. {
  62. rtfTerminal.SelectedText = string.Empty;
  63. rtfTerminal.SelectionFont = new Font(rtfTerminal.SelectionFont, FontStyle.Bold);
  64. rtfTerminal.SelectionColor = LogMsgTypeColor[(int)msgtype];
  65. rtfTerminal.AppendText(msg);
  66. rtfTerminal.ScrollToCaret();
  67. }));
  68.  
  69.  
  70. }
  71.  
  72. //Convertit un tableau d'octets en une chaîne formatée de chiffres hexadécimaux.
  73. private string ByteArrayToHexString(byte[] data)
  74. {
  75. StringBuilder sb = new StringBuilder();
  76. foreach (byte b in data)
  77. sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
  78.  
  79. return sb.ToString().ToUpper();
  80. }
  81.  
  82. static public string ReverseString(string str)
  83. {
  84. char[] charArray = str.ToCharArray();
  85. Array.Reverse(charArray);
  86. return new string(charArray);
  87. }
  88.  
  89. public static string Reverse(string text)
  90. {
  91. string retour = "";
  92. string[] str = text.Split(' ');
  93. for (int i = 0; i < str.Length; i++)
  94. {
  95. retour += ReverseString(str[i]);
  96. retour += " ";
  97. }
  98. return retour;
  99. }
  100.  
  101.  
  102.  
  103. public void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
  104. {
  105.  
  106. switch (e.EventType)
  107. {
  108. case SerialData.Chars:
  109. {
  110. // Si le port est ouvert, le fermer
  111. if (!sp.IsOpen) return;
  112.  
  113. // Obtenir le nombre d'octets en attente dans le tampon du port
  114. int bytes = sp.BytesToRead;
  115. // Créez une zone tampon (tableau d'octets) pour stocker les données entrantes
  116. byte[] buffer = new byte[bytes];
  117. // Lire les données du port et de le stocker dans la mémoire tampon
  118. sp.Read(buffer, 0, bytes);
  119.  
  120. // Montrer à l'utilisateur les données entrantes dans un format hexadécimal
  121. Log(LogMsgType.Incoming, ByteArrayToHexString(buffer));
  122. string s = Reverse(ByteArrayToHexString(buffer)).Substring(0, 1);
  123.  
  124. MessageBox.Show(s);
  125. break;
  126. }
  127. case SerialData.Eof:
  128. {
  129. sp.Close();
  130. break;
  131. }
  132. }
  133. }
  134.  
  135. }
  136. }


Voici un exemple de ce que je reçois : 60 00 50 00 53 51 80 00 51

Mon soucis,c'est que je reçois deux MessagesBox avec (si on reprends l'exemple), le 1er MessageBox qui affiche '6' et le second qui affiche '0'. Donc en gros ça me fait deux chaînes :
chaîne1 = 60 et chaîne2 = 00 50 00 53 51 80 00 51
Alors qu'en fait j'aimerais obtenir qu'une seule chaîne concaténant la chaîne1 et la chaîne2
Du coup, je comprends pas pourquoi j'obtiens ce résultat

Je vous remercie d'avance

Autres pages sur : traitement donnees port serie

a b L Programmation
3 Mai 2012 23:55:30

Tu as reçu le message en 2 morceaux. Donc, il faut que selon le type de message, tu boucles pour recevoir tout le message.
4 Mai 2012 11:22:10

Je dois boucler sur cette partie :
  1. sp.Read(buffer, 0, bytes);
?

Comme je reçois deux morceaux, comment récupérer que la première valeur du premier morceau ?
a b L Programmation
5 Mai 2012 21:31:47

Il faut d'abord décoder le type de message pour connaitre la taille du message. Après, tu boucles effectivement sur le read tant que tu n'arrives pas à la taille attendue.
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS