Problème de decodage trame nmea

Résolu
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008 - 21 avril 2008 à 23:21
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008 - 26 mai 2008 à 11:40
Bonjours à toutes et à tous,

Je developpe une petite appli avec mon gps sous visual basic 2008, mais je n'arrive pas à trouver les commandes pour lire le buffer, le segmenter, et le traiter. Quelqu'un pourrait il eclairer ma lanterne svp?

Merci d'avance.

Flatron

28 réponses

NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
24 avril 2008 à 16:54
Bonjour

Je n'ai pas eu spécialement le temps de regardé le code, mais il me semble que tu as récupéré le conde ici :
http://www.codeproject.com/KB/vb/WritingGPSApplications1.aspx

Dans ce cas, normalement, il suffit de récupérer le code présenté dans le Listing 1.2
et écouter l'evenement :PositionReceived

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
3
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
13 mai 2008 à 08:34
Bonjour

Par un Timer par exemple.
Ou un Thread, c'est selon le besoin.

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
3
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
22 avril 2008 à 13:41
Bonjour

Tu communique en COM, TCP, autre ?
Qu'as-tu déjà fait ?

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
22 avril 2008 à 17:57
Bonjour et merci pour ta réponse. Je communique sur du COM virtuel simulé par un petit logiciel (par ailleurs trés pratique) nommée spanner. Concernant ce que j'ai déjà, je lis les trames NMEA dans une textbox, voici le code:
OptionExplicitOn<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>

 

 

Imports System

Imports System.Collections.Generic

Imports System.ComponentModel

Imports System.Data

Imports System.Drawing

Imports System.Text

Imports System.Windows.Forms

Imports System.IO.Ports

Imports MSCommLib

Imports System.Globalization

 

 

 

PublicClass Form4

 

    DimWithEvents serialPort AsNew IO.Ports.SerialPort

 

    PrivateSub Form1_Load( _

       ByVal sender As System.Object, _

       ByVal e As System.EventArgs) _

       HandlesMyBase.Load

 

        For i AsInteger = 0 To _

           My.Computer.Ports.SerialPortNames.Count - 1

            cbbCOMPorts.Items.Add( _

               My.Computer.Ports.SerialPortNames(i))

        Next

        btnDisconnect.Enabled = False

    EndSub

 

    PrivateSub DataReceived( _

       ByVal sender AsObject, _

       ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _

       Handles serialPort.DataReceived

 

        txtDataReceived.Invoke(New  _

                       myDelegate(AddressOf updateTextBox), _

                       NewObject() {})

    EndSub

 

 

    PublicDelegateSub myDelegate()

    PublicSub updateTextBox()

        With txtDataReceived

            .Font = New Font("Garamond", 8.5!, FontStyle.Bold)

            .SelectionColor = Color.Blue

            .AppendText(serialPort.ReadExisting)

            .ScrollToCaret()

        EndWith

    EndSub

 

    PrivateSub btnConnect_Click( _

       ByVal sender As System.Object, _

       ByVal e As System.EventArgs) _

       Handles btnConnect.Click

        If serialPort.IsOpen Then

            serialPort.Close()

        EndIf

        Try

            With serialPort

                .PortName = cbbCOMPorts.Text

                .BaudRate = 9600

                .Parity = IO.Ports.Parity.None

                .DataBits = 8

                .StopBits = IO.Ports.StopBits.One

                ' .Encoding = System.Text.Encoding.Unicode

            EndWith

            serialPort.Open()

 

            lblMessage.Text = cbbCOMPorts.Text & " connected."

            btnConnect.Enabled = False

            btnDisconnect.Enabled = True

        Catch ex As Exception

            MsgBox(ex.ToString)

        EndTry

    EndSub

 

    PrivateSub btnDisconnect_Click( _

       ByVal sender As System.Object, _

       ByVal e As System.EventArgs) _

       Handles btnDisconnect.Click

        Try

            serialPort.Close()

            lblMessage.Text = serialPort.PortName & " disconnected."

            btnConnect.Enabled = True

            btnDisconnect.Enabled = False

        Catch ex As Exception

            MsgBox(ex.ToString)

        EndTry

    EndSub

 

    PublicClass TestNmeaInterpreter

        ' Processes information from the GPS receiver

 

        PublicFunction Parse(ByVal sentence AsString) AsBoolean

            ' Divide the sentence into words

 

            Dim Words() AsString = GetWords(sentence)

            ' Look at the first word to decide where to go next

 

            SelectCase Words(0)

                Case"$GPRMC"      ' A "Recommended Minimum" sentence was found!

 

                    ' Indicate that the sentence was recognized

 

                    ReturnTrue

                CaseElse

                    ' Indicate that the sentence was not recognized

 

                    ReturnFalse

            EndSelect

        EndFunction

 

        ' Divides a sentence into individual words

 

        PublicFunction GetWords(ByVal sentence AsString) AsString()

            Return sentence.Split(","c)

        EndFunction

 

 

        PublicEvent PositionReceived(ByVal latitude AsString, _

                                      ByVal longitude AsString)

 

 

        PublicFunction ParseGPRMC(ByVal sentence AsString) AsBoolean

            ' Divide the sentence into words

 

            Dim Words() AsString = GetWords(sentence)

            ' Do we have enough values to describe our location?

 

            If Words(3) <> ""And Words(4) <> ""And Words(5) <> ""And _

                                        Words(6) <> ""Then

                ' Yes. Extract latitude and longitude

 

                Dim Latitude AsString = Words(3).Substring(0, 2) & "°"' Append hours

 

                Latitude = Latitude & Words(3).Substring(2) & """"      ' Append minutes

                Latitude = Latitude & Words(4)     ' Append the hemisphere

 

                Dim Longitude AsString = Words(5).Substring(0, 3) & "°"' Append hours

 

                Longitude = Longitude & Words(5).Substring(3) & """"     ' Append minutes

 

                Longitude = Longitude & Words(6)     ' Append the hemisphere

 

                ' Notify the calling application of the change

 

                RaiseEvent PositionReceived(Latitude, Longitude)

            EndIf

            ' Indicate that the sentence was recognized

 

            ReturnTrue

        EndFunction

 

        PublicFunction GetChecksum(ByVal sentence AsString) AsString

            ' Loop through all chars to get a checksum

 

            Dim Character AsChar

            Dim Checksum AsInteger

            ForEach Character In sentence

                SelectCase Character

                    Case"$"c

                        ' Ignore the dollar sign

 

                    Case"*"c

                        ' Stop processing before the asterisk

 

                        ExitFor

                    CaseElse

                        ' Is this the first value for the checksum?

 

                        If Checksum = 0 Then

                            ' Yes. Set the checksum to the value

 

                            Checksum = Convert.ToByte(Character)

                        Else

                            ' No. XOR the checksum with this character's value

 

                            Checksum = Checksum Xor Convert.ToByte(Character)

                        EndIf

                EndSelect

            Next

            ' Return the checksum formatted as a two-character hexadecimal

 

            Return Checksum.ToString("X2")

        EndFunction

 

        PublicFunction ParseGPGSV(ByVal sentence AsString) AsBoolean

            Dim PseudoRandomCode AsInteger

            Dim Azimuth AsInteger

            Dim Elevation AsInteger

            Dim SignalToNoiseRatio AsInteger

            ' Divide the sentence into words

 

            Dim Words() AsString = GetWords(sentence)

            ' Each sentence contains four blocks of satellite information.

 

            ' Read each block and report each satellite's information

 

            Dim Count AsInteger

            For Count = 1 To 4

                ' Does the sentence have enough words to analyze?

 

                If (Words.Length - 1) >= (Count * 4 + 3) Then

                    ' Yes.  Proceed with analyzing the block.  Does it contain any

 

                    ' information?

 

                    If Words(Count * 4) <> ""And Words(Count * 4 + 1) <> "" _

                    And Words(Count * 4 + 2) <> ""And Words(Count * 4 + 3) <> ""Then

                        ' Yes. Extract satellite information and report it

 

                        PseudoRandomCode = CType(Words(Count * 4), Integer)

                        Elevation = CType(Words(Count * 4 + 1), Integer)

                        Azimuth = CType(Words(Count * 4 + 2), Integer)

                        SignalToNoiseRatio = CType(Words(Count * 4 + 2), Integer)

                        ' Notify of this satellite's information

 

                        RaiseEvent SatelliteReceived(PseudoRandomCode, Azimuth, Elevation, _

                          SignalToNoiseRatio)

                    EndIf

                EndIf

            Next

            ' Indicate that the sentence was recognized

 

            ReturnTrue

        EndFunction

 

        PublicFunction IsValid(ByVal sentence AsString) AsBoolean

            ' Compare the characters after the asterisk to the calculation

 

            Return sentence.Substring(sentence.IndexOf("*") + 1) = _

                                               GetChecksum(sentence)

        EndFunction

 

        PublicEvent DateTimeChanged(ByVal dateTime As DateTime)

        PublicEvent BearingReceived(ByVal bearing AsDouble)

        PublicEvent SpeedReceived(ByVal speed AsDouble)

        PublicEvent SpeedLimitReached()

        PublicEvent FixObtained()

        PublicEvent FixLost()

        PublicEvent SatelliteReceived(ByVal pseudoRandomCode AsInteger, _

          ByVal azimuth AsInteger, _

          ByVal elevation AsInteger, _

          ByVal signalToNoiseRatio AsInteger)

 

        Private NmeaCultureInfo AsNew CultureInfo("en-US")

        Private MPHPerKnot AsDouble = Double.Parse("1.150779", NmeaCultureInfo)

 

    EndClass

  

 

    EndSub

EndClass

J'ai parcouru le site de long en large, mais aucune des solutions proposées ne fonctionnait. Je code en vb2008, depuis un mois, ce qui m'a surement empeché de trouver la solution (car je ne comprend pas tout pour l'instant). Je crois qu'il faut utiliser "mydelegate" pour appeler les données dans le buffer et aprés passer à la segmentation. Enfin bref, merci pour ton aide en tout cas
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
23 avril 2008 à 15:24
Comme on peut le voir, j'ai essayé de decoder le tout avec la class nmeainterpreter. Mais je n'ai rien touché d'autre, et meme le "sentence", à mon avis, dois etre remplacé par quelquechose en raport avec Mydelegate. Enfin je ne sais pas trop...
0
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
24 avril 2008 à 14:07
Bonjour

Quest ce qui est affiché dans ta TextBox ?
Car il existe plusieurs type de trames NMEA : http://fr.wikipedia.org/wiki/Nmea

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
24 avril 2008 à 16:39
Dans ma textbox, je peux visualer, en temps réel, l'arrivée des divers trames envoyées par le GPS.
Je reçois les types de trames suivantes:
- GPGGA
- GPRMB
- GPGSA
- GPGSV
- GPGLI
- GPBOD
- DPVTG
- PGRME
- PGRMZ
- PGRMM
- HCHDG
- GPRTE
- GPRMC
- GPRMB
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
24 avril 2008 à 18:06
Effectivement, j'ai "tenté" d'utiliser cette source, ainsi qu'un morceau d'un autre (voir SerialCommchat, je n'ai plus le lien). Je te remercie de tes eclaircissement, je vais voir ce que je peux avec le "Positionreceveid". Je te tiens au courant. Quoi qu'il en soit, merci pour ton aide ;)
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
28 avril 2008 à 15:00
Salut Nico,

Merci pour ta soluce.

Voici mon soucis suivant (ce serait trop facile sinon):

J'obtiens mes coordonnées dans deux autres textbox, cependant le format ne me convient pas et je voudrais les afficher (en plus) sous un autre format. J'ai les formules:

Degrees = Int(Decimal_Deg)
Minutes = (Decimal_Deg - Degrees) * 60
Seconds = Format(((Minutes - Int(Minutes)) * 60), "0")
Convert_Degree = " " & Degrees & "° " & Int(Minutes) & "' " & Seconds + Chr(34)

Et voici ce que récupères mes boxs (au départ, donc non converti:)

LAB_Latitude.Text = wInfo.Latitude.ToString
LAB_Longitude.Text = wInfo.Longitude.ToString

Le soucis: comment les associer? Et comment déclarer les noms?

Merci de votre aide
0
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
28 avril 2008 à 15:15
Bonjour

Le mieux pour des formules plus Frameworks :

dim Degrees as integer=cint(Math.Truncate(Decimal_Deg))

Decimal_Deg-=Degrees

Decimal_Deg*=60

Dim Minutes as integer=cint(math.Truncate(Decimal_Deg))

Decimal_Deg-=Minutes

Decimal_Deg*=60
dim Secondes as integer= cint(math.Truncate(
Decimal_Deg))

dim ConvertDegree as string=string.format({0}° {1}' {2}'',Degrees,Minutes,Secondes)

Cela fonctionne à la condition que Decimal_Deg soit un Double ou un Decimal (voir Double.Parse, Decimal.parse).

"Comment déclarer les noms" ??? Que veux-tu dire ?

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
28 avril 2008 à 15:30
En fait j'ai du mal à saisir quelle variable je dois prendre et ou je dois la mettre pour que la function de conversion s'applique, et ou recuperer le resultat.
0
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
28 avril 2008 à 16:31
Bonjour

Si tu gère l'evenement "PositionReceived", tu obtient directement les cooéronées sours la forme x°y'z".

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
28 avril 2008 à 17:26
Je commence à y voir plus clair.

Dans la definition de l'event "position receveid" il y a latitude et longitude (en string), comment puis-je les gerer simultanément? (je sais ça doit te paraitre simple)

Si je veux l'afficher dans une textbox, je dois faire comment?

Merci de ton aide, c'est sympas ;)
0
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
29 avril 2008 à 08:54
Bonjour

Dans la gestion de l'evenement (voir WithEvents et Addhandler), tu fais simplement :
TxtLatitude.text=latitude
TxtLongitude.text=longitude

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
29 avril 2008 à 09:53
Bonjour Nico,

Oui Oui mais c'est plutot dans la definition que je ne sais pas trop, genre "function...byval...As..." je vais voir ce que je peux faire avec ça. Merci en tout cas pour ton aide :)
0
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
29 avril 2008 à 09:59
Bonjour

Le prototype de la procédure de gestion est :

Sub NMEA_PositionReceived(ByVal latitude As String, ByVal longitude AsString)

Tu peux changer le nom de la procédure si tu veux, mais reste cohérent avec le programme.

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
29 avril 2008 à 23:55
Nickel !!!! ça marche :) Merci t'assure. Par contre je n'arrive à traiter que les evenements de la trame GPMRC, les autres ne veulent pas, donc je n'ai que les infos de base. Est il possible que, utilisant un Garmin, le protocole proprietaire plante la norme NMEA ?  Et par rapport aux Integer, je crois que ce n'est pas une valeur numerique pouvant etre inserer dans une textbox. Comment peux t on faire?

Merci
0
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
30 avril 2008 à 08:16
Bonjour

Regarde cette fonction :

PublicFunction Parse(ByVal sentence AsString) AsBoolean
' Look at the first word to decide where to go next

SelectCase GetWords(sentence)(0)
Case"$GPRMC"' A "Recommended Minimum" sentence was found!

Return ParseGPRMC(sentence)
CaseElse
' Indicate that the sentence was not recognized

ReturnFalse
EndSelect
EndFunction

Il te suffit de rajouter des "Case ""$...."""
Et ensuite de voir comment est traitée la trame GPRMC (et non  GPMRC comme tu l'as écrit) et de faire ce que tu désire.

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
0
flatron123 Messages postés 49 Date d'inscription mardi 11 mars 2008 Statut Membre Dernière intervention 29 juin 2008
3 mai 2008 à 22:45
Bonsoir,

Bon c'est parfait, tout marche. Pour les trames qui ne voulaient pas etre decoupées, cela venait simplement d'un caracteres en trops, dans les cases tu me parlais.

Mes problèmes suivants se situe au niveau de la trame GPGSV. Celle ci est, en theorie, divisé en 3 parties, et te donne les infos sur les satellites en vue.

<center>Satellites en vue - GPS</center>
<center>$GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75
</center>
2 = Nombre de trames GSV avec les données complètes.
1 = Trame 1 de 2 trames (jusqu'à 3 trames)
08 = Nombre de satellites visibles (SV).
01 = N° d'identification du 1er Satellite.
40 = Elevation en degrés du 1er Satellite.
083 = Azimuth en degrés du 1er Satellite.
46 = Force du signal du 1er Satellite (Plus grand=meilleur)

(Cette séquence se répète jusqu'à 4 satellites par trames.
On peut donc avoir jusqu'à 3 trames GSV dans une transmision (12 satellites).)
*75 = cheksum
non représentés les CR et LF

Ce qui vous explique la limitation à 12 satellites de nos petits appareils.
http://www.gpspassion.com/forumsen/topic.asp?TOPIC_ID=17661

Mon soucis est que, regulierement, la trame complète n'arrive pas, et est "tronquée" dans sa troisieme partie, ce qui me fait planter mon code.

Dans mes cases, j'ai dit "si le caractere est different de zero, alors..." mais comment faire si le caractere est "vide".

Autre point d'interrogation, comment représenté les satellites (on dispose de l'azimuth, et l'elevation de chacun dans la trame aussi). Je me dirige vers une picturebox sur laquelle se disposerons mes icones en fonction de coordonnées cartesiennes, mais je n'ai pas trouvé de tuto en rapport. Tu as une idée?

Merci

Flatron
0
NHenry Messages postés 15151 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 4 septembre 2024 159
5 mai 2008 à 14:19
Bonjour

Pour la représentation, je ne pourrais t'aider.

En ce qui concerne la réception, comment définis-tu la fin de ta réception ?

Le fer à souder a besoin d'une panne pour fonctionner.
VB (6, .NET1&2), C++, C#.Net1
0
Rejoignez-nous