Trames NMEA : GxRMC et GxGGA#
Pourquoi#
Le PPS donne un top de seconde d’une précision autour de la microseconde,
mais il ne dit pas quelle seconde vient de sonner (chapitre Constellations
GNSS). Cette information (la date et l’heure du calendrier) arrive par le
second flux du récepteur : les trames NMEA, lues par gpsd et
transmises à chrony en mémoire partagée (chapitre Chrony). Un récepteur GNSS
émet spontanément toute une famille de trames (GGA, GSA, GSV, VTG, GLL,
ZDA…) ; ce projet n’en exploite volontairement que deux : GxRMC et
GxGGA.
Ce choix n’est pas qu’une question d’économie de bande passante sur la
liaison série. Il tient surtout à un principe de reproductibilité. Le
NMEA 0183 est une norme publique et indépendante du constructeur, éditée à
l’origine pour l’électronique marine : tout récepteur GNSS du marché la
parle, du module u-blox à n’importe quelle puce SiRF ou MediaTek. À
l’inverse, le protocole binaire UBX du récepteur utilisé ici (u-blox
NEO-M9N) est plus riche mais propriétaire, lié à l’outillage d’un seul
fabricant. En ne dépendant que de GxRMC et GxGGA, deux trames que tout
récepteur standard sait produire, la méthode entière de ce guide se
transpose telle quelle sur n’importe quel autre matériel, sans rien
réécrire.
Comment#
Anatomie d’une trame NMEA#
Une trame NMEA 0183 est une simple ligne de texte ASCII :
$ GN RMC ,champ,champ,... *HH
│ │ │ │
│ │ │ └─ somme de contrôle (XOR de
│ │ │ tout ce qui précède, en hexadécimal)
│ │ └──────────────────── type de trame (3 lettres : RMC, GGA...)
│ └─────────────────────── identifiant d'émetteur (2 lettres)
└───────────────────────── début de trameL’identifiant d’émetteur (talker ID) est le “Gx” du titre : ces deux lettres désignent la constellation qui a fourni la solution.
| Talker ID | Source |
|---|---|
GP | GPS seul |
GL | GLONASS seul |
GA | Galileo seul |
GB | BeiDou seul |
GN | solution combinée (plusieurs constellations à la fois) |
Un récepteur multi-constellation comme celui de ce projet émet le plus
souvent des trames GN (par exemple $GNRMC), puisqu’il calcule une
solution unique à partir de plusieurs systèmes. C’est pourquoi on note
GxRMC avec un x générique plutôt que GPRMC : figer GP dans une
configuration passerait à côté des trames réellement émises.
GxRMC : la date, l’heure et la validité#
RMC signifie Recommended Minimum specific GNSS data, la trame minimale
recommandée par la norme. C’est la seule trame courante qui porte la
date du calendrier :
$GNRMC,182017.00,A,xxxx.xxxxx,N,xxxxx.xxxxx,E,0.002,,260726,,,A,V*hh
│ │ │
│ │ └─ date : 26/07/26 (JJMMAA)
│ └─────────────────────────────────── statut : A = valide,
│ V = invalide
└───────────────────────────────────────────── heure UTC : 18:20:17Les champs de position (latitude, longitude) et la somme de contrôle sont
masqués (xxxx.xxxxx, *hh) : seuls comptent ici l’heure, la date et le
statut. Les deux dernières lettres avant la somme de contrôle (A,V) sont
l’indicateur de mode et le statut de navigation ajoutés par la norme
NMEA 4.1, sans usage pour ce projet.
Deux champs sont décisifs pour un serveur de temps :
- L’heure UTC + la date : c’est le couple complet qui lève l’ambiguïté
de seconde du PPS. Le PPS dit “c’est maintenant, une transition de
seconde exacte” ;
GxRMCdit “et ce maintenant, c’est le 26 juillet 2026 à 18:20:17 UTC”. - Le statut
A/V:A(Active) signale un point de navigation valide,V(Void) un récepteur sans fix exploitable. Ce champ est ce qui distingue “je reçois des trames” de “j’ai une heure fiable” : c’est lui qui fonde la directivelock GPSde chrony (chapitre Chrony), laquelle refuse de discipliner l’horloge tant que le statut n’est pasA.
GxGGA : la qualité du fix#
GGA signifie Global Positioning System Fix Data. Elle ne porte pas
la date (seulement l’heure du jour), mais apporte les indicateurs de
qualité que GxRMC n’a pas :
$GNGGA,182017.00,xxxx.xxxxx,N,xxxxx.xxxxx,E,1,12,0.87,xx.x,M,xx.x,M,,*hh
│ │ │ │
│ │ │ └─ HDOP : 0,87 (qualité géométrique)
│ │ └── satellites utilisés : 12
│ └──── qualité du fix : 1 = fix GPS
└──────────────────────────────────── heure UTC : 18:20:17Le nombre de satellites utilisés et le HDOP sont les métriques que
l’on surveille pour juger de la santé de la réception (chapitre Vérification
finale), et le champ qualité de fix distingue un point standard d’un
point dégradé. gpsd s’appuie sur GxGGA pour renseigner le mode de fix
et le compte de satellites qu’affiche cgps.
Ce que chaque trame apporte#
| Information | GxRMC | GxGGA |
|---|---|---|
| Heure UTC (du jour) | oui | oui |
| Date du calendrier | oui | non |
Statut de validité A/V | oui | non |
| Qualité du fix | non | oui |
| Nombre de satellites utilisés | non | oui |
| HDOP, altitude | non | oui |
La lecture du tableau donne la raison du couple : GxRMC fournit
l’horodatage complet et le verrou de validité dont chrony a besoin,
GxGGA fournit le diagnostic de réception. Aucune des deux ne suffit
seule : un récepteur qui n’émettrait que GxGGA priverait gpsd de la
date, et donc de tout horodatage UTC complet.
Réduire le récepteur à ces deux trames#
Émettre uniquement GxRMC et GxGGA allège la liaison série et supprime
des trames inutiles au projet (les GSV, qui listent chaque satellite en
vue, sont les plus verbeuses). La sélection des trames actives se fait
côté récepteur ; gpsd, lui, se contente d’exploiter ce qui arrive et
extrait l’heure de n’importe quelle trame standard datée. Le principe reste
volontairement générique : sur un u-blox on ajuste les cadences par
UBX-CFG-MSG, mais l’idée (“ne garder que la trame datée et la trame de
qualité”) vaut pour tout récepteur, quel que soit son outil de
configuration.
Erreurs à éviter#
- Ne compter que sur
GxGGA. SansGxRMC(niZDA), aucune trame ne porte la date :gpsdne peut pas reconstruire un horodatage UTC complet, et la lecture de seconde échoue silencieusement. - Figer le talker ID sur
GP. Un récepteur multi-constellation émet des tramesGN; un filtre ou un test qui cherche littéralement$GPRMCne verra jamais rien passer. Toujours raisonner enGxRMC. - Prendre l’heure NMEA pour une source de précision. La trame arrive
par la liaison série avec une latence de l’ordre de ±10 ms, non
déterministe (chapitre Matériel et câblage). Elle ne sert qu’à dire
quelle seconde ; la précision vient du PPS. C’est exactement pour cela
que la source correspondante est déclarée
noselectcôté chrony. - Ignorer la somme de contrôle. Une trame tronquée ou corrompue sur la
liaison série a une somme de contrôle fausse ; un consommateur qui ne la
vérifie pas peut lire une heure erronée.
gpsdeffectue cette vérification, mais tout parsing maison doit la refaire.
Vérifier#
# Flux NMEA brut : on doit voir défiler des trames RMC et GGA, une fois
# par seconde. Le talker ID (GN, GP...) dépend du récepteur.
gpspipe -r -n 20 | grep -E '(RMC|GGA)'
# Isoler le statut de validité de la trame RMC (3e colonne, virgule) : A attendu
gpspipe -r -n 20 | grep -m1 'RMC' | cut -d, -f3
# A = fix valide, V = pas de fix exploitable
# Nombre de satellites utilisés, lu dans la trame GGA (8e colonne, virgule)
gpspipe -r -n 20 | grep -m1 'GGA' | cut -d, -f8Tant que le statut de GxRMC reste V, c’est que le récepteur n’a pas
encore de fix exploitable (antenne masquée, ou cold start en cours) :
chronyd ne disciplinera pas l’horloge, conformément à lock GPS.
📚 Pour aller plus loin
- Le format des trames est défini par la norme NMEA 0183 (Standard for Interfacing Marine Electronic Devices), National Marine Electronics Association. La norme est payante, mais le sous-ensemble des trames GNSS courantes (
RMC,GGA,GSA,GSV,ZDA) est abondamment documenté dans les manuels des récepteurs et la documentation degpsd.- La liste exacte des trames reconnues par
gpsd, champ par champ, est tenue à jour dans sa page de manuelgpsd_jsonet dans le fichierNMEA.txtdu projetgpsd.- Chapitres liés : Constellations GNSS (comment le récepteur obtient l’heure), Acquisition GNSS/PPS (mise en place de
gpsd), Chrony (consommation de la trame viarefclock SHM).