Decoder for GPS Data in NMEA-0183 format

(only available for certain terminals with a sutable serial aynchronous interface, and a special firmware)

This document describes how the terminal's asynchronous serial interface can be used to receive position data from an external GPS receiver. Inside the terminal, the received (and decoded) data can be accessed through the interpreter.

Note: Only a few terminals support this optional function - see Feature Matrix : "GPS decoder" !
This feature must be unlocked (by the manufacturer, or via password) before using it .

Contents

  1. Interfacing a GPS receiver ('mouse') on various MKT-Views
  2. Overview of interpreter functions and -procedures for the GPS decoder
    Interpreter functions to retrieve the GPS position, altitude, date, time, speed, quality, number of satellites, ...
  3. Processing GPS data via script
    1. GPS/CAN-gateway using the 'OnLocationChanged'-handler
  4. Testing the GPS receiver with the terminal's built-in GPS test function
    Appendix: Internal storage format for latitude and longitude, sample application, conflicts when downloading through the serial port

See also:

Note: The GPS/NMEA decoder inside the terminal is an optional feature, which must be unlocked to use it. You can use this function for testing purposes (before paying for it) in "evaluation mode". In evaluation mode, the position returned by the NMEA decoder will jump around the true position by a few hundred meters. This is not a bug, but a motivation to contact the manufacturer to have this feature unlocked. The general feature unlocking procedure is described here.

In the simulator (i.e. in the programming tool), NMEA strings received from a serial port is always possible. Connect a suitable GPS mouse (which sends NMEA strings) to your PC, and select its COM port number on the programming tool's Settings tab. After issuing the command gps.prot="NMEA", the programming tool 'connects' the serial port to the GPS decoder, and you can process the GPS data in the simulator just as on the target device. A simple adapter between GPS-mouse and the PC's serial port may be required, because a standard RS-232 port doesn't have the necessary 5- or 12-Volt supply for the receiver.

Interfacing a GPS receiver on various MKT-Views

Depending on the hardware type (MKT-View II / III / IV), different connectors for the GPS port were used.


Figure 1 : GPS connector on the right side of an MKT-View IV

All of the above 'GPS connectors' contain a voltage supply for the external GPS receiver.
Thus these connectors cannot be compatible with a standard RS-232 cable !
For details and the pin assignment, refer to the decive specific data sheet.
Some datasheets can be found on the 'MKT-CD' (which is available on-line now).

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

Overview of interpreter functions for the GPS / NMEA interface

Note: The following commands for the GPS receiver are not necessary for normal application.
For normal use, you only configure the GPS receiver once in the display's 'Setup' menu, item "GPS Rcv Type". The following choices should be sufficient for all but the 'most exotic' GPS receiver types: With the commands listed in the following chapters, your display application can override the settings from the System Setup menu.

Configuration of the serial interface (baudrate)

gps.baud
get or set the baudrate for the serial port, when "occupied" by the external GPS receiver. Unit is bit per second. Allowed values are 1200, 2400, 4800, 9600, 19200, and sometimes 38400 (bit/second). Caution, some targets don't support 38400 bit/sec. Example:
@gps.baud=4800
sets the baudrate of the serial port to 4800 bit/sec (this is what most GPS receivers use by default).
gps.prot
selects the protocol used for the serial port. The parameter is a double-quoted string with the following meaning:
"OFF" = no characters are received or sent (from the application's point of view, the serial port is "unused"). This is the default state, for reasons explained here.
"NMEA" = data are transmittes as TEXT LINES, as explained in the NMEA-0183 protocol specification.
gps.cfg
starts a special configuration which is specific to certain GPS receivers (like the "4-Hz-GPS-Mouse" or the "10-Hz-GPS-Mouse"). Do not use this command if you connect a generic GPS receiver which only supports the standard NMEA-0183 protocol !
To change the GPS receiver configuration, use a formal assignment like gps.cfg=4 (to initialize a certain 4-Hz-GPS-mouse).

Reception

gps.da
returns the current day-of-month (in UTC) from the GPS receiver as an integer number .  
See also: gps.yr, gps.mo, gps.da, gps.hr, gps.mi, gps.se . All these functions use UTC (universal time coordinated), almost the same as Greenwich Mean Time (GMT).
gps.dstr
returns the current date from the GPS receiver as a string, format YYYY-MM-DD (ISO8601, no country-specific stuff) .
gps.hasl
returns the current height above sea level in meters.
gps.hdop
returns the current 'HDOP'-value from the GPS receiver. HDOP means horizontal dilution of precision, so the larger this value, the worse the accuracy of the horizontal position. Values below 4 are commonly accepted as "good", values above 8 are "bad". Note: This is a dimensionless value, not 'meters' !
gps.hr
returns the current hour (in UTC) from the GPS receiver, ranging from 0 to 23.
See also: gps.tstr which returns the time formatted into a string.
gps.lat_d
returns the current latitude as a floating point value in degrees.
In the script language, the result is a double-precision (64 bit) floating point value.
gps.lat
returns the current latitude in the internal format (1/100 arc seconds), as a 32-bit integer number. Good for logging and calculations. For display purposes, use gps.pos instead.
gps.lon_d
returns the current longitude as a floating point value in degrees.
In the script language, the result is a double-precision (64 bit) floating point value.
gps.lon
returns the current longitude in the internal format (1/100 arc seconds), as a 32-bit integer number.
gps.mi
returns the current minute (in UTC) from the GPS receiver, ranging from 0 to 59
gps.mo
returns the current month-of-year (in UTC) from the GPS receiver, range 1 (January) to 12 (December).
gps.mjd
Returns the calendar date from the GPS receiver as MJD (Modified Julian Date).
The MJD is more efficient for storage and computation than year, month, and day number in separate fields.
The script language has functions to convert from and to MJD.
See also: gps.unix_time (preferred format, returns date and time as 'Unix seconds').
gps.nsat
returns the number of satellites currently "in view" to the GPS receiver, usually ranging from 0 to 12 (or 8 for some very old receivers).
gps.pos
Without parameters, returns the current position as a string, in the degree-minute-seconds format, like:
52°11'33.2"N 008°35'20.2"E
Note: This seemed to be the more common, 'international' notation, with the latitude (N/S) before the longitude (E/W). Some new receivers show degrees and minutes only, but no arc seconds. For calculations, or for logging of the current position in numeric forn, use gps.lat and gps.lon instead. 
gps.pos( <latitude>, <longitude>)
Converts a coordinate into a string, with the format as above. Here, latitude and longitude are given in the internal format. Example:
gps.pos(360000,360000)  will return 01°00'00.0"N 001°00'00.0"E
gps.rstr
retrieves the last received string (data set in ASCII) received from the serial port. Used for troubleshooting, to check if the GPS sends anything at all, and to see what the receiver sends in raw form (it may send something else, which is not NMEA-0183). If this function only returns garbled characters, check the baudrate.
gps.se
returns the current second (in UTC) from the GPS receiver, ranging from 0 to 59
gps.sec
Similar as gps.se (seconds into the current minute), but the result is a floating point value ranging from 0.0 to 59.99 (seconds).
Only makes a real difference for GPS receivers with more than one position reports per second, like the "4-Hz GPS mouse".
gps.speed
returns the speed over ground in km/h (not "knots" as in the NMEA sentences).
gps.time
returns the current time from the GPS receiver in seconds since midnight, as a floating-point number
gps.tstr
returns the current time from the GPS receiver as a string, format hh:mm:ss .
gps.unix_time
Returns a combination of GPS-date und -time, measured in 'Unix Seconds' (seconds elapsed since January 1st, 1970, 00:00:00 UTC; possibly fractional).
The result is a 64-bit 'double precision'-floating point value, which can be compared directly with the system time (system.unix_time) to check the difference between GPS and internal clock (battery backed-up RTC).
gps.ustr
retrieves the last unrecognized string received from the serial port. Mainly used for troubleshooting, to check if your GPS sends something which cannot be handled by the NMEA parser (the receiver may send something else, which is not NMEA-0183).
gps.yr
returns the current year from the GPS receiver, range 2000 ... 2099.

Processing GPS data via script

Since 2017, data received from the GPS can also be processed directly in the application's Script. The syntax is the same as explained in the previous chapter (for the older display interpreter). Script-specific extensions like latitude, longitude, and Unix time as floating point values with double precision (64 bit) will be explained with a few examples in this chapter.


GPS/CAN-gateway using the 'OnLocationChanged'-handler

To process 'new' GPS data in the application very quickly (without 'polling'), your script may contain a parameter-less procedure named 'OnLocationChanged'. In that case, this procedure (handler) will be called immediately whenever a new block of GPS data has been received (usually consisting of "$GPRMC" and "$GPGGA"). Whenever the handler is called, the new current data (decoded from NMEA) can be read from the 'gps' function block.

Depending on the GPS receiver (and its configuration), this will happen once, four, or ten times per second; for special receivers even faster.

The following script was taken from the demo application in programs/GPS_test.cvt. It passes the data from the GPS receiver on to the CAN-bus, using two different principles:
proc OnLocationChanged() // Called whenever the GPS has reported a new location
  local tCANmsg msg;

   // 'hard-wired' transmission of GPS data to the 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: Copy GPS data into *display variables* (below)
   // and let the system (firmware) do the rest, i.e. map to CAN.
   // Those signals have been declared as 'transmit signals' when
   // importing the CAN database (*.dbc) in the programming tool.
   // (source : programs/GPS_to_CAN.dbc) .
   // If the variable's "update time" (transmit interval) is set
   // to ZERO (on the variable definition tab), the CAN message
   // will be sent 'event-driven' by the firmware, e.g. "if a value
   // was modified". Thus, the CAN messages with the following
   // display variables will be transmitted at the same rate as the
   // GPS receiver emits '$GPRMC' or '$GPGGA' sentences.
   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   display.GpsLat  := gps.lat_d;  // latitude in degrees
   display.GpsLon  := gps.lon_d;  // longitude in degrees
   display.GpsTime := gps.time;   // number of seconds since midnight
   display.GpsDate := gps.mjd - 40587; // number of DAYS since Unix was born
   display.GpsSpeed := gps.speed; // speed in km/h (!)
   display.GpsHeight := gps.hasl; // height above sea level in meters
   display.GpsUnixSeconds := gps.unix_time + 0.0001; // 64-bit 'double',
       // with 0.1 milliseconds added to check resolution of the CAN signal

endproc; // OnLocationChanged

Testing the receiver with the terminal's built-in GPS test function

Note: This is NOT a replacement for a nice graphic GPS display. It was designed for a quick test of the GPS receiver, without having to load a special test application into the terminal.

To start the GPS test, enter the terminal's system menu, then select "System Test" ... "GPS Receiver". If the receiver is not initialized yet (by the application), select the init function from the test menu. The current position (lat + lon in degrees, minutes, seconds), date+time in UTC, speed in km/h, height above sea level in meters, number of satellites in view, and the HDOP value will be displayed on the screen:
 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         ← number of NMEA frames received
 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 ← quality, number of satellites,..
 Rx= $GPGGA, .....         ← last received NMEA sentence

(Built-in GPS receiver test, here in an MKT-View IV)


A more comprehensive GPS test can be performed with the GPS sample application - see appendix .

Hint: For testing, you can also connect the GPS receiver directly to the PC. The programming tool emulates the entire device firmware, including the parser for NMEA sentences. Furthermore, the raw NMEA sentences ($GPRMC, $GPGGA, ..) can be displayed on the programming tool's 'Errors & Messages' tab (if the port is assigned to GPS, i.e. after setting gps.prot="NMEA"). To show the raw NMEA sentences, check 'Enable messages from ...' / 'Other protocols'.


Appendix

Internal format for GPS Latitude and Longitude

Some of the GPS-related interpreter functions use latitude and longitude in the internal format, which uses 32-bit integer values (no floating point!). The unit for lat+lon is one hundredth of an arcsecond (*). Furthermore,

To retrieve the present coordinate in this format, use the functions gps.lat and gps.lon .

(*) Note on resolution vs accuracy: 0.01 arc seconds correspond with a spatial resolution of about 30 cm on the earth's surface, which exceeds the accuracy of most civilian GPS receivers.


Sample application for the GPS / NMEA decoder

There is a small test file for the MKT-View which demonstrates some of the NMEA-decoder functions. You can load it from \programs\GPS_test.cvt .

screenshot GPS / NMEA Decoder Test

On this screen of the test application, the most important interpreter functions for the GPS / NMEA0183 decoder are displayed, along with the results when testing the decoder with a GPS receiver in front of the author's office window.

Note that the "gps.rbuf" does not contain a complete NMEA sentence in this screenshot yet. This is not an error - it's the purpose of the "gps.rbuf"-function : Take a look at the received characters before the sentence is complete. The last completely received NMEA sentence is displayed by "gps.rstr".

The GPS receiver parameters (baudrate and protocol) are set in the display page's "page-enter"-event, so they will be executed once when the display page is invoked. In a real-world application, you should do this on page zero of your display application.





Besides displaying the current GPS data, the demo application (gps_test.cvt) also sends some data via CAN-Bus (position, time of day, date, GPS speed, height above sea level). Other CAN-nodes may receive and display/log/process those data, as shown in application programs/GPS_from_CAN.cvt (also contained in the installation archive).
As usual, the message structure is defined in a database for CAN (programs/GPS_to_CAN.dbc). The self-defined GPS data signals on CAN (GpsLat, GpsLon, GpsTime, GpsDate, GpsSpeed, GpsHeight) were imported into gps_test.cvt and declared as transmit-signals; in gps_from_CAN.cvt the same signals were imported as receive-signals.
Details about sending signals defined in a database for CAN (*.dbc) can be found here.
Of course, the structure of the messages sent by this 'GPS→CAN-Gateway' can be tailored for your own needs. We suggest to use a DBC editor for this purpose, for example Kvaser's (Kvaser Database Editor).


Notes on conflicting usage of the serial interface

Originally, the serial port was exclusively used to download the terminal application ("user program") through the PC's RS-232 interface. Since the serial port may now be occupied by the GPS receiver, the terminal cannot (always) listen for commands from the PC. Why ?

The program download between PC and Terminal uses a block-oriented protocol for the serial port called "3964R". When you select "Send application to the terminal through the serial port", but the serial port is occupied by the application (as described in this document), the 3964R-handler may be passive to avoid interference with the protocol which your terminal-application uses (through appropriate interpreter commands). The PC will therefore never receive the expected response from the terminal .... and your terminal application will, at least, be "irritated" by the characters received from the serial port.

So what to do in this case, when your application occupies the terminal's serial port, but you want to download a new application through just this port ? The solution is:

The terminal will reprogram the serial port for communication with the PC in this case, which includes the initialisation of the 3964R-protocol.

If the serial port is not occupied by the terminal-application or the GPS-decoder (which is the default, see gps.prot), you don't necessarily have to use the system menu to activate the download.

Related subject: Command gps.prot="NMEA" to 'occupy' the serial port for the GPS receiver


File: ..?..\uptwin1\help\gpsdec_01.htm
Author: W.Büscher, MKT Systemtechnik
Last modified: 2017-08-15 (ISO8601, YYYY-MM-DD)

back to top