Establishing a GPS connection under Linux

From Thomas-Krenn-Wiki
Jump to navigation Jump to search

In this example, we show you how to configure a GPS connection under Ubuntu 22.04.4 server on the command line directly. In the test, we use the mini industrial server system UNO127 with an installed Quectel EM05-E M.2 modem.

In the following, we provide a code that reads out the GPS information and processes them in an easier way.

Test environment

The following components were used for the testing of the GPS connection:

  • small
    industrial solution UNO 127
    • BIOS Build version: U1270000060x007/08-01-23/9:28:16
  • Quectel EM05-E Modem
    • GPS Connector (G) connected
    • GPS Antenne passive / 1575.42 Mhz
    • Firmware version: EM05EFAR06A05M4G
  • Ubuntu 22.04.4 LTS
  • The test was carried out outside in a flying setup with a direct view of the sky. The LTE antenna feeds were removed for the photo. (better visibility of the connected GPS connector)
Important: Never operate the radio modules without antennas! The operation without antenna can damage your hardware.

Recognition of card under Linux

With the following code, you can request the state of the Quectel Modem card via usb-devices:

GPS Connector (G) internal connection

rahmenlos

Setting of GPS mode

You can use the socat tool to query, activate or activate and verify the GPS mode:

echo 'AT+QGPS?' | socat - /dev/ttyUSB3,crnl
echo 'AT+QGPS=1' | socat - /dev/ttyUSB3,crnl
echo 'AT+QGPS?' | socat - /dev/ttyUSB3,crnl
  • Here, every action on the part of the modem should be acknowledged with an OK.

GPS Aktivierung auf EM-05E Quectel Card

The value +QGPS: must be set as the value, then GPS is active and operational.

Verification of NMEA sentences

Please use the following link for the verification of the arrival of NMEA sentences (GPS data). For this, a passive GPS antenna must be used.

echo 'AT+QGPSLOC=0' | socat - /dev/ttyUSB3,crnl
 GPS Location NMEA extract  

Now, you can export the data in the desired format (here: Recommended minimum specific GNSS Data, briefly: RMC).

Time stamps and coordinates are then output at this point.

echo 'AT+QGPSGNMEA="RMC"' | socat - /dev/ttyUSB1,crnl

Verification of GPS configuration and code-sided process

To process data, they need to be translated correctly.

In the following, there is a data set as example:

$GPGGA,061015.00,4849.7360,N,01332.9844,E,1,03,1.0,332.0,M,0.0,M,,*6B

The data set is composed of the following parts:

  • $GPGGA: This is the message type, which states that it is about a GPS Fix data message.
  • Zeit: 061015.00: The time of Fix in UTC (Coordinated Universal Time).
  • 4849.7360,N: The latitude coordinate. In this case 48°49.7360' north.
  • 01332.9844,E: A longitude coordinate. In this case 13°32.9844' east.
  • 1: GPS-quality indicator: 0: no GPS-Fix GPS-Fix (SPS - Standard Positioning Service)
  • 03: number of used satelites for the calculation of the position
  • 1.0: horizontal Dilution of Precision (HDOP). A measure for the accuracy of the horizontal position.
  • 332.0,M: height over the sea level in meters.
  • 0.0,M: height of the Geoid reference over the WGS84 ellipsoid in meters.
  • (leer): age of the DGPS data(Differential GPS), in this case not stated.
  • *6B: check sum, which is used for the integrity check of the message.

Scriptcode/bash

The following steps are compiled in a short code-snippet.

Important: To execute the code, socat must be installed as package

The execution of odes has the following effect:

  • A log file with the converted log file gpslog.txt is created
  • A link is created with which the locations are displayed under Google Maps
#!/bin/bash
### This code reads GPS data at intervals of every 5 seconds
### directly via modem / EM05E via USB converts it to
### suitable format (decimal degree)
### Generates processed data / GoogleLink / Log file for the validation of GPS data  
### by TK 2024 / wseifert

# Function for extracting and processing GPS-LOC data
process_gpsloc_data() {
    while read -r line; do
        if [[ $line == +QGPSLOC:* ]]; then
            # extract data set +QGPSLOC for processing 
            GPSLOC_LINE=$(echo "$line" | cut -d ' ' -f 2-)

            # extract data field 
            IFS=',' read -r -a ADDR <<< "$GPSLOC_LINE"
            TIME="${ADDR[0]}"
            LAT="${ADDR[1]}"
            LON="${ADDR[2]}"
            HDOP="${ADDR[3]}"
            ALT="${ADDR[4]}"
            SATS="${ADDR[5]}"
            SPEED="${ADDR[6]}"
            COURSE="${ADDR[7]}"
            DATE="${ADDR[9]}"

            # Convert latitude and longitude to decimal degrees
            LAT_DEG=$(echo "${LAT:0:2}")
            LAT_MIN=$(echo "${LAT:2}")
            LAT_DEC=$(echo "$LAT_DEG + ($LAT_MIN / 60)" | bc -l)
            if [[ "${LAT: -1}" == "S" ]]; then LAT_DEC=$(echo "-$LAT_DEC" | bc); fi

            LON_DEG=$(echo "${LON:0:3}")
            LON_MIN=$(echo "${LON:3}")
            LON_DEC=$(echo "$LON_DEG + ($LON_MIN / 60)" | bc -l)
            if [[ "${LON: -1}" == "W" ]]; then LON_DEC=$(echo "-$LON_DEC" | bc); fi

            # Output original response of the interface
              echo "Original response of the interface: $line"

            # Show breakdown of fields
            echo "breakdown of fields:"
            echo "  - Time: $TIME"
            echo "  - Latitude: $LAT_DEG° $LAT_MIN'"
            echo "  - Longitude: $LON_DEG° $LON_MIN'"
            echo "  - HDOP: $HDOP"
            echo "  - Altitude: $ALT m"
            echo "  - Satellites: $SATS"
            echo "  - Speed: $SPEED km/h"
            echo "  - Course: $COURSE°"
            echo "  - Date: $DATE"

            # create Google Maps link
            GOOGLE_MAPS_LINK="https://www.google.com/maps?q=$LAT_DEC,$LON_DEC"

            # issue Google Maps link
            echo "Google Maps link: $GOOGLE_MAPS_LINK"

            # create data field for further process 
            DATA_FIELD="$TIME,$LAT_DEG,$LAT_MIN,$LON_DEG,$LON_MIN,$HDOP,$ALT,$SATS,$SPEED,$COURSE,$DATE"
            
            # create or attach log file or atLogdatei and write data field 
            echo "$DATA_FIELD" >> gpslog.txt

            # issue data field 
            echo "Datenfeld: $DATA_FIELD"
        fi
    done
}

# main program: send AT-command and process answer 
echo 'AT+QGPSLOC=0' | socat - /dev/ttyUSB3,crnl | process_gpsloc_data


Here is the code in action:

Troubleshooting / FAQ

The following mistakes are known so far:

CME Error

Description

The card reports a CME error.

Cause

  • a GPS module is not available
  • a GPS module is not active
  • no fix can be established with a satellite

Solution

  • restart the Quectel Modem: echo 'AT+cfun=1,1 | socat - /dev/ttyUSB3,crnl
  • for a connection in 2D (length and width), three satelites with visual connection are needed for a fix. This can take several minutes.
    • For 3D (longitude, latitude and altitude), 4 satellites with line of sight are required and takes correspondingly longer
  • Find out the firmware version of the modem card: echo 'AT+CGMR' | socat - /dev/ttyUSB3,crnl


Author: Wilfried Seifert

Wilfried Seifert, working in the Systems Engineering department at Thomas-Krenn, is responsible for system/prototype development in his work area. LPIC 3 certified, deals with construction / programming of embedded / GPIO systems; in his spare time he likes to repair old home computers, attends Linux conferences or is on the road with his bike (MTB) for sporting compensation.


Translator: Alina Ranzinger

Alina has been working at Thomas-Krenn.AG since 2024. After her training as multilingual business assistant, she got her job as assistant of the Product Management and is responsible for the translation of texts and for the organisation of the department.