Trame NMEA d’un GPS

Protocole NMEA

La norme NMEA 0183 est une spécification pour la communication entre équipements électroniques marins (GPS, radar, girouette, pilote automatique, …). Elle est définie et contrôlée par la National Marine Electronics Association (NMEA), association américaine de fabricants d’appareils électroniques maritimes.

Dans le cas d’un GPS, les trames sont transmises en boucle via une simple transmission série à la vitesse de 4800 baud, sous la forme d’une suite de caractères ASCII, tous imprimables, ainsi que les caractères [CR] Retour Chariot et [LF] Retour à la ligne.

Chaque trame commence par le caractère $, suivi par un groupe de 2 lettres pour l’identifiant du récepteur (par exemple GP pour Global Positioning System). La virgule est utilisée pour séparer les différents champs de donnée.

Suit un groupe de 3 lettres pour l’identifiant de la trame, comme par exemple :

  • GGA : pour GPS Fix et Date,
  • GLL : pour Positionnement Géographique Longitude – Latitude,
  • GSA : pour DOP et satellites actifs,
  • GSV : pour Satellites visibles,
  • VTG : pour Direction (cap) et vitesse de déplacement (en nœuds et km/h),
  • RMC : pour données minimales exploitables spécifiques.

En queue de trame, un champ nommé checksum, précédé du signe *, représente le OU exclusif de tous les caractères compris entre $ et * (exclus).

 

Parmi les messages émis par les GPS on rencontre les données d’acquisition du FIX (trame GGA) :

$GPGGA,123519,4807.038,N,01131.324,E,1,08,0.9,545.4,M,46.9,M, , *42

    • 123519 = Acquisition du FIX à 12:35:19 UTC
    • 4807.038,N = Latitude 48°07.038′ N
    • 01131.324,E = Longitude 11°31.324′ E
    • 1 = Fix qualification : (0 = non valide, 1 = Fix GPS, 2 = Fix DGPS)
    • 08 = Nombre de satellites en poursuite.
    • 0.9 = DOP (horizontal dilution of position) Dilution horizontale.
    • 545.4,M = Altitude, en Mètres, au dessus du MSL (mean see level) niveau moyen des Océans.
    • 46.9,M = Correction de la hauteur de la géoïde en Mètres par rapport à l’ellipsoïde WGS84 (MSL).
    • (Champ vide) = nombre de secondes écoulées depuis la dernière mise à jour DGPS.
    • (Champ vide) = Identification de la station DGPS.
    • *42 = checksum

 

Travail demandé

La trame issue d’un module GPS a été transmise vers le port série d’un ordinateur et affichée au format texte dans un logiciel de type terminal :

$GPGGA,122755.095,4849.7970,N,00134.7688,W,1,03,2.3,-48.0,M,48.0,M,,0000*54
$GPGSA,A,2,27,26,05,,,,,,,,,,2.5,2.3,10*30
Interpréter ces trames afin de déterminer les valeurs de longitude et de latitude envoyées par le GPS.

 

L’objectif est de réaliser un programme en Python capable d’interpréter automatiquement ce type de trame afin d’extraire les suites de caractères définissant la latitude et la longitude, puis de les afficher sur un écran de contrôle.

Le traitement des chaînes de caractères nécessite de bien les identifier et d’en connaître précisément le format. Celui de la longitude est différent de celui de la latitude : il possède un chiffre significatif supplémentaire. Ceci s’explique par la valeur de l’angle qui ne dépasse pas 90° pour une latitude et qui peut atteindre 180° pour une longitude.

 

Un algorithme permettant d’extraire la latitude de la trame NMEA est fourni ci-dessous. Les phrases précédées par // sont des commentaires.

Chaque ligne débute par un caractère $. Il faut ensuite repérer la suite de caractères GPGGA, puis passer deux virgules pour commencer à lire les informations relatives à la latitude.

 

// La fonction serie(p, n), appelée plusieurs fois, permet de lire n octets reçus successivement sur le port p. 
// Pour lire un seul octet, il suffit de positionner n à 1.

// Déclaration des variables
reception, latitude, longitude de type chaîne de caractères
compteur de type entier

// Recherche de l’entête de la trame NMEA

Début
   reception <- "" // Initialisation de la variable reception avec une chaîne vide
   Répéter // Recherche de la suite de caractères $GPGGA
      Répéter
         reception serie(1, 1)
      Jusqu'à reception = "$"
      reception <- "" // Réinitialisation de la variable reception avec une chaîne vide
      reception <- serie(1, 5)
   Jusqu'à reception = "GPGGA"

   // La variable reception ayant maintenant pour contenu la suite de caractères GPGGA, 
   // on recherche le début de la chaîne de caractères relative à la latitude

   reception <- "" // Réinitialisation de la variable reception avec une chaîne vide
   Pour compteur allant de 1 à 2
      Répéter
         reception <- serie(1, 1)
      Jusqu'à reception = ","
      reception <- "" // Initialisation de la variable reception avec une chaîne vide
   Fin pour
   
   // Lecture de la suite de caractères relative à la latitude
   latitude <- ""            // Initialisation de la variable latitude avec une chaîne vide
   latitude <- serie(1, 11)  // La variable latitude contient maintenant la bonne valeur

   // Appel de la fonction afficher(variable, 1) 
   // qui permet de convertir les derniers caractères stockés dans la variable reception en une donnée lisible par l’opérateur
   // et d’afficher ces informations sur la première ligne de l’écran de contrôle.
   
   afficher(latitude, 1)

   // .................................
Fin

 

 

Compléter l’écriture de cet algorithme afin d’extraire et d’afficher la longitude.

 

Implémenter le programme en Python et tester son bon fonctionnement.

 

 

 

 

D’après sujet Bac S-SI 2013 Métropole

Sources : http://www.cedricaoun.net/eie/trames%20NMEA183.pdf

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *