Skip to main content

GNSS (GPS) on Tachyon

The Particle Tachyon leverages the Qualcomm QCM6490 chipset, which includes integrated GNSS (GPS). This provides globally compatible location based services.


Antenna Configuration

Connect the Particle GNSS Antenna PARANTGN1 to the u.FL connector marked "GNSS".

More details on how to attach and mount your GNSS antenna can be on the Particle GNSS FPC Antenna page.

Tachyon GNSS (GPS) Antenna

Query GNSS Location

Use the command particle-tachyon-ril-ctl gnss to get the current location information. Returns a dictionary of key: <value> pairs.

Note: It may require a little time initially to acquire a satellite fix before location info is available. Make sure the GNSS antenna is attached, and up against a window (better yet outside with full view of the sky)

Example output

particle-tachyon-ril-ctl gnss
valid: 1
last_lock_time_ms: 971
svnum: 10
beidou_svnum: 5
nshemi: N
ewhemi: W
latitude: 44.332211
longitude: -88.776655
gpssta: 1
posslnum: 8
fixmode: 2
pdop: 1.200000
hdop: 1.000000
vdop: 0.800000
altitude: 123.400000
speed: 0.000000
utc: 2025/06/19 20:14:15
slmsg[0]: 2,13,320,24
slmsg[1]: 8,9,291,15
slmsg[2]: 10,69,334,31
slmsg[3]: 15,6,68,18
slmsg[4]: 18,23,167,28
slmsg[5]: 23,55,94,26
slmsg[6]: 24,38,57,28
slmsg[7]: 27,10,257,30
slmsg[8]: 28,13,195,25
slmsg[9]: 32,54,260,26
slmsg[10]: 0,0,0,0
slmsg[11]: 0,0,0,0
beidou_slmsg[0]: 78,17,35,22
beidou_slmsg[1]: 80,11,141,26
beidou_slmsg[2]: 79,29,89,19
beidou_slmsg[3]: 69,46,38,23
beidou_slmsg[4]: 85,51,278,15
beidou_slmsg[5]: 0,0,0,0
beidou_slmsg[6]: 0,0,0,0
beidou_slmsg[7]: 0,0,0,0
beidou_slmsg[8]: 0,0,0,0
beidou_slmsg[9]: 0,0,0,0
beidou_slmsg[10]: 0,0,0,0
beidou_slmsg[11]: 0,0,0,0
possl[0]: 10
possl[1]: 15
possl[2]: 18
possl[3]: 23
possl[4]: 24
possl[5]: 27
possl[6]: 28
possl[7]: 32
possl[8]: 0
possl[9]: 0
possl[10]: 0
possl[11]: 0

Key description

  • int32_t valid 1 = at least one update; 0 = no updates yet
  • uint64_t last_lock_time_ms Milliseconds since last location update (latitude/longitude) or fixmode/gpssta value change
  • uint8_t svnum Number of visible GPS satellites
  • uint8_t beidou_svnum Number of visible BeiDou or GLONASS satellites
  • char nshemi Hemisphere (North/South): 'N' = North, 'S' = South
  • char ewhemi Hemisphere (East/West): 'E' = East, 'W' = West
  • double latitude Latitude (already signed based on nshemi, -S, +N)
  • double longitude Longitude (already signed based on ewhemi, -W, +E)
  • uint8_t gpssta GPS status: 0 = No fix; 1 = Non-differential fix; 2 = Differential fix; 6 = Estimated
  • uint8_t posslnum Number of GPS satellites used for positioning (0–12)
  • uint8_t fixmode Fix type: 1 = No fix; 2 = 2D fix; 3 = 3D fix
  • double pdop Position dilution of precision (PDOP), (0.0–50.0)
  • double hdop Horizontal dilution of precision (HDOP), (0.0–50.0)
  • double vdop Vertical dilution of precision (VDOP), (0.0–50.0)
  • double altitude Altitude, value in 0.1 meters
  • double speed Ground speed, value in 0.001 km/h
  • nmea_utc_time utc UTC time and date: .year, .month, .date, .hour, .min, .sec
  • nmea_satellitemsg slmsg[12] Array of GPS satellite data [0-11]
  • beidou_nmea_satellitemsg beidou_slmsg[12] Array of BeiDou/GLONASS satellite data [0-11]
  • uint8_t possl[12] Array of satellite IDs used for positioning [0-11]

Structs

typedef struct
{
char num; // Satellite number
char eledeg; // Elevation angle of the satellite
int azideg; // Azimuth angle of the satellite
char sn; // Signal-to-noise ratio (SNR)
} nmea_satellitemsg;

typedef struct
{
char beidou_num; // Satellite number
char beidou_eledeg; // Elevation angle of the satellite
int beidou_azideg; // Azimuth angle of the satellite
char beidou_sn; // Signal-to-noise ratio (SNR)
} beidou_nmea_satellitemsg;

typedef struct
{
int year; // Year
char month; // Month
char date; // Day
char hour; // Hour
char min; // Minute
char sec; // Second
} nmea_utc_time;

Example Script

Here's a simple script that captures the latitude, longitude, speed, and last_lock_time_ms every 1 second, and logs that data with a timestamp to the terminal and a log file.

loc.sh

#!/usr/bin/env bash

capture_location_info() {
while [ 1 ]; do
gnss=$(./build/ctl/particle-tachyon-ril-ctl gnss)
lat=$(echo "$gnss" | grep latitude)
lon=$(echo "$gnss" | grep longitude)
speed=$(echo "$gnss" | grep speed)
last_lock=$(echo "$gnss" | grep last_lock_time_ms)
echo "$(date): $lat, $lon, $speed, $last_lock" | tee -a speed.log
sleep 1
done
}

capture_location_info

Example script output

Thu Jun 19 19:35:11 CDT 2025: latitude: 44.332211, longitude: -88.776655, speed: 0.000000, last_lock_time_ms: 834
Thu Jun 19 19:35:13 CDT 2025: latitude: 44.332211, longitude: -88.776655, speed: 0.000000, last_lock_time_ms: 6
Thu Jun 19 19:35:14 CDT 2025: latitude: 44.332211, longitude: -88.776655, speed: 0.000000, last_lock_time_ms: 197
Thu Jun 19 19:35:15 CDT 2025: latitude: 44.332211, longitude: -88.776655, speed: 0.000000, last_lock_time_ms: 385
Thu Jun 19 19:35:16 CDT 2025: latitude: 44.332211, longitude: -88.776655, speed: 0.000000, last_lock_time_ms: 604
Thu Jun 19 19:35:17 CDT 2025: latitude: 44.332211, longitude: -88.776655, speed: 0.000000, last_lock_time_ms: 775
Thu Jun 19 19:35:19 CDT 2025: latitude: 44.332211, longitude: -88.776655, speed: 0.000000, last_lock_time_ms: 969

GNSS D-Bus Interface Documentation

If you'd like to create your own utility for parsing d-bus data directly like the particle-tachyon-ril-ctl gnss does, the following details are helpful.

Service Name: io.particle.tachyon.GNSS

Object Path: /io/particle/tachyon/GNSS/Modem

Interface: io.particle.tachyon.GNSS.Modem

Method: GetGnss

Signature:

GetGnss   (OUT a{sv} properties);

Description: Retrieves the latest parsed GNSS data.

Call Type: D-Bus method call on interface io.particle.tachyon.GNSS.Modem.

Returns: A dictionary of string keys and variant values (a{sv}) representing GNSS data fields.

For an example of what is returned, run the following command in the terminal:

dbus-send --system --dest=io.particle.tachyon.GNSS --print-reply \
/io/particle/tachyon/GNSS/Modem io.particle.tachyon.GNSS.Modem.GetGnss