Partage
  • Partager sur Facebook
  • Partager sur Twitter

c# Réceptionner data port série [WPF]

Sujet résolu
    7 juin 2019 à 11:26:46

    Bonjour,

    Voici mon problème.

    Je souhaite récupérer des datas d'un petit boitier. Ce boitier est connecté à mon PC en port série (port com 8). J'ai essayer de suivre pas mal d'exemple sur internet, mais je n'arrive pas à récupérer dans mon formulaire la moindre data émanant de ce boitier.

    Pouvez vous me mettre sur la piste svp ? Voici mon code qui ne fonctionne pas pour la réception de data. J'arrive bien à ouvrir mon port. Je précise que la réception doit se faire au moment où l'on clique sur le bouton BNR

    Je me demandais si il faut pas envoyer une commande au boitier pour récupérer les datas ?

    using System.IO.Ports;
    
    
    namespace testBoitier
    {
        public partial class boitier: Form
        {
         
            
            public boitier()
            {
                InitializeComponent();
            }
    
        private void BNR_Click(object sender, EventArgs e)
            {
              
                SerialPort mySerialPort = new SerialPort("COM8");
    
                mySerialPort.BaudRate = 4800;
                mySerialPort.Parity = Parity.None;
                mySerialPort.StopBits = StopBits.One;
                mySerialPort.DataBits = 8;
                mySerialPort.Handshake = Handshake.None;
                mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceviedHandler);
    
                mySerialPort.Open();
    
      
    
                mySerialPort.Close();
        
            }
    
            private static void DataReceviedHandler( object sender, SerialDataReceivedEventArgs e)
            {
                SerialPort sp = (SerialPort)sender;
                string indata = sp.ReadExisting();
            }
    
    }
    }



    Je vous remercie par avance de votre aide

    -
    Edité par xeration 7 juin 2019 à 11:35:06

    • Partager sur Facebook
    • Partager sur Twitter
      7 juin 2019 à 11:58:54

      >Je me demandais si il faut pas envoyer une commande au boitier pour récupérer les datas ?

      Ça doit être marqué dans la documentation du boitier, non ?

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        7 juin 2019 à 13:47:51

        Je ne sais pas la doc est plus disponible et les références sont effacés, je donnais une piste savoir si ce genre de chose pouvait se faire ou non ^^"
        • Partager sur Facebook
        • Partager sur Twitter
          7 juin 2019 à 14:04:23

          Oui, un dispositif peut attendre qu'on lui demande pour parler, c'est même très courant.

          Il est bien fourni avec un logiciel, votre boitier "bidule" ?

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
            7 juin 2019 à 16:13:34

            Aucun logiciel d'installer sur le poste où il est en question il est juste branché en port série sur le PC. (C'est un vieux coucou qui est installé ici depuis plusieurs années, je redéveloppe une application existante dont les sources sont disponible en C++)

            La partie qui m'interesse est celle ci :

               if (m_actif_port_serie == TRUE)
            
            	   { 
            
                       m_strSend.Format("QXY\r\n");
            
            		   m_ports.WriteToPort(m_strSend.GetBuffer(0));
            
            	   }
            
            



            mais je ne sais pas comment la retranscrire en C#

            -
            Edité par xeration 7 juin 2019 à 16:14:53

            • Partager sur Facebook
            • Partager sur Twitter
              7 juin 2019 à 16:37:06

              On voit bien qu'il y a envoi de données, "WriteToPort" est assez explicite.

              Si vous n'avez pas de documentation, vous devez analyser l'existant.

              N'ayant pas connaissance des classes C++ qui votre vieil applicatif utilise, on ne peut pas faire le boulot à votre place.

              Mais à la tête du nom des méthodes, "WrtiteToPort" me semble bien correspondre à la méthode "Write" de SerialPort de .NET.

              https://www.codeproject.com/Questions/1130049/How-to-write-serial-port-using-Csharp

              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                11 juin 2019 à 8:22:45

                Je galère un petit peu.

                J'ai retrouvé ce code fait en VBA qui est fonctionnel, encore une fois je n'arrive pas à retranscrire en C# ...

                'Vider le buffer
                NETComm1.InBufferCount = 0
                
                'choisir un port série
                NETComm1.CommPort = 1 'Ici
                
                'Balance
                '4800 bauds,pas parité, 8 bits de données, 1 bit d'arrêt
                NETComm1.Settings = "4800,N,8,1" 'Ici
                
                'ouvre le port
                NETComm1.PortOpen = True
                
                
                
                'envoi lecture des valeurs
                NETComm1.Output = "QXY" & vbCrLf
                
                Do
                    DoEvents
                    Tampon$ = Tampon$ & NETComm1.InputData
                
                Loop Until InStr(Tampon$, vbCrLf)
                
                valeur = Tampon$
                
                Valeur_X = Left(valeur, 10)
                
                Valeur_Y = Left(valeur, 8)
                
                Worksheets("Mesures").Activate
                
                Worksheets("Mesures").Cells(2 + ligne, 2 + colone).Value = Valeur_X
                Worksheets("Mesures").Cells(3 + ligne, 2 + colone).Value = Valeur_Y
                
                colone = colone + 1
                
                
                'ferme le port
                NETComm1.PortOpen = False  'Ici
                'UserForm1.Hide



                • Partager sur Facebook
                • Partager sur Twitter
                  11 juin 2019 à 9:24:32

                  Le VBA fonctionne comme le code C++.

                  Vous commencez par envoyer la chaine de caractère "QXY" suivi d'un caractère ASCII CR puis d'un caractère ASCII LF.

                  Il faut donc lui envoyer ces 5 octets pour que votre boitier commence à causer.

                  Donc utilisez la méthode "Write" de l'objet de type SerialPort. Il faut juste faire attention à bien envoyer vos chaine en ASCII.

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                    11 juin 2019 à 10:17:35

                    Voici mon code :

                      SerialPort mySerialPort = new SerialPort("COM8");
                                
                                mySerialPort.BaudRate = 4800;
                                mySerialPort.Parity = Parity.None;
                                mySerialPort.StopBits = StopBits.One;
                                mySerialPort.DataBits = 8;
                                mySerialPort.Handshake = Handshake.None;
                                mySerialPort.Encoding = System.Text.Encoding.Default;
                                mySerialPort.Open();
                                string envoie = "QXY" + System.Environment.NewLine;
                                mySerialPort.Write(envoie);
                    
                                received += mySerialPort.ReadExisting();
                    
                    
                                mySerialPort.Close();
                                TBNRRZ.Text = received;

                    Et je ne récupère toujours rien, j'ai vu sur un site pour l'ascii il fallait envoyé ça via cette ligne :

                              mySerialPort.Encoding = System.Text.Encoding.Default;



                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 juin 2019 à 11:35:10

                      Il ne faut pas utiliser "NewLine" car c'est fonction de la plateforme et le boitier, il s'en fout, il veut du CRLF, que vous soyez sous MAC ou Windows ou Android etc...

                      Le plus simple, c'est d'utiliser un analyser de protocole sur le lien série pour voir comment cela fonctionne avec le code C++ et VBA et de voir ce qui diffère avec la version C#.

                      Je pense que des "00" sont ajoutés dans la version C#.

                      Installez le delegate sur réception de données avant l'envoi des caractères, n'utilisez pas de "ReadExisting", et fermez le port que dans le delegate de réception ou d'erreur.

                      (ou utilisez des primitives synchrones)

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                        12 juin 2019 à 8:16:49

                        J'ai résolu le problème, c'est assez spécifique donc je ne sais pas si ça peux aider quelqu'un.

                        Le boitier en effet attendais la commande "QXY" + System.Environment.NewLine

                        Il fallait ensuite que je mette   Thread.Sleep(1000); pour laisser le temps au boitier de me répondre.

                        Ensuite il y avait un problème de configuration, il fallait mettre 2 bits d'arrêt, et non 1.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          12 juin 2019 à 11:46:43

                          Ok, merci pour ce retour.

                          Attention "System.Environment.NewLine" est une fausse bonne idée, utilisez le format de fin de ligne que comprend votre boitier, pas celui de votre machine hôte.

                          Vous "devez" utiliser un "Thread.Sleep(xxx)" parce que vous n'utilisez ni d'API bloquante, ni de mécanisme de lecture par event avant de fermer votre connexion. C'est assez bizarre d'utiliser des API non bloquante et de faire des Sleep juste pour ne pas lire trop vite.

                          Simplifiez-vous la vie en utilisant des API synchrone bloquante comme Read.

                          https://docs.microsoft.com/fr-fr/dotnet/api/system.io.ports.serialport.read?view=netframework-4.8

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                          c# Réceptionner data port série [WPF]

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          • Editeur
                          • Markdown