Skip to main content

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.

note

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:

  1. Open nRF Connect for Desktop.

  2. Open LTE Link Monitor. The terminal shows by default.

  3. If the side panel is not visible, click Show side panel.

  4. Find the cards that list network parameters in the side panel, and note their values:

    • Mccand Mnc appear as one number. Mcc is the first three digits and Mnc is the last two digits. These are separate values in API calls.
    • CellId: This is eci 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:

  1. At the bottom of the terminal window, click Open log file. A file opens.
  2. 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.
  3. 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 of CellId in your network information.
  • mcc: The first three digits of the Mccmnc parameter in your network information.
  • mnc: The last two digits of the Mccmncparameter 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.

note

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 of CellId in your network information.
  • mcc: The first three digits of the Mccmnc parameter in your network information.
  • mnc: The last two digits of the Mccmncparameter 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 parameters earfcn and pci 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.