DEV Community

Cover image for Use Cell Tower and Wi-Fi Triangulation to Achieve Pin-Point Locations, without GPS
Rob Lauer for Blues

Posted on • Originally published at blues.io

Use Cell Tower and Wi-Fi Triangulation to Achieve Pin-Point Locations, without GPS

Many IoT solutions include one basic requirement: to know precisely where they are in the world.

where in the world am i

While ascertaining location is usually handled with a GNSS/GPS module, there are scenarios where GPS is not reliable or practical. In fact, I'll give you three exact scenarios:

  1. Indoor deployments where getting a GPS satellite fix is impossible.
  2. Use of a physical enclosure that prevents a GPS fix.
  3. Low-power solutions that can't afford the power drain of GPS.

Here at Blues Wireless, when we talk about gathering lat/lon coordinates, we usually refer people to the onboard GPS capabilities of the Cellular Notecard, which we highly recommend as the first (and often only) way of ascertaining location.

However, today I want to look more closely at a lesser-known capability of the Notecard: Cell Tower and Wi-Fi Triangulation.

Triangulation

If you've taken basic trigonometry or geometry courses, you already know that triangulation is the process of determining a location by forming triangles to the point of interest, from a series of other known points.

cell tower triangulation example

The Notecard provides built-in capabilities of utilizing triangulation in a few different ways: cell tower triangulation, Wi-Fi triangulation, or both!

Cell Tower Location

If you're experienced with the Cellular Notecard, you've likely noticed the tower_ parameters that show up in Notehub events:

"tower_when": 1656000634,
"tower_lat": 43.074087500000005,
"tower_lon": -89.44282812499999,
"tower_country": "US",
"tower_location": "Shorewood Hills WI",
"tower_timezone": "America/Chicago",
"tower_id": "310,410,17169,77315594",
Enter fullscreen mode Exit fullscreen mode

The tower_lat and tower_lon values are an approximate location of the single cell tower this Notecard was connected to at the given tower_when timestamp. While this is a nice (rough) location, it's not useful on its own when trying to determine the precise location of a device.

For example, here is the approximate position of the cell tower used in a recent request, relative to my location:

single cell tower location with notecard

Cell Tower Triangulation

In scenarios where GPS is unusable, performing cell tower triangulation with the Notecard can provide a massive improvement, thanks to the magic of the card.triangulate API.

To enable cell tower triangulation on a Cellular Notecard, simply issue this request:

{
  "req": "card.triangulate",
  "mode": "cell"
}
Enter fullscreen mode Exit fullscreen mode

The next time the Notecard establishes a new session with Notehub, information about every visible cell tower will be uploaded and processed. A new set of location data will appear in every Notehub event, prepended with tri_, like so:

"tri_when": 1656011112,
"tri_lat": 43.07113895,
"tri_lon": -89.43272533,
"tri_location": "Shorewood Hills WI",
"tri_country": "US",
"tri_timezone": "America/Chicago",
"tri_points": 16,
Enter fullscreen mode Exit fullscreen mode

Here is the updated location estimate, based on cell tower triangulation only:

cell tower triangulation with notecard

As you can see, the actual location has improved significantly, and will only improve as more cell towers are visible.

NOTE: It's important to know that cell tower triangulation comes with a non-trivial power penalty because the modem scan for nearby cell towers can take almost as long as an entire sync. Triangulation also only occurs during a connection to Notehub and there is no way to "re-triangulate" during a continuous Notehub session.

Wi-Fi Triangulation

If your host MCU has an onboard Wi-Fi module (like the ESP32), you can perform a Wi-Fi access point (AP) scan and send this data to the Notecard to perform Wi-Fi triangulation.

NOTE: Wi-Fi triangulation is an experimental, technical preview feature from Blues Wireless that is free
for use today, but may use Consumption Credits in
the future.

The format of the card.triangulate call is a little different when using Wi-Fi triangulation. Note that you can use cell, wifi, or both with wifi,cell when enabling triangulation.

{
  "req": "card.triangulate",
  "mode": "wifi",
  "text": "+CWLAP:(4,\"Blues\",-51,\"74:ac:b9:12:12:f8\",1)\n+CWLAP:(3,\"AAAA-62DD\",-70,\"6c:55:e8:91:62:e1\",11)\n+CWLAP:(4,\"Blues\",-81,\"74:ac:b9:11:12:23\",1)\n+CWLAP:(4,\"Blues\",-82,\"74:ac:a9:12:19:48\",11)\n+CWLAP:(4,\"Free Parking\",-83,\"02:18:4a:11:60:31\",6)\n+CWLAP:(5,\"GO\",-84,\"01:13:6a:13:90:30\",6)\n+CWLAP:(4,\"AAAA-5C62-2.4\",-85,\"d8:97:ba:7b:fd:60\",1)\n+CWLAP:(3,\"DIRECT-a5-HP MLP50\",-86,\"fa:da:0c:1b:16:a5\",6)\n+CWLAP:(3,\"DIRECT-c6-HP M182 LaserJet\",-88,\"da:12:65:44:31:c6\",6)\n\n"
}
Enter fullscreen mode Exit fullscreen mode

What's that scary-looking text field? It's a newline-terminated list of Wi-Fi access points that follows a pattern similar to the ESP32's AT+CWLAP command output.

Deriving Access Point Data with Arduino

If you're comfortable issuing AT commands to your host MCU, you can send AT+CWLAP and format the response per the above requirements. However, not many of us are so cozy with AT syntax, which is why we provide the
Notecard Auxiliary Wi-Fi Arduino library
for an easier way of programmatically pulling a list of Wi-Fi access points with
your Wi-Fi enabled host MCU, and sending them to the Notecard in one command:

// Update Notecard Triangulation Data
aux_wifi.updateTriangulationData();
Enter fullscreen mode Exit fullscreen mode

Deriving Access Point Data with CircuitPython

Developing with CircuitPython? Here is an example function that uses the built-in wifi library to gather the same WAP data when used with an ESP32 MCU:

import wifi
import binascii

def get_wifi_access_points():
    """ returns a set of visible access points, corresponds to esp32 AT+CWLAP format """
    # https://docs.espressif.com/projects/esp-at/en/latest/esp32/AT_Command_Set/Wi-Fi_AT_Commands.html#cmd-lap

    all_wifi_aps = ""

    for network in wifi.radio.start_scanning_networks():

        wifi_ap = "+CWLAP:("

        if wifi.AuthMode.ENTERPRISE in network.authmode:
            wifi_ap += "5"
        elif wifi.AuthMode.PSK in network.authmode:
            wifi_ap += "6"
        elif wifi.AuthMode.WPA3 in network.authmode:
            wifi_ap += "6"
        elif wifi.AuthMode.WPA2 in network.authmode:
            wifi_ap += "3"
        elif wifi.AuthMode.WPA in network.authmode:
            wifi_ap += "2"
        elif wifi.AuthMode.WEP in network.authmode:
            wifi_ap += "1"
        else:
            wifi_ap += "0"

        bssid = binascii.hexlify(network.bssid).decode("ascii")
        bssid = ':'.join(bssid[i:i+2] for i in range(0,12,2))

        wifi_ap = wifi_ap + ",\"" + str(network.ssid) + "\"," + str(network.rssi) + ",\"" + bssid + "\"," + str(network.channel) + ")\n"

        all_wifi_aps += wifi_ap

    wifi.radio.stop_scanning_networks()

    return all_wifi_aps
Enter fullscreen mode Exit fullscreen mode

Wi-Fi Triangulation in Action

How different are my results when using Wi-Fi triangulation? Well the only access point my ESP32 was able to find was my own router. However, even with just that one AP, here are the results:

"tri_when": 1656011112,
"tri_lat": 43.07113895,
"tri_lon": -89.43272533,
"tri_location": "Shorewood Hills WI",
"tri_country": "US",
"tri_timezone": "America/Chicago",
"tri_points": 16,
Enter fullscreen mode Exit fullscreen mode

Which becomes amazingly accurate when displayed on a map!

wi-fi triangulation with notecard

Wi-Fi triangulation becomes even more valuable when you realize the power requirements are minimal, and it adds only 1-2 seconds to the sync time with Notehub.

Be sure to consult the developer documentation on Cell Tower and Wi-Fi Triangulation as there are additional settings in Notehub that you may want to change, depending on how you use triangulation in your solution.

Triangulation with Wi-Fi Notecard

Up until now, all of these instructions have revolved around using the Cellular Notecard. What about if you're using the Wi-Fi Notecard (which doesn't have an onboard GNSS/GPS module)?

Luckily enough, Wi-Fi triangulation is enabled on the Wi-Fi Notecard by default, no configuration changes required!

After setting up a Wi-Fi Notecard, here were the results in a given event:

"tri_when": 47,
"tri_lat": 43.07121864,
"tri_lon": -89.43263674,
"tri_location": "Shorewood Hills WI",
"tri_country": "US",
"tri_timezone": "America/Chicago",
"tri_points": 3,
Enter fullscreen mode Exit fullscreen mode

Which, again, when plotted on a map, comes shockingly close to landing on my location:

triangulation with wi-fi notecard

Summary

While GPS is the de facto standard for identifying the precise location of an IoT device, and should always be the first option when gathering location data, the Notecard's triangulation capabilities provide options when GPS isn't available.

Happy Mapping with the Notecard and Notehub! 📍🗺

Top comments (0)