Decoder für GPS-Daten im NMEA-0183 Format

(nur für bestimmte Geräte mit Schnittstelle für GPS-Empfänger, nach Freischaltung)

Dieses Dokument beschreibt, wie im Terminal Daten von einem externen GPS-Empfänger verarbeitet werden können. In Geräten wie z.B. MKT-View können GPS-Daten nicht nur mit dem Logger aufgezeichnet werden, sondern auch in der Applikation für eigene Zwecke verwendet werden.

Nicht alle Geräte sind zum Anschluß eines GPS-Empfängers geeignet - siehe Feature Matrix : "GPS decoder") !
Das hier beschriebene Feature muss vom Hersteller erst freigeschaltet werden, was i.A. bereits bei der Bestellung erfolgt.

Inhalt

  1. Anschluss eines GPS-Empfängers ('Maus') am MKT-View
  2. Übersicht der Funktionen zum Zugriff auf die GPS-Daten : Position, Höhe, Datum, Uhrzeit, Geschwindigkeit, Qualität, Anzahl Satelliten, ...
  3. Verarbeitung von GPS-Daten per Script
    1. Verwendung des 'OnLocationChanged'-Handlers als GPS/CAN-Gateway
  4. Überprüfen des Empfängers mit dem GPS-Test im MKT-View
    Anhang: Internes Format für Breiten- und Längengrad, Beispielprogramm

Siehe auch:

Hinweis: Der GPS/NMEA-Decoder im MKT-View ist ein optionales Feature, welches vor der Verwendung einmal freigeschaltet werden muss. Er kann allerdings auch ohne Freischaltung (vor dem Kauf) im 'Evaluierungs-Modus' betrieben werden. Im Evaluierungs-Modus sind die GPS-Koordinaten ungenau, und die Anzeige als Zeichenkette (String) weist gelegentlich auf den 'Testbetrieb' hin. Das Freischalten der optionalen Features wird in diesem Dokument beschrieben.

Im Simulator (d.h. Testbetrieb im Programmiertool) funktioniert das Decodieren von NMEA-Zeichenketten immer. Am PC muss dazu lediglich eine geeignete GPS-Maus am seriellen Port des PCs angeschlossen werden, und dessen 'COM-Port-Nummer' im Programmiertool auf dem Panel 'Einstellungen des Programmiertools' angewählt werden. Beim Aufruf des Befehls gps.prot="NMEA" verbindet das Programmiertool den seriellen Port des PCs mit dem GPS-Decoder (NMEA-Parser). Zwischen GPS-Maus und seriellem Port (am PC) könnte ein einfacher Adapter erforderlich sein, da am üblichen RS-232-Anschluss keine 5 bzw. 12 Volt für den GPS-Empfänger abgegriffen werden können. Angaben zur Spannungsversorgung des Empfängers entnehmen Sie bitte dem Datenblatt des Herstellers.

Anschluss eines GPS-Empfängers ('Maus') am MKT-View

Je nach Hardware (und verfügbarem Platz am Gehäuse) kommen für MKT-View II / III / IV unterschiedliche Anschlussbuchsen für den GPS-Empfänger verwendet:


Abbildung 1 : GPS-Anschluss an der rechten Seite vom MKT-View IV

Alle 'GPS-Anschlüsse' führen die Versorgungsspannung für den GPS-Emfänger heraus.
Darum können diese Anschlüsse nicht kompatibel mit einer RS-232-Schnittstelle sein, auch wenn dies beim MKT-View II 'auf den ersten Blick' der Fall zu sein scheint.
Details zum GPS-Anschluss, inklusive Pinbelegung von Buchse oder Stecker, finden Sie im gerätespezifischen Datenblatt.
Einige Datenblätter finden Sie auf der mittlerweile online gestellten 'MKT-CD'.

See also: Testing the GPS receiver, Programming Tool, 'A to Z' .

Übersicht der Funktionen zum Zugriff auf die GPS-Daten

Hinweis: Die im folgenden beschriebenen, noch nicht komplett übersetzten Befehle zum Zugriff auf den GPS-Empfänger bzw. auf die vom Empfänger gelieferten Werte werden für eine 'normale' Anwendung nicht benötigt.
Für den normalen Einsatz (mit Aufzeichnung der GPS-Daten per Logger) muss lediglich der passende Empfängertyp im 'Setup'-Menü eingestellt werden. Eine der folgenden Auswahlmöglichkeiten sollte für Ihren GPS-Empfänger passen: Mit den unten aufgeführten Kommandos kann Ihre Applikation notfalls die im System-Setup eingestellte Auswahl überstimmen.

Konfiguration des seriellen Interfaces (GPS-Baudrate)

gps.baud
Liest oder setzt die Baudrate für den seriellen Port, an dem der GPS-Empfänger angeschlossen werden soll. Einheit: Bits pro Sekunde. Übliche Werte sind 1200, 2400, 4800, 9600, 19200, und manchmal 38400 (bit/second). Beispiel:
@gps.baud=4800
Setzt die Baudrate für den GPS-Port auf die früher üblichen 4800 Bit/Sekunde.
gps.prot
Dieser Parameter sollte von der Applikation auf das zum GPS-Empfänger passende Protokoll gesetzt werden. Der zugewiesene Parameter ist eine Zeichenkette (String, wie bei Strings üblich mit Anführungszeichen umschlossen):
"OFF" = Keine GPS-Daten auf dem seriellen Port (d.h. der Port kann 'für andere Zwecke' verwendet werden). Dies ist aus den hier erläuterten Gründen die Default-Einstellung (auch im Programmiertool / Simulator) !
"NMEA" = GPS-Daten werden Form von Textzeilen übertragen, mit einem NMEA-0183-kompatiblen 'Satz' pro Zeile. Details finden Sie in der frei verfügbaren NMEA-0183-Spezifikation.
gps.cfg
Die Zuweisung eines von Null verschiedenen Wertes an gps.cfg startet eine spezielle Konfigurationsprozedur, die z.B. für die Initialisierung bestimmter "4-Hz-" oder "10-Hz-"GPS-Mäuse benötigt wird, um diese zum Senden von 4 bzw 10 Positionsmeldungen pro Sekunde zu motivieren. Für GPS-Empfänger, die nur das Standard- NMEA-0183-Protokoll verwenden, ist dies nicht nötig (denn normale GPS-Empfänger beginnen autonom mit dem Senden von Positionsdaten, sobald der Satelliten-Almanach empfangen wurde).
Für die o.g. "speziellen" GPS-Empfänger verwenden Sie eine formale Zuweisung wie z.B.
  gps.cfg=4
(Beispiel zum Initialisieren einer "4 Hz"-Maus).

GPS-Empfang

gps.da
Liefert den aktuellen Tag des Monats (1 bis 31).
Siehe auch: gps.yr, gps.mo, gps.da, gps.hr, gps.mi, gps.se . Alle Funktionen zum Auslesen von GPS-Datum und -Uhrzeit verwenden UTC (Universal Time Coordinated), was nahezu mit GMT (Greenwich Mean Time) identisch ist.
Ein GPS-Empfänger liefert immer UTC - nicht Ihre lokale Zeit !
gps.dstr
Liefert das aktuelle (UTC-)Datum als Zeichenkette im Format YYYY-MM-DD (ISO8601, längerspezifische Formate werden nicht unterstützt) .
gps.hasl
Liefert die aktuelle Höhe in Metern über dem Meeresspiegel (hasl = height above sea level).
gps.hdop
Liefert den aktuellen 'HDOP'-Wert vom GPS-Empfänger. HDOP bedeutet
horizontal dilution of precision. Je höher der Wert, desto schlechter ist die Genauigkeit der horizontalen Position. Werte unter 4 gelten üblicherweise als "gut", Werte über 8 sind "schlecht". Der HDOP-Wert ist dimensionslos (keine Angabe in Metern).
gps.hr
Liefert die aktuelle Stunde des Tages (Teil von Datum und Uhrzeit in UTC). Wertebereich 0 bis 23.
Siehe auch: gps.tstr (liefert die komplette Uhrzeit als Zeichenkette für die Anzeige).
gps.lat_d
Liefert den aktuellen Breitengrad als Fliesskommawert in Grad (90°=Nordpol ... -90°=Südpol).
gps.lon_d
Liefert den aktuellen Längengrad als Fliesskommawert in Grad (0°=Greenwich-Meridian, positiv bis 180°=östliche Länge).
gps.lat
Liefert den aktuellen Breitengrad als 32-Bit Integer im internen Format (1/100stel Bogensekunden).
gps.lon
Liefert den aktuellen Längengrad als 32-Bit Integer im internen Format (1/100stel Bogensekunden).
gps.mi
Liefert die aktuelle Minute (als Teil der Uhrzeit in UTC). Wertebereich 0 bis 59.
gps.mo
Liefert die aktuelle Monatsnummer (bezogen auf UTC). Wertebereich 1 (Januar) bis 12 (Dezember).
gps.mjd
Liefert das aktuelle GPS-Datum als Integer-Wert im MJD-Format (Modifiziertes Julianisches Datum).
Das MJD ist zum Speichern und für Berechnungen besser geeignet als die Komponenten year, month, and day number.
Die Script-Sprache enthält eine Funktion zum Konvertieren von Jahr, Monat, Tag nach MJD, und die Umkehrfunktion (Zerlegen von MJD in Jahr, Monat, Tag).
Siehe auch: gps.unix_time (favorisiertes Format, liefert Datum und Uhrzeit im Unix-Format).
gps.nsat
Liefert die Anzahl der für den GPS-Empfänger momentan sichtbaren Satelliten. Wertebereich 0 bis 12 (bei sehr alten Empfängern maximal 8).
gps.pos
Ohne zusätzliche Argumente liefert diese Funktion eine Zeichenkette mit der aktuellen Position im Format Grad-Minuten-Sekunden, z.B.:
52°11'33.2"N 008°35'20.2"E
Dieses Format entspricht der bei vielen GPS-Geräten üblichen 'internationalen' Schreibweise, mit Breitengrad (latitude, N/S) vor dem Längengrad (longitude, E/W). Einige Empfänger zeigen nur Grade und (Bogen-)Minuten, aber keine (Bogen-)Sekunden. Für Berechnungen oder zum Aufzeichnen von GPS-Daten in numerischer Form verwenden Sie stattdessem besser die Funktionen gps.lat und gps.lon.
gps.pos( <latitude>, <longitude>)
Konvertiert eine Koordinate (mit Breiten- und Längengrad) in eine Zeichenkette, im oben beschriebenen Format. Aus Kompatibilitätsgründen erwartet diese Funktion Breiten- und Längengrad als Integer-Werte im internen Format (hunderstel Bogensekunden). Beispiel:
gps.pos(360000,360000)  liefert die Zeichenkette 01°00'00.0"N 001°00'00.0"E
gps.rstr
Ermöglicht den Zugruff auf die letzte vom seriellen Port empfangene Zeichenkette (rstr = received string; z.B. NMEA-Satz in ASCII). Diese Funktion diente primär zu Testzwecken (z.B. um festzustellen, ob und was ein GPS-Empfänger sendete, wenn keine Position decodiert werden konnte. Ein Empfänger könnte z.B. statt NMEA-0183-Daten Diagnosemeldungen senden).
Liefert diese Funktion nur unleserliches 'Kauderwelsch', überprüfen Sie die Baudrate des Empfängers.
gps.se
Liefert die aktuelle Sekunde (Teil der Uhrzeit in UTC). Wertebereich: 0 bis 59 (abgerundeter Integer).
gps.sec
Ähnlich wie gps.se (Sekunden der aktuellen Minute), das Ergebnis ist allerdings eine Fliesskommazahl im Bereich 0.0 bis 59.99 (Sekunden).
Bei GPS-Empfängern mit mehr als einer Positionsmeldung pro Sekunde (z.B. der "4-Hz-Maus") steht damit die volle Auflösung zur Verfügung.
gps.speed
Geschwindigkeit über Grund in km/h (die Geschwindigkeit aus NMEA-0183 in "Knoten" wird intern umgerechnet).
gps.time
Aktuelle Tageszeit (in UTC), gemessen in Sekunden ab Mitternacht, als Fliesskommazahl.
Bei Empfängern, die nur eine Positionsangabe pro Sekunde liefern, liefert diese Funktion immer eine ganze Zahl (volle Sekunde).
gps.tstr
Liefert die aktuelle Uhrzeit als Zeichenkette im Format hh:mm:ss .
gps.unix_time
Liefert eine Kombination aus GPS-Datum und -Uhrzeit als 'Unix-Zeit' (Anzahl seit dem 1. Januar 1970, 00:00:00 UTC verstrichener Sekunden).
Das Ergebis ist ein 64-Bit 'double precision'-Wert, der z.B. direkt mit der per system.unix_time auslesbaren Systemzeit verglichen werden kann um die Abweichung zwischen batteriegepufferter Echtzeituhr und der vom GPS-Empfänger gelieferten Zeit zu ermitteln.
gps.ustr
Liefert den letzten unerkannten String von der seriellen Schnittstelle, d.h. üblicherweise einen NMEA-Satz, den der Standard-NMEA-Parser nicht zuordnen konnte. (manche Empfänger senden Zeilen mit Schlüsselwörtern, die nicht in NMEA-0183 spezifiziert sind).
gps.yr
Liefert die aktuelle Jahreszahl vom GPS-Empfänger. Wertebereich 2000 ... 2099.

Verarbeitung von GPS-Daten per Script

Seit 2017 können Daten vom GPS-Empfänger auch direkt in der Script-Sprache verarbeitet werden. Die Syntax ist mit der im vorhergehenden Kapitel vorgestellten Befehlen (für den Display-Interpreter) kompatibel. Einige Script-spezifische Erweiterungen, z.B. das Auslesen von Längen- und Breitengrad als Fliesskommawerte mit 'doppelter Präzision' (64 Bit) werden in diesem Kapitel anhand einfacher Beispiele vorgestellt.


Verwendung des 'OnLocationChanged'-Handlers als GPS/CAN-Gateway

Um in der Applikation sehr schnell auf 'neue' GPS-Daten zu reagieren (ohne 'Polling'), kann im Script eine parameterlose Prozedur namens 'OnLocationChanged' definiert werden. Ist diese vorhanden, wird sie jedesmal vom System aufgerufen, wenn ein kompletter Block von NMEA-Sätzen (i.A. "$GPRMC" oder / und "$GPGGA") von der seriellen Schnittstelle empfangen wurde. Beim Aufruf liegen dann bereits die aktuellen Daten vor, und können wie im folgenden Beispiel aus dem Funktionsblock 'gps' ausgelesen werden.

Abhängig vom verwendeten GPS-Empfänger (und dessen Konfiguration) wird 'OnLocationChanged' ein bis zehn mal pro Sekunde aufgerufen; bei speziellen GPS-Empfängern noch häufiger.
Der folgende Ausschnitt des Scripts aus programs/GPS_test.cvt demonstriert zwei Möglichkeiten, um Daten vom GPS-Empfänger auf dem CAN-Bus auszugeben:
proc OnLocationChanged() // Handler wird bei jeder neuen GPS-Position aufgerufen
  local tCANmsg msg;

   // 'Fest verdrahtetes' Senden von GPS-Data per CAN-Bus:
   msg.id   := 0x501;   // CAN message id for 1st part of the GPS data
   msg.len  := 8;       // data length code (number of data bytes) 
   msg.f64[0] := gps.lon_d; // longitude in degrees as 64-bit 'double'
   can_transmit( msg ); // send CAN message

   msg.id   := 0x502;   // CAN message id for 2nd part of the GPS data
   msg.len  := 8;       // data length code (number of data bytes) 
   msg.f64[0] := gps.lat_d; // latitude in degrees as 64-bit 'double'
   can_transmit( msg ); // send CAN message

   msg.id   := 0x503;   // CAN message id for 3rd part of the GPS data
   msg.len  := 8;       // data length code (number of data bytes) 
   msg.f64[0] := gps.unix_time; // seconds since 1970-01-01 00:00:00.0 UTC
   can_transmit( msg ); // send CAN message

   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   // Alternative: GPS-Daten in *Display-Variable* kopieren (s.U.).
   // Den Rest (Senden per CAN) erledigt die Firmware, wenn die ent-
   // sprechenden Variablen durch Import einer CAN-Datenbank (*.dbc)
   // als *zu sendendende CAN-Signale* konfiguriert wurden.
   // (Quelldatei : programs/GPS_to_CAN.dbc) .
   // Variablen mit einem Sendeintervall ("Update Time") von NULL
   // werden 'ereignisgesteuert' gesendet, d.h. immer dann, wenn sich
   // bei der folgenden Zuweisung *der Wert* geändert hat.
   // Dadurch wird das CAN-Sende-Intervall durch die Frequenz der
   // '$GPRMC'- oder '$GPGGA'-Sätze vom GPS-Empfänger bestimmt.
   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   display.GpsLat  := gps.lat_d;  // Breitengrad (°)
   display.GpsLon  := gps.lon_d;  // Längengrad (°)
   display.GpsTime := gps.time;   // Anzahl Sekunden seit Mitternacht
   display.GpsDate := gps.mjd - 40587; // Anzahl TAGE seit UNIX-Epoche (1. Januar 1970)
   display.GpsSpeed := gps.speed; // Geschwindigkeit in km/h (!)
   display.GpsHeight := gps.hasl; // Höhe über Meeresspiegel (m)
   display.GpsUnixSeconds := gps.unix_time + 0.0001; // 64-bit 'double',
       // plus 0.1 Millisekunde zum Testen der *Auflösung* des CAN-Signals

endproc; // OnLocationChanged

Überprüfen des Empfängers mit dem GPS-Test im MKT-View

Die hier beschriebene Funktion ist kein Ersatz für eine 'hübsche' GPS-Koordinaten-Anzeige. Sie dient nur für einen 'schnellen' Test des GPS-Empfängers, ohne dass eine spezielle Test-Applikation in das programmierbare Gerät geladen werden muss.

Der GPS-Test wird wie unten gezeigt über das 'System-Menü' aufgerufen. Sollte der Empfänger nicht bereits vorher (per Setup oder Applikation) gestartet worden sein, oder die falsche Baudrate / das falsche Protokoll eingestellt sein, rufen Sie die passende Initialisierung im unten abgebildeten Testmenü aus. Die aktuelle Position (mit Längen- und Breitengrad in Grad, Minuten, Sekunden), Datum und Uhrzeit in UTC (=GPS-Zeit), Geschwindigkeit in km/h, Höhe über Meeresspiegel in Metern, Anzahl momentan sichtbarer Satelliten, Signalqualität und HDOP (Horizontal Dilution Of Precision, bedeutet ungefähr "Verringerung der Genauigkeit") werden auf dem Bildschirm angezeigt:
 Main system menu (9)
 EXIT !
 Load program from FILE
 Transfer via CAN = OFF/Auto
 Other transfers ... ▶
 Audio Recorder
 CAN snooper mode
 CAN logger config
 User Settings
 System Setup / Unlock
 System Test  GPS Receiver 
 Network Setup
 Diagnostics
 General Settings
 ...
 GPS Receiver Test
 F1 : Init receiver for 9k6, NMEA .
 F2 : Init receiver for "4-Hz"-mouse .
 F3 : Quit

 GPS baudrate = 38400
 Protocol = 1   (NMEA)

 GPS decoder output :
 SampleIdx = 12345         ← Anzahl empfangener NMEA-Sätze
 Pos = 52°11'33.1"N 008°35'20.0E
 UTC = 2016-11-07 17:00:00
 Speed= 0.3km/h Height= 80.5m(ASL)
 Qual=2 NSats=11 HDOP= 0.9 ← Qualität, Anzahl Satelliten,..
 Rx= $GPGGA, .....         ← zuletzt empfangener NMEA-Satz

(Integrierter GPS-Empfänger-Test, hier im MKT-View IV)


Ein ähnlicher Test kann auch in Ihre Applikation integriert werden. Ein Beispiel dazu finden Sie im Anhang .

Tipp: Der GPS-Empfänger kann zu Testzwecken auch an den PC angeschlossen werden. Der im Programmiertool enthaltene Firmware-Simulator übernimmt dann das Decodieren der NMEA-Sätze. Ferner können die NMEA-Sätze im "Rohformat" ($GPRMC, $GPGGA, ..) im Programmiertool auf der Registerkarte 'Fehler und Meldungen' angezeigt werden. Setzen Sie dazu den Haken vor der Option 'Meldungen aktivieren von ...' / 'Andere Protokolle'.


Anhang

Internes Format für Breiten- und Längengrad

Einge der oben aufgelisteten Interpreter-Funktionen liefern den aktuellen Breiten- und Längengrad als 32-Bit-Integer-Wert (kein Fliesskomma). Die Einheit ist eine hundertstel Bogensekunde (1/100 arc seconds) (*). Dabei sind..

Um die aktuelle Position in diesem Format zu lesen verwenden Sie die Funktion gps.lat (latitude, Breitengrad) bzw. gps.lon (longitude, Längengrad). .

(*) Dies ist die Auflösung, nicht die Genauigkeit: 0.01 Bogensekunden entsprechen einer räumlichen Auflösung von etwa 30 cm auf der Erdoberfläche, was weit jenseits der Genauigkeit von handelsüblichen GPS-Empfängern (ohne DGPS) liegt.


Beispielapplikation mit GPS / NMEA - Anzeige

Nach der Installation des Programmiertools finden Sie in der Applikation programs/GPS_test.cvt ein Beispiel zur Anzeige von GPS-Daten auf einer programmierbaren Anzeigeseite.

screenshot GPS / NMEA Decoder Test

Auf der oben gezeigten Seite der Beispiel-Applikation werden die wichtigsten 'Messwerte' (vom GPS-Empfänger), und zusätzlich die Konfigration des NMEA-Decoders angezeigt. Der GPS-Empfänger befand sich dabei auf der Fensterbank innerhalb eines Gebäudes.


Die Funktion "gps.rbuf" lieferte in diesem Beispiel noch keinen kompletten NMEA-Satz. Dies ist kein Fehler sondern der Zweck dieser Funktion: Sie liefert den aktuellen Inhalt des Empfangspuffers (als Zeichenkette), auch bevor der "Satz" (hier: $GPGGA) komplett empfangen wurde. Der letzte komplett empfangene NMEA-Satz wird per "gps.rstr" abgefragt.


Die GPS-Konfigurationsparameter (Baudrate und Protokoll) wurden in diesem speziellen Beispiel im 'page-enter'-Event eingestellt, so dass diese unabhängig von den Einstellungen im System-Setup sind.



Neben der Anzeige der aktuellen GPS-Daten sendet die Beispielapplikation auch einige GPS-Daten per CAN-Bus. Die Daten (Position, Uhrzeit, Datum, Geschwindigkeit, Höhe) können von allen CAN-Knoten empfangen und angezeigt oder weiterverarbeitet werden, z.B. mit der Applikation programs/GPS_from_CAN.cvt (ebenfalls im Installationsarchiv enthalten).
Die Telegrammstruktur ist wie üblich in einer Datenbank für CAN definiert (programs/GPS_to_CAN.dbc). Die selbstdefinierten Signale (GpsLat, GpsLon, GpsTime, GpsDate, GpsSpeed, GpsHeight) wurden in der Applikation GPS_test.cvt als zu sendende Signale aus der Datenbank importiert; in der Applikation GPS_from_CAN.cvt werden die gleichnamigen Signale empfangen.
Details zum Senden von Signalen, die in einer CAN-Datenbank (*.dbc) definiert sind, finden Sie hier.
Die Struktur der von diesem 'GPS→CAN-Gateway' gesendeten Telegramme kann selbstverständlich für eigene Anwendungen geändert oder erweitert werden. Wir empfehlen dazu einen geeigneten DBC-Editor, z.B. von Kvaser (Kvaser Database Editor).


Datei: ..?..\uptwin1\help\gpsdec_49.htm
Autor: W.Büscher, MKT Systemtechnik
Stand: 2017-08-15 (ISO8601, YYYY-MM-DD)

zurück zum Seitenanfang