locked
Récepteur Trame GPS RMC sur HTC (Windows Moile) RRS feed

  • Question

  • Bonjour,

    Je suis actuellement en développement d'une application de localisation sur smartphone HTC 3G. 
    Pour ce faire j'utilise une librairie OpenNETCF dont celle ci ==> OpenNETCF.IO.Serial. 
    J'arrive bien à recevoir les trames et je fait un traitement pour récupérer les informations utile de la trame RMC.

    Le problème que j'ai remarquer est que le programme est très gourmand et quand je le quitte de (avec Close(); ou Application.Exit();) de la mémoire n'est pas libérer et quand je veux le supprimer un message m'averti que m'on application n'est pas quitter ???? (et dans l'affichage des applications ouvert je ne la voit plus)

    Je pense que mon problème vient de la réception des trames, alors voici mon code avec l'utilisation de OpenNETCF :

    
            private void Initialisation()
            {
                // parametrage de la liaison serie avec le port COM et le materiels
                // grace a la librairie OpenNETCF.IO.Serial
                DetailedPortSettings portSettings = new OpenNETCF.IO.Serial.HandshakeNone();
                port1 = new Port("COM1:");
                port1.Settings.BaudRate = BaudRates.CBR_9600; // Debit en bauds
                port1.Settings.ByteSize = 8; // Taille des bytes
                port1.Settings.Parity = Parity.none; // pas de parite
                port1.Settings.StopBits = StopBits.one; // 1 stop de bit
                port1.RThreshold = 1; // get an event for every 1 byte received
                port1.InputLen = 1; // calling Input will read 1 byte
                port1.SThreshold = 1; // send 1 byte at a time
    
                GPS.Erreur = false;
            }


    la methode 

    
            //-----------------------------------------------------------------------------------
            //----------------------------------Methode Lecture----------------------------------
            //-----------------------------------------------------------------------------------
    
            public bool OuvrirPortCom()
            {
                try
                {
                    if (port1.Open() == true)
                        return true;
                    else
                        return false;
                }
                catch
                {
                    Exit();
                    return false;
                }
            }
    
            /* Permet de recevoir les informations du sattelite 
             * et stocke le tout dans une variable Trame 
             */
            public string LecturePortCom()
            {
                byte[] caract = null;
                char car = '0';
    
                //Thread.Sleep(500);
                bool Flag = true;
                string TrameRecep = "";
    
                // on stocke toute les valeur de car dans TrameRecep
                // on les converties pour les rendre compréhensible
                // et ainsi pouvoir les traiter par la suite
                do
                {
                    caract = port1.Input;
                    if (caract.Length <= 0)
                        Flag = false;
                    else
                    {
                        car = Convert.ToChar(caract[0]);
                        TrameRecep += car;
                    }
                } while (Flag);
    
                return TrameRecep;
            }



    et le main :

     

    
                if (GPS.OuvrirPortCom() == true)
                {
                    textBox1.Text = "Port open";
    
                    // permet la lecture et la reception des informations
                    // envoyer par le satellite
                    Trame = GPS.LecturePortCom();
    
                    //MessageBox.Show(Trame);
    
                    // si le programme s'execute trop rapidement la 1ere fois
                    // les infos recu sont vide donc on refait un traitement.
                    if (string.Compare(Trame, "") == 0)
                    {
                        while ((string.Compare(Trame, "") == 0) && (Trame.Length < 30))
                        {
                            Trame = GPS.LecturePortCom();
                        }
                    }
    mercredi 7 avril 2010 15:11

Toutes les réponses

  • Bonjour,

    La méthode que tu utilises est bien trop gourmande en temps. Tu boucles, caractère par caractère jusqu'à obtenir une trame valide sans laisser de l'air au système.

    Il faut que tu bosses par événement. Quand un caractère arrive, un événement est déclenché, tu l'ajoutes à ta trame générale et tu regardes si par hasard tu n'as pas une trame valide. Si c'est le cas tu la traites, sinon tu laisses tomber et tu recommenceras au caractère suivant. Entre chaque arrivée de caractère le système peut respirer.

    Autre méthode, tu lis à intervalle régulier tout ce qu'il y a dans le buffer d'entrée de la liaison série (méthode pool, moins bonne), tu ajoutes le tout à ta trame générale et tu regardes si dans cette trame générale il n'y a pas une ou plusieurs trames valides. Là tu ne réponds pas à l'événement d'arrive de caractère mais à celui d'un timer qui va cadencer tes lectures par blocs.

    Il y a un article qui parle de ça ici : http://www.codeppc.com/dotnetcf2/gps/index.htm

    Bonne chance.

    jeudi 8 avril 2010 07:13
  • Bonjour, 

     

    Merci encore une fois Stéphane. Je suis désoler toute fois car je viens seulement de voir ta réponse mais j'ai bien avancé sur mon projet.

    Finalement, je reçois une série de trame, je fait un traitement pour trouver une trame RMC complète et ainsi obtenir mes donnée de position.

    Cela marche plutôt bien mais au bout d'environ 50 traitement le programme sature !

     

    Je n'ai pas très bien compris le système d'événement pour faire respirer le programme ?

    Je pense qu'il faudrait que je revois ma méthode LecturePortCom() ou peut être que mon programme possèdent des failles à comblé ???

    Pourriez vous jeter un coup d'oeil pour me dire si mon programme possèdent des erreurs vraiment grossière ou possible d'amélioration ???

     

    Voici un aperçu de mon programme :

    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Text;
    using OpenNETCF.IO.Serial;
    
    namespace LectureTrame
    {
      class tGPS
      {
        //-----------------------------------------------------------------------------------
        //---------------------------------Declaration variable------------------------------
        //-----------------------------------------------------------------------------------
    
        // initialisation de la structure tInfoGPS ==> GPS
        tInfoGPS InfoGPS = new tInfoGPS();
    
        // initialisation du portcom (com1) == port1
        public static Port port1;
    
        #region "Initialisation"
        //-----------------------------------------------------------------------------------
        //-----------------------------------Initialisation----------------------------------
        //-----------------------------------------------------------------------------------
    
        /* Initialise le port serie pour pouvoir recevoir les informatiosn 
         * du sattelite
         */
        public tGPS()
        {
          // parametrage de la liaison serie avec le port COM et le materiels
          // grace a la librairie OpenNETCF.IO.Serial
          DetailedPortSettings portSettings = new OpenNETCF.IO.Serial.HandshakeNone();
          port1 = new Port("COM1:");
          port1.Settings.BaudRate = BaudRates.CBR_9600; // Debit en bauds
          port1.Settings.ByteSize = 8; // Taille des bytes
          port1.Settings.Parity = Parity.none; // pas de parite
          port1.Settings.StopBits = StopBits.one; // 1 stop de bit
          port1.RThreshold = 1; // get an event for every 1 byte received
          port1.InputLen = 1; // calling Input will read 1 byte
          port1.SThreshold = 1; // send 1 byte at a time
        }
    
        public void Exit()
        {
          // quite le programme proprement (normalement)
          port1.Close();
        }
        #endregion
    
        #region "Reception et Lecture Trame"
        //-----------------------------------------------------------------------------------
        //----------------------------------Methode Lecture----------------------------------
        //-----------------------------------------------------------------------------------
    
        public bool OuvrirPortCom()
        {
          try
          {
            if (port1.Open() == true)
              return true;
            else
              return false;
          }
          catch
          {
            Exit();
            return false;
          }
        }
    
        /* Permet de recevoir les informations du sattelite 
         * et stocke le tout dans une variable Trame 
         */
        public string LecturePortCom()
        {
          byte[] caract = null;
          char car = '0';
    
          bool Flag = true;
          string TrameRecep = "";
    
          do
          {
            caract = port1.Input;
            if (caract.Length <= 0)
              Flag = false;
            else
            {
              car = Convert.ToChar(caract[0]);
              TrameRecep += car;
            }
          } while (Flag);
    
          return TrameRecep;
        }
        #endregion
    
        #region "Traitement de la Trame"
        //-----------------------------------------------------------------------------------
        //--------------------------------Methode Traitement---------------------------------
        //-----------------------------------------------------------------------------------
    
        /* Permet de verifier dans un premier temps que la trame possédent
         * des informations renvoyé par le sattelite
         * Ensuite on recherche la trame contenant nos informations (trame RMC)
         * en cas d'echec on traite une trame par default
         */
        public tInfoGPS GererTraiterTrame(string[] Tableau)
        {
          // initialisation de la structure tInfoGPS ==> GPS
          tInfoGPS InfoGPS = new tInfoGPS();
    
          string[] TrameTableau = null;
          TrameTableau = Tableau;
          bool Flag = false;
          int i = 0;
    
          if (TrameTableau[i] != "")
          {
            // Continu de lire les ligne de trame
            // temps qu'on a pas trouver celle qu'on cherche
            // ou qu'il n'y a plus de trame à lire
            while ((!Flag) & (i < TrameTableau.Length))
            {
              // verifie qu'il s'agit bien de la trame renvoyer pour le GPS (type NMEA)
              if (TrameTableau[i].IndexOf("$GP", 0) == 0)
              {
                // verifie qu'il s'agit bien de la trame avec nos informations (type RMC)
                if ((TrameTableau[i].IndexOf("$GPRMC", 0) == 0) & (TrameTableau[i].Length > 35))
                {
                  // Trame NMEA est de type RMC
                  InfoGPS = DecomposerTrame(TrameTableau[i], false);
                  Flag = true;
                }
                else
                {
                  InfoGPS = DecomposerTrame("$GPTRM,000000,,0,0,0,0,,,010101,,,", true);
                }
              }
              // la trame contenent nos informations est vide 
              // retour un trame par default en cas d'echec 
              // lorsqu'on capte mal par exemple
              else
              {
                InfoGPS = DecomposerTrame("$GPTRM,000000,,0,0,0,0,,,010101,,,", true);
              }
              i++;
            }
          }
          else
          {
            // la trame contenent nos informations est vide 
            // retour un trame par default en cas d'echec 
            // lorsqu'on capte mal par exemple
            InfoGPS = DecomposerTrame("$GPTRM,000000,,0,0,0,0,,,010101,,,", true);
          }
          return InfoGPS;
        }
    
        /* Decompose la trame contenent nos information, pour recuperer
         * les informations que nous avons besoin pour nous situé
         */
        public tInfoGPS DecomposerTrame(string TrameTableau, bool Erreur)
        {
          // initialisation de la structure tInfoGPS ==> GPS
          tInfoGPS InfoGPS = new tInfoGPS();
    
          //MessageBox.Show("plop");
          //MessageBox.Show(TrameTableau);
          string[] Tableau = null;
          Tableau = new string[14];
          // decoupe une trame (caractere ',') 
          // pour stocker ligne par ligne dans un tableau 
          Tableau = TrameTableau.Split(',');
    
          // on stocke dans une structure GPS les valeur obtenu
          // dans un Tableau par le traitement de notre trame
          InfoGPS.DateHeure = TraiterDateHeure(Tableau[9], Tableau[1]);
          InfoGPS.Latitude = TraiterLatitude(Tableau[3]);
          //MessageBox.Show(InfoGPS.Latitude);
          InfoGPS.NordSud = NordSud(Tableau[4]);
          InfoGPS.Longitude = TraiterLongitude(Tableau[5]);
          InfoGPS.EstOuest = EstOuest(Tableau[6]);
          InfoGPS.Erreur = Erreur;
    
          return InfoGPS;
        }
    
        /* La date et l'heure contenu dans notre trame sont de la forme
         * Heure = xxxxxx et Date = xxxxxx donc on les decoupes pour 
         * les metres de la forme Heure = xx:xx:xx et Date = xx/xx/xx
         */
        private DateTime TraiterDateHeure(string Date, string Horaire)
        {
          DateTime DateHeureTraite;
          int Jours = 01;
          int Mois = 01;
          int Annees = 01;
          int Secondes = 00;
          int Minutes = 00;
          int Heures = 00;
    
          // Verrifie qu'il y a une valeur dans la variable Date
          // si elle n'est pas vide on la met en forme (jj/mm/aaaaa)
          // en passant par DateTime
          if ((Date != "") & (Date.Length > 3))
          {
            Jours = Convert.ToInt32(Date.Substring(0, 2));
            Mois = Convert.ToInt32(Date.Substring(2, 2));
            Annees = Convert.ToInt32(Date.Substring(4, 2));
          }
    
          // Verrifie qu'il y a une valeur dans la variable Horaire
          // si elle n'est pas vide on la met en forme (hh:mm:ss)
          // en passant par DateTime
          if ((Horaire != "") & (Horaire.Length > 3))
          {
            Heures = Convert.ToInt32(Horaire.Substring(0, 2));
            Heures = Heures + 1;
            Minutes = Convert.ToInt32(Horaire.Substring(2, 2));
            Secondes = Convert.ToInt32(Horaire.Substring(4, 2));
          }
          DateHeureTraite = new DateTime(Annees, Mois, Jours, Heures, Minutes, Secondes);
          return DateHeureTraite;
        }
    
        /* La latitude contenu dans notre trame sont de la forme
         * Latitude = ddmm.mmmm donc on la decoupes pour 
         * les metres de la forme Latitude ==> dd°mm.mmm'
         * ainsi on peut retrouvé notre positions sur google map (exemple)
         */
        private string TraiterLatitude(string Latitude)
        {
          // Verrifie qu'il y a une valeur dans la variable Latitude
          if ((Latitude != "") & (Latitude.Length > 6))
          {
            string LatitudeTraite = "";
            // Traite la Latitude = ddmm.mmmm ==> 25°03.6319'
            // En entree Latitude = ddmm.mmmm
            string Degres = "";
            string Minutes = "";
    
            Degres = Latitude.Substring(0, 2);
            Minutes = Latitude.Substring(2, 7);
    
            LatitudeTraite = Degres + '°' + Minutes + '\'';
    
            // En sorti Longitude = 25°03.6319'
            return LatitudeTraite;
          }
          // renvoye Erreur si pas de valeur (vide)
          else
            return "0";
        }
    
        /* Retourne le sens de la latitude contenu dans notre trame
         */
        private string NordSud(string NordSud)
        {
          // Verrifie qu'il y a une valeur dans la variable NordSud (le Sens de la Latitude)
          if ((NordSud != "") & (NordSud.Length == 1))
          {
            string NordSudTraite = "";
            NordSudTraite = NordSud;
            // Renvoye NordSud = N(pour Nord) ou S(pour Sud)
            return NordSudTraite;
          }
          // renvoye Erreur si pas de valeur (vide)
          else
            return "0";
        }
    
        /* La Longitude contenu dans notre trame sont de la forme
         * Longitude = dddmm.mmmm donc on la decoupes pour 
         * les metres de la forme Longitude ==> ddd°mm.mmm'
         * ainsi on peut retrouvé notre positions sur google map (exemple)
         */
        private string TraiterLongitude(string Longitude)
        {
          // Verrifie qu'il y a une valeur dans la variable Longitude
          if ((Longitude != "") & (Longitude.Length > 7))
          {
            string LongitudeTraite = "";
            // Traite la Longitude = dddmm.mmmm ==> 121°36.0099'
            // En entree Longitude = dddmm.mmmm
            string Degres = "";
            string Minutes = "";
    
            Degres = Longitude.Substring(0, 3);
            Minutes = Longitude.Substring(3, 7);
    
            LongitudeTraite = Degres + '°' + Minutes + '\'';
    
            // En sorti Longitude = 121°36.0099'
            return LongitudeTraite;
          }
          // renvoye Erreur si pas de valeur (vide)
          else
            return "0";
        }
    
        /* Retourne le sens de la longitude contenu dans notre trame
         */
        private string EstOuest(string EstOuest)
        {
          // Verrifie qu'il y a une valeur dans la variable EstOuest (Sens de la Longitudes)
          if ((EstOuest != "") & (EstOuest.Length == 1))
          {
            string EstOuestTraite = "";
            EstOuestTraite = EstOuest;
            // Renvoye EstOuset = E(pour Est) ou O(pour Ouest)
            return EstOuestTraite;
          }
          // renvoye Erreur si pas de valeur (vide)
          else
            return "0";
        }
        #endregion
    
    
      }
    }
    Cordialement Ullrik

    lundi 3 mai 2010 22:45