Finding device location using cell towers
This tutorial shows you how to find a device's location using one or more cell towers over REST. It uses the Asset Tracker v2 application and LTE Link Monitor (part of nRF Connect for Desktop) to find network information that you need to call the REST API.
The reference hardware for this tutorial is the nRF9160 DK.
Prerequisites and hardware requirements
For this tutorial, you need to program your device with Asset Tracker v2 with debug logs enabled. The setup for CELL location is different from the general one, so read through this section before you start.
Make sure you have met the general prerequisites and hardware requirements for Location Services.
This tutorial requires nRF Connect SDK v1.8.0 or later.
Application
For this tutorial, you need to program your device with Asset Tracker v2 with debug logs enabled. The setup for CELL location is different from the general one, so read through Building the application before you start.
Building the application
Follow the instructions to build your application and program your device through nRF Connect for VS Code or through the command line, with the following changes:
- Through nRF Connect for VS Code: When you reach the step setting your build configuration, under the menu Kconfig fragments, select
overlay-debug.conf
. - Through the command line: Use
west build -b nrf9160dk_nrf9160ns -- -DOVERLAY_CONFIG=overlay-debug.conf
to build the application with debug logs enabled.
Once you have built your application, continue with programming your device.
Getting network information
Once you have a device running Asset Tracker v2 and connected to nRF Cloud, you need parameter values related to the towers near the device. These values are used to determine the device's location.
You can get this information using the LTE Link Monitor application:
Open nRF Connect for Desktop.
Open LTE Link Monitor. The terminal shows by default.
If the side panel is not visible, click Show side panel.
Find the cards that list network parameters in the side panel, and note their values:
Mcc
andMnc
appear as one number.Mcc
is the first three digits andMnc
is the last two digits. These are separate values in API calls.CellId
: This iseci
in API calls.TAC
: A five-digit area code.
You also need information on neighbor cells. Because you built your application with debug options enabled, you can access the debug log through LTE Link Monitor:
- At the bottom of the terminal window, click Open log file. A file opens.
- In the log file, search for
nmr
. This array contains data on neighbor cells. Within the array are more parameters:earfcn
: Evolved Absolute Radio Frequency Channel.pci
: Physical Cell Identity.
- Make a note of these values. You need them to call the API.
Here is an example debug log entry with network data:
[00:01:41.711,608] <inf> event_manager: DATA_EVT_DATA_READY
Encoded message:
{
"appId": "CELL_POS",
"messageType": "DATA",
"data": {
"lte": [{
"eci": 33903884,
"mcc": 242,
"mnc": 2,
"tac": 2801,
"earfcn": 6300,
"rsrp": -66,
"rsrq": -7,
"adv": 16,
"nmr": [{
"earfcn": 6300,
"pci": 181,
"rsrp": -89,
"rsrq": -29
}, {
"earfcn": 6300,
"pci": 176,
"rsrp": -96,
"rsrq": -34.5
}]
}],
"doReply": 0
}
}
[00:01:41.771,026] <dbg> data_module.data_encode: Neighbor cell data encoded successfully
[00:01:41.779,663] <dbg> data_module.data_list_add_pending: Pending data added: 0x20022f38
[00:01:41.788,482] <inf> event_manager: DATA_EVT_NEIGHBOR_CELLS_DATA_SEND
Constructing the API request
This step shows you how to query device location from one or more cell towers, depending on what data you include in your request and which endpoint you call.
Click to expand the section relevant to your method.
Calling the ground fix endpoint for Wi-Fi and cell location
Using ground fix
The GetLocationFromCellTowersOrWifiNetworks
ground fix endpoint combines Wi-Fi and cellular methods into a single call. The service attempts to find the device's location using Wi-Fi first and falls back to cellular if the Wi-Fi request cannot resolve.
Example
The following example is for REST, using Wi-Fi and cellular methods:
curl --location --request POST "$API_HOST/v1/location/ground-fix" \
--header "Authorization: Bearer $JWT" \
--header "Content-Type: application/json" \
--data-raw "{\"lte\":[{\"mcc\":$MCC, \"mnc\":$MNC,\"tac\":$TAC,\"eci\":$ECI}], \"wifi\":{\"accessPoints\": [{\"macAddress\": \"FE:1E:41:2D:9E:53\", \"ssid\": \"my-wifi-network\", \"signalStrength\": -42}, {\"macAddress\": \"EF:E1:14:D2:E9:35\", \"ssid\": \"my-other-wifi-network\", \"signalStrength\": -22}]}}"
For cellular, use the -d
or --data-raw
field to pass a JSON-formatted lte
array including the following parameters:
eci
: The value ofCellId
in your network information.mcc
: The first three digits of theMccmnc
parameter in your network information.mnc
: The last two digits of theMccmnc
parameter in your network information.tac
: The area code in your network information.nmr
: Include neighbor cell data for a multi-cell request.
The server responds with latitude and longitude, as well as uncertainty in meters. The fulfilledWith
property tells you which method nRF Cloud used. See GetLocationFromCellTowersOrWifiNetworks
for an example request and response.
The server stores cell location data for device-to-cloud requests in the location history. To view this, call the GetLocationHistory
endpoint. You can also view historical location data under the Location card on a device's page in the nRF Cloud portal.
Calling the cell-only endpoint
Using cell only
Construct a call to the GetLocationFromCellTowers
endpoint, including the network data you gathered from LTE Link Monitor. This example uses cURL, like all examples in the API documentation.
Include the array lte
in your request using the --data-raw
option.
Make sure you escape quotation marks in your message body (for example, \"mcc\":<mcc>
).
Example
This example is for a single cell request:
curl --location --request POST "$API_HOST/v1/location/cell" \
--header "Authorization: Bearer $JWT" \
--header "Content-Type: application/json" \
--data-raw "{\"lte\":[{\"mcc\":$MCC, \"mnc\":$MNC,\"tac\":$TAC,\"eci\":$ECI}]}"
Include neighbor cell data in the --data-raw
field for a multi-cell request:
{
"lte": [
{
"mcc": 310,
"mnc": 120,
"eci": 167899669,
"tac": 13601,
"earfcn": 41490,
"adv": 20000,
"rsrp": -90,
"rsrq": -8,
"nmr": [
{
"earfcn": 41490,
"pci": 143,
"rsrp": -90,
"rsrq": -8,
"timeDiff": 300
}
]
}
]
}
Some of the parameters have different names than in LTE Link Monitor, and are all lowercase:
eci
: The value ofCellId
in your network information.mcc
: The first three digits of theMccmnc
parameter in your network information.mnc
: The last two digits of theMccmnc
parameter in your network information.tac
: The area code in your network information.nmr
: Neighbor cell data from your debug log, or the terminal on the device's page in nRF Cloud. Include within this array the required parametersearfcn
andpci
if you want to use multiple cell towers to determine the device location. If you leave this out of your request, the server returns a single cell result instead.
The server responds with latitude, longitude, and uncertainty in meters. See GetLocationFromCellTowers
for an example request and response.
The server stores this cell location data in the location history. To view this, call the GetLocationHistory
endpoint. You can also view historical location data under the Location card on a device's page in the nRF Cloud portal.