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.

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 yetuint64_t
last_lock_time_ms
Milliseconds since last location update (latitude/longitude) or fixmode/gpssta value changeuint8_t
svnum
Number of visible GPS satellitesuint8_t
beidou_svnum
Number of visible BeiDou or GLONASS satelliteschar
nshemi
Hemisphere (North/South): 'N' = North, 'S' = Southchar
ewhemi
Hemisphere (East/West): 'E' = East, 'W' = Westdouble
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 = Estimateduint8_t
posslnum
Number of GPS satellites used for positioning (0–12)uint8_t
fixmode
Fix type: 1 = No fix; 2 = 2D fix; 3 = 3D fixdouble
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 metersdouble
speed
Ground speed, value in 0.001 km/hnmea_utc_time
utc
UTC time and date: .year, .month, .date, .hour, .min, .secnmea_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