🎉 25% off Pre-Sale! Bluetooth LE course with real hardware included - no SDK required
Tutorial · · 19 min read

Integrate Hubble Network on your nRF54L15 for Global Connectivity

Learn how to connect your Bluetooth LE devices to Hubble Network's global IoT infrastructure—90M+ smartphone gateways—using Nordic's nRF54L15 and the reference app.

Integrate Hubble Network on your nRF54L15 for Global Connectivity
Integrate Hubble Network on your nRF54L15 for Global Connectivity

This post is sponsored by Hubble Network.

What if your Bluetooth LE device could communicate beyond the range of traditional gateways—even from remote locations without cellular coverage? Hubble Network makes this possible. They've built a global infrastructure for delivering device data to the cloud, using over 90 million terrestrial gateways that receive standard Bluetooth LE advertisements (available now) and a direct-to-satellite network with its own transmission protocol (currently in beta with select customers, with general availability expected later in 2026).

In this tutorial, we'll walk through setting up a Hubble Network demo on Nordic's nRF54L15 DK using nRF Connect SDK and VS Code. We'll use Hubble's reference app as our starting point, with a small tweak to how the device key is loaded—making the provisioning workflow simple and IDE-friendly. By the end, you'll have a working beacon that transmits encrypted data to Hubble's terrestrial network, and you'll see that data appear in their cloud dashboard—accessible via their open API for easy integration into downstream applications. I've found this to be one of the most straightforward ways to explore satellite/terrestrial IoT connectivity without needing specialized hardware or setting up my own scanning infrastructure.

In this tutorial, we'll cover:

💡
Prefer video? I recorded a full walkthrough of this tutorial using the nRF54L15 DK and the Hubble Connect mobile app. Jump to the video demo to see the entire process in action—from provisioning to seeing our device data in the Hubble dashboard.

What is Hubble Network?

Hubble Network is building global IoT connectivity infrastructure that works with standard, off-the-shelf Bluetooth LE chips. Unlike traditional IoT solutions that require cellular modems, LoRa radios, or proprietary hardware, Hubble works with the standard Bluetooth LE radio that's already in most devices.

Founded in 2021 by Alex Haro (co-founder of Life360) and Ben Wild, the company has raised $100M in funding and achieved a major milestone in 2024: the first-ever Bluetooth-to-satellite connection.

Let's take a closer look at how this works.

How It Works

Our device broadcasts a standard Bluetooth LE advertisement containing an encrypted payload. Hubble's infrastructure—either terrestrial gateways or satellites—receives these advertisements and forwards the data to their cloud. From there, we can access our device data via API or dashboard.

The Hubble SDK handles all the complexity. For example, here's what happens under the hood when our device broadcasts:

The following diagram shows the complete data flow from device to cloud:

Hubble Network data flow diagram showing nRF54L15 device connecting via Bluetooth LE to smartphone gateway or satellite, then to Hubble Cloud and dashboard
Data flow: nRF54L15 broadcasts via Bluetooth LE to terrestrial gateways or satellites, which forward to Hubble Cloud

How Hubble Compares to Amazon Sidewalk

If you're familiar with the IoT connectivity space, you might be wondering how Hubble compares to Amazon Sidewalk—another network that uses existing infrastructure for low-power device connectivity.

While both aim to solve the "last mile" connectivity problem for IoT devices, there are some key differences:

Feature Hubble Network Amazon Sidewalk
Terrestrial Coverage 90M+ smartphones (dedicated, always-on) Consumer Echo/Ring devices (users may opt out)
Global Reach Satellite constellation (coming later 2026) US only, no satellite component
Coverage Consistency Purpose-built network with high engagement users Depends on Amazon device density and opt-in rates
Chip Support Nordic, TI, Silicon Labs (any standard Bluetooth LE) Amazon-certified devices only
Enterprise Focus Built for commercial IoT with REST API and webhooks Primarily consumer-oriented

The key advantage of Hubble over something like Amazon Sidewalk is the satellite component—once operational, our devices will have connectivity anywhere on Earth, not just in neighborhoods with Amazon devices. For applications like stolen vehicle recovery, fleet tracking, or remote asset monitoring, you really need global coverage. You can't rely on thieves driving through areas with good Sidewalk coverage. 😄

Terrestrial and Satellite Networks

Hubble has two networks:

Network Status Coverage Use Case
Terrestrial Available now Urban/suburban via 90M+ smartphones Asset tracking, fleet/vehicle tracking, stolen vehicle recovery, dense urban deployments
Satellite Beta testing with select customers (coming later 2026) Global including oceans and remote areas Asset tracking, agriculture, maritime, wilderness

For this tutorial, we'll focus on the terrestrial network. The satellite network has its own SDK library (CONFIG_HUBBLE_SAT_NETWORK) with a different transmission protocol, but it shares the same provisioning keys and cloud backend—so the foundation we build here transfers directly.

The Advertisement Format

When our device broadcasts, the Bluetooth LE advertisement contains 18-31 bytes of Hubble-specific data depending on whether we include custom payload (the complete Bluetooth LE packet includes additional headers and addressing). The following table shows the packet structure, using standard Bluetooth AD types:

Hubble Bluetooth LE Advertisement (18-31 bytes)
AD Structure Field Value Description
UUID List

(4 bytes)
Length 0x03 3 bytes follow
Type 0x03 Complete List of 16-bit UUIDs
UUID 0xFCA6 Hubble Network Service
Service Data

(14-27 bytes)
Length 0x0D - 0x1A 13-26 bytes follow
Type 0x16 Service Data - 16-bit UUID
UUID + Hubble Payload 0xFCA6 + 10 bytes Encrypted: Protocol version, sequence number, device ID, auth tag
Custom Payload (optional) 0-13 bytes Encrypted application data (telemetry, sensor readings)

The base 10-byte Hubble payload (generated by the SDK) contains:

You can optionally add up to 13 bytes of custom payload for application-specific data—for example, temperature readings, motion events, or diagnostic information. See Hubble's Custom Payload guide for encoding examples. This custom data is encrypted alongside the Hubble fields using our device's master key.

When a Hubble gateway receives this advertisement, it adds its own GPS location and forwards everything to the cloud. The backend decrypts the payload using our device's key and associates the data with our account.

Supported Chip Platforms

The Hubble Device SDK is compatible with any Bluetooth LE-capable chip. The examples below are platforms Hubble has tested and provides additional resources for (like reference apps):

Platform Supported Chips Notes
Nordic Semiconductor nRF52, nRF53, nRF54 series Official support via nRF Connect SDK (Zephyr-based)
Zephyr RTOS Any Zephyr-compatible Bluetooth LE chip Official support via Zephyr SDK module
Espressif ESP32 family Official support via ESP-IDF
Texas Instruments CC23xx family (e.g., CC2340R5) Official support via FreeRTOS (TI partnership)
Silicon Labs EFR32MG24 and Series 2 SoCs Includes Secure Vault integration

This tutorial uses the nRF54L15 DK, but the same principles apply to any supported platform. The Hubble SDK integrates as a Zephyr module, making it compatible with any Zephyr-based build system.

Development Environment Setup

Let's get our development environment ready. We'll be using nRF Connect for VS Code, which is what I use for all my NCS projects. If you're already familiar with this toolchain, skip ahead to Step 2 where we clone the Hubble SDK.

Prerequisites

Before we begin, make sure you have:

Software:

What to Expect: Sandbox vs. Live Access

When you sign up at dash.hubble.com, you'll receive Sandbox access by default. Here's what that means:

Access Level What You Get How to Test
Sandbox (self-signup) Local testing only Use the Hubble Connect mobile app as a local gateway
Live Full Terrestrial Network access via 90M+ gateways Contact Hubble Sales

With Sandbox access, the production Terrestrial Network still detects our device's packets and shows aggregate statistics in our dashboard, but the actual packet data is only delivered when captured locally using the Hubble Connect mobile app on our phone. That works fine for development and testing—we can verify our implementation before deploying to production.

For production deployments with full Terrestrial Network connectivity, you'll need to contact Hubble's sales team.

For this tutorial, Sandbox access is all you need. We'll use the Hubble Connect app to verify our beacon is working correctly.

Step 1: Install nRF Connect for VS Code

If you haven't already set up nRF Connect for VS Code:

  1. Download and install Visual Studio Code
  2. Open VS Code and go to the Extensions view (Ctrl+Shift+X or Cmd+Shift+X)
  3. Search for "nRF Connect for VS Code" and install the extension pack
  4. Click the nRF Connect icon in the sidebar to open the extension panel
  5. Under Manage Toolchains, install the latest toolchain
  6. Under Manage SDKs, install nRF Connect SDK (v3.2.0 was used for this tutorial)

The SDK installation takes a few minutes as it downloads the full nRF Connect SDK (including Zephyr RTOS and all dependencies).

Step 2: Clone the Hubble Network SDK

The Hubble Device SDK is available on GitHub. Clone it to a convenient location:

mkdir hubble-demo && cd hubble-demo
git clone https://github.com/HubbleNetwork/hubble-device-sdk.git hubblenetwork-sdk

This gives you the following structure:

hubble-demo/
└── hubblenetwork-sdk/
    ├── samples/
    │   ├── zephyr/
    │   │   ├── ble-beacon/           # Terrestrial beacon
    │   │   └── ble-network/          # Combined terrestrial + satellite
    │   ├── esp-idf/ble-beacon/       # ESP32 sample
    │   └── freertos/ti/ble-beacon/   # TI FreeRTOS sample
    ├── port/
    │   ├── zephyr/                   # Zephyr/NCS integration layer
    │   ├── esp-idf/                  # ESP-IDF integration layer
    │   └── freertos/                 # FreeRTOS integration layer
    ├── include/hubble/               # SDK headers
    ├── tools/                        # Provisioning scripts
    └── zephyr/module.yml             # Module registration for Zephyr

Step 3: Set Up the Reference App

Hubble provides a reference app that streamlines the development workflow. It handles key loading and computes the UTC timestamp automatically at build time—no extra steps before each build.

Clone the reference app into your project directory:

git clone https://github.com/HubbleNetwork/hubble-reference-zephyr-simple.git ble-beacon-refapp

Our project structure should now look like:

hubble-demo/
├── hubblenetwork-sdk/            # SDK (keep clean, can git pull updates)
└── ble-beacon-refapp/            # Our reference app project
    ├── src/
    │   ├── main.c                # Application code
    │   ├── b64.c                 # Base64 decoder (for runtime key decode)
    │   └── b64.h
    ├── prj.conf
    └── CMakeLists.txt            # Key loading + UTC timestamp at build time

The key part is CMakeLists.txt. The stock reference app reads the device key from a HUBBLE_DEVICE_KEY environment variable—which works fine when building from the command line, but can be unreliable in VS Code since the IDE doesn't always inherit your shell environment. We've made a small modification to read the key from a file instead (hubble-device-b64.key in the parent directory), which works reliably regardless of how you trigger the build. It also computes the UTC timestamp automatically at build time—so we just need to save our key to a file before building:

# Device key from file (our modification — stock app uses environment variable)
set(_keyfile "${CMAKE_CURRENT_SOURCE_DIR}/../hubble-device-b64.key")
if(EXISTS "${_keyfile}")
  file(READ "${_keyfile}" HUBBLE_DEVICE_KEY)
  string(STRIP "${HUBBLE_DEVICE_KEY}" HUBBLE_DEVICE_KEY)
else()
  set(HUBBLE_DEVICE_KEY "1111111111111111111111111111111111111111111=")
endif()

# UTC timestamp computed automatically at build time
string(TIMESTAMP EPOCH_S "%s" UTC)
math(EXPR TIME_MS "${EPOCH_S} * 1000")

target_compile_definitions(app PRIVATE HUBBLE_KEY="${HUBBLE_DEVICE_KEY}")
target_compile_definitions(app PRIVATE TIME=${TIME_MS})

The app decodes the Base64 key at runtime using a bundled b64.c decoder, so the raw key bytes are available to the Hubble SDK at initialization.

Step 4: Create the Build Configuration

Now let's set up the build configuration in VS Code:

Configure the following settings:

Expand Extra CMake arguments and add:

-DEXTRA_ZEPHYR_MODULES=/absolute/path/to/hubble-demo/hubblenetwork-sdk

That's all you need—no extra Kconfig fragments required. The reference app has CONFIG_LOG_BACKEND_UART=y in prj.conf, so serial logging is ready to go.

The EXTRA_ZEPHYR_MODULES argument tells the build system to include the Hubble SDK as an external Zephyr module, making its Kconfig options (like CONFIG_HUBBLE_BLE_NETWORK) and source files available to your project. If you've worked with Zephyr modules before, this should look familiar.

Step 5: Enable Debug Logging

The reference app registers its log module with CONFIG_APP_LOG_LEVEL, which defaults to CONFIG_LOG_DEFAULT_LEVEL (info). For development, I recommend overriding this to LOG_LEVEL_DBG directly in main.c so we can see all the diagnostic output—decoded key bytes, advertisement details, and payload contents:

LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);

This enables debug logging for our application module only, without flooding the console with debug messages from every Zephyr subsystem (which is what happens if you set CONFIG_LOG_DEFAULT_LEVEL=4 globally). You'll see the key decode, temperature, and advertisement messages while keeping the OS-level noise at info level.

Device Provisioning

Before you can build and run the application, we need to provision our device with an encryption key. This key is used to encrypt the Bluetooth LE advertisements so that only Hubble's backend can decrypt and identify our device.

Step 1: Register Your Device with Hubble

First, we need to register a device in the Hubble dashboard to obtain an encryption key. You'll need an API Token to access the API—see how to create one here. You can also import the API spec into your preferred developer environment (Postman, Insomnia, etc.).

Go to the Register New Devices page in the Hubble Cloud API documentation, which provides an interactive form for registering devices directly from the browser.

In the interactive panel on the right, fill in:

In the Body section, configure:

Hubble Cloud API Register New Devices interface
The Cloud API documentation provides an interactive form for registering devices
💡
Tip: If you prefer to automate device registration, you can also use curl or any HTTP client to call the same API endpoint directly. See Hubble's API documentation for the request format.
⚠️
Important: Each device needs a unique key. If you're testing with multiple development boards, register a separate device for each one. Hubble's backend uses rolling counters for replay protection, and if two devices share the same key, the backend may filter out packets that appear to be replay attacks. For development, I recommend naming your devices descriptively—for example, nrf54l15_dk_01 and nrf54l15_dk_02—so you can easily identify them in the dashboard.

Step 2: Set the Device Key

With our modified CMakeLists.txt, we read the device key from a file called hubble-device-b64.key in the parent directory (i.e., the hubble-demo/ folder). Save your key to this file:

echo "YOUR_BASE64_KEY_HERE" > hubble-demo/hubble-device-b64.key

Replace YOUR_BASE64_KEY_HERE with the Base64-encoded key you received from the API in Step 1. The build system reads this file automatically—no environment variables to manage.

💡
Tip: If you're working with multiple devices, just swap the contents of hubble-device-b64.key when switching between devices—no need to manage environment variables or restart your IDE.
📝
Note: The stock reference app uses the environment variable approach (export HUBBLE_DEVICE_KEY=...), which is what Hubble's documentation shows. That works well when building with west build directly from the command line. However, when using VS Code with the nRF Connect extension, environment variables set in your shell profile (e.g., ~/.zshrc) aren't automatically inherited by the IDE's build process. That's why we modified CMakeLists.txt to read from a file instead—it works reliably regardless of how you trigger the build.

Fresh Timestamp on Every Build

The UTC timestamp is computed fresh by CMake on every build, so you can just rebuild and flash at any time. The timestamp is always current.

The Terrestrial Network supports ±24 hours of clock precision. Since the reference app generates a fresh timestamp on every pristine build, you'll always be within that window as long as you do a pristine build before flashing.

For production devices, Hubble recommends at least 500PPM clock accuracy to control drift over time. If your device will run for extended periods, consider implementing a time synchronization protocol—the Terrestrial Network gateways do not manage or refresh device time.

📝
Note: Make sure the hubble-device-b64.key file contains your actual device key before building. If the file is missing or contains the default test key, your device won't appear under "My Devices" in the Hubble dashboard.

The reference app initializes the Bluetooth LE stack and the Hubble SDK, then calls hubble_ble_advertise_get() in a loop to generate fresh encrypted payloads. That single SDK function handles all the cryptography (key derivation, nonce generation, AES-256 encryption) internally, so we don't have to deal with any of that. We also add temperature sensor reading as a custom payload—see Adding Custom Sensor Data below for details on how the encoding works.

Building and Flashing

Now that our device key is in place, let's build and flash the application.

Build the Application

  1. Open the nRF Connect extension panel in VS Code
  2. Find your build configuration under Applications
  3. Click the Build button (hammer icon)

The build should complete without errors. You'll verify the key was loaded correctly in the serial output after flashing.

Flash to the nRF54L15 DK

  1. Connect your nRF54L15 DK to your computer via USB
  2. In the nRF Connect panel, click the Flash button
  3. Wait for the flashing process to complete

Verify with Serial Output

Open a serial terminal (115200 baud) to see the application output:

  1. In VS Code, open the nRF Terminal (View > Terminal, then select nRF Terminal)
  2. Or use your preferred serial terminal application

We should see output similar to:

*** Booting nRF Connect SDK v3.2.0 ***
[00:00:00.022,411] <dbg> main: main: Hubble Network BLE Beacon Reference App started
[00:00:00.022,439] <inf> main: Temperature sensor initialized
[00:00:00.024,124] <inf> bt_hci_core: Identity: D1:11:FE:93:26:44 (random)
[00:00:00.024,184] <dbg> main: decode_master_key: Decoded key: bc 6b 26 5f c1 b4 ad 00 ...
[00:00:00.024,200] <dbg> main: decode_master_key: TIME = 1738000000000
[00:00:00.024,213] <inf> hubblenetwork: Hubble Network SDK initialized
[00:00:00.028,996] <inf> main: Temperature: 28.50 C | Base64: CyI=
[00:00:00.031,137] <dbg> main: main: Number of bytes in advertisement: 14

The output confirms several things: our key was decoded correctly (the Decoded key: line logs the first bytes of the decoded key so you can confirm the right key was loaded), the temperature sensor we added is reading (28.50°C), and the advertisement includes 14 bytes of service data content (2-byte UUID + 10-byte Hubble payload + 2 bytes of our temperature data). The device broadcasts at a 2-second advertising interval, refreshing the encrypted payload—including a new temperature reading—every 5 minutes.

💡
Verifying the key: Want to double-check that the decoded bytes match your key? Run this in your terminal:

cat hubble-device-b64.key | base64 -d | xxd -p -c 8 | head -1

The output should match the hex bytes shown in the Decoded key: line.

Our device is now broadcasting Hubble advertisements!

Testing and Verification

Let's verify that our device is communicating with the Hubble network. With Sandbox access, we'll use the Hubble Connect mobile app as a local gateway to receive our device's Bluetooth LE advertisements and forward them to the cloud.

Testing with the Hubble Connect App

The Hubble Connect app (available on iOS and Android) turns our smartphone into a local Hubble gateway for development and testing:

  1. Download Hubble Connect from the App Store
  2. Log in with your Hubble developer account (the same one you used at dash.hubble.com)
  3. Grant Bluetooth and location permissions when prompted
  4. The app will start scanning for nearby Hubble devices
  5. Our registered device should appear in the My Devices tab
Hubble Connect mobile app My Nearby Devices screen showing nrf54l15_dk device with UUID and Live tag
The Hubble Connect app detecting our nRF54L15 beacon in the My Nearby Devices list

The app scans for nearby devices broadcasting on the Hubble protocol and registered with our organization. When it receives our device's advertisement, it forwards the encrypted payload to Hubble's cloud.

📝
Note: With Sandbox access, the production Terrestrial Network (90M+ smartphones) will still detect our device's packets and show aggregate statistics in the dashboard. However, the actual packet data is only delivered when captured locally through the Hubble Connect app. For full Terrestrial Network data delivery, contact Hubble's sales team for Live access.

Check the Hubble Dashboard

  1. Open dash.hubble.com and log in
  2. Navigate to our devices list
  3. Find our registered device (e.g., "nrf54l15_demo")
  4. Click to view device details
Hubble cloud dashboard showing nrf54l15_dk device with network traffic graph, recent packet data including payload CyI=, RSSI, and gateway location
The Hubble dashboard showing our device's network traffic and recent packet data

With the Hubble Connect app running nearby, we should see recent data including:

Understanding the Data

When we view a device packet in the dashboard, we'll see something like:

{
  "location": {
    "timestamp": 1769703217.7,
    "latitude": 39.76493314820157,
    "longitude": -86.16218773415692,
    "altitude": 219.84721038564210,
    "horizontal_accuracy": 4.67592332215799,
    "vertical_accuracy": 30
  },
  "device": {
    "id": "826b4243-1c0b-41c4-8555-dfcc723c36a1",
    "name": "nrf54l15_dk",
    "tags": {
      "_env": "production"
    },
    "payload": "CyI=",
    "sequence_number": 3,
    "counter": 20481,
    "rssi": -51,
    "timestamp": 1769703220.007
  },
  "network_type": "TERRESTRIAL"
}

The location comes from the gateway, not your device. This is how Hubble provides location context—the gateway knows where it is and tags the received packets with that information.

Adding Custom Sensor Data

To demonstrate end-to-end data flow, we add temperature sensor reading to the reference app. This is a small modification—we read the nRF54L15's on-chip die temperature sensor every advertising cycle and include it as a 2-byte custom payload in the Hubble advertisement.

I find that sending a known sensor value and comparing the Base64 output on the serial console with what appears on the dashboard is the quickest way to verify end-to-end data flow—from the device, through the gateway, to the cloud.

How the Payload Works

The temperature is packed as a big-endian int16 in 0.01°C units (so 28.50°C becomes the integer 2850, or 0x0B22). Our app logs both the human-readable temperature and its Base64 encoding for easy comparison with the dashboard:

[00:00:00.028,996] <inf> main: Temperature: 28.50 C | Base64: CyI=

The 2 bytes of temperature data are passed to hubble_ble_advertise_get() as the custom payload, encrypted alongside the Hubble protocol fields, and transmitted in the advertisement. That's well within the 13-byte maximum—you still have 11 bytes left over if you want to pack in additional readings or device state down the road.

Configuration

For the temperature sensor and Base64 debug logging, we add these Kconfig options to prj.conf:

# Sensor subsystem (for on-chip temperature)
CONFIG_SENSOR=y

# Base64 encoding (for debug payload logging)
CONFIG_BASE64=y

Verifying the Payload End-to-End

Now let's verify that our data made it through. The serial console shows each temperature reading along with its base64 encoding:

Serial console output from nRF54L15 showing Hubble beacon startup, decoded key, temperature reading of 28.50 C, and Base64-encoded payload CyI=
The serial console shows the temperature reading (28.50 C) and its Base64 encoding (CyI=)—we'll match this on the dashboard

And on the Hubble Connect app (or the web dashboard), the same base64 string appears in the payload field:

Hubble Connect mobile app showing received packet from nrf54l15_dk device with payload CyI= matching the serial console output
The Hubble Connect app shows "payload": "CyI="—matching the serial output, confirming end-to-end delivery

The payloads match. For example, a reading of 28.50°C gets packed as 0x0B22 (2850 in 0.01°C units), which base64-encodes to CyI=. That value was encrypted by the SDK, transmitted via Bluetooth LE, received by a terrestrial gateway, decrypted in the cloud, and delivered to our dashboard—all verifiable with a quick glance at both screens.

This is the core workflow for any custom payload application. Whether it's sensor readings, device diagnostics, or application state—the pattern is the same: pack your data into a byte array (up to 13 bytes), pass it to hubble_ble_advertise_get(), and retrieve it from the dashboard or via Hubble's API. At this point, you should be able to send any custom data through the Hubble network and verify it arrives intact.

Video Demo

Want to see the entire process in action? In this video, I walk through the complete tutorial—from provisioning the nRF54L15 DK to building and flashing the firmware, then verifying the device using the Hubble Connect mobile app and the cloud dashboard.

Real-World Applications

Hubble's technology enables applications that were previously impractical with standard Bluetooth LE. Two use cases that make the most sense here:

Stolen Vehicle Recovery

Traditional GPS tracking modules and cellular modems are bulky, predictably placed (usually under the dashboard or in the engine compartment), and therefore quickly disabled by criminals who know exactly where to look. With Hubble, there's no telltale antenna or obvious hardware to rip out. A tiny Bluetooth LE beacon can be hidden virtually anywhere in a vehicle—for example, inside a door panel, within the seat cushion, or embedded in a non-obvious location. Since the beacon doesn't need a cellular signal or large GPS antenna, thieves have no easy way to locate and disable it.

This same principle applies broadly to stolen asset recovery—think high-value equipment, construction machinery, boats, trailers, or even expensive bicycles. Any asset that's at risk of theft can benefit from a tracking solution that's small, inconspicuous, and doesn't rely on easily-disabled cellular infrastructure.

Fleet Tracking

For logistics and transportation companies, tracking vehicles and cargo across vast distances (including areas with spotty cellular coverage) has traditionally required expensive satellite communicators or accepting gaps in visibility. Hubble enables continuous fleet tracking using inexpensive Bluetooth LE beacons, with the upcoming satellite network ensuring coverage even through remote highways, rural areas, and international routes.

Other Applications

Beyond vehicle and fleet tracking, you can think of any scenario where you need to know where something is (or that it's still there) without relying on cellular—agriculture sensors in remote fields, wildlife trackers, pipeline monitoring, shipping containers on ocean crossings. Hubble delivers not only better satellite connectivity but also lower power requirements than traditional cellular IoT solutions, which works well for battery-constrained deployments.

Next Steps

That's it—we now have a working Hubble Network beacon on the nRF54L15 DK, complete with custom sensor data. Here are some ways to extend this further:

Conclusion

In this tutorial, we covered a lot! We went from zero to a working Hubble beacon. We set up the nRF Connect SDK toolchain, cloned the Hubble SDK and reference app, provisioned our device key, and added temperature sensor reading as a custom payload. We then verified the whole thing end-to-end through the Hubble Connect app and cloud dashboard.

Here's what we covered:

At this point you should be comfortable integrating the Hubble SDK into your own nRF Connect SDK projects, provisioning devices, and deploying Bluetooth LE beacons with custom payload data that talk to Hubble's infrastructure.

The nRF54L15 paired with Hubble's network is a solid combination for IoT applications that need connectivity beyond cellular or WiFi. And once the satellite constellation goes live, your Bluetooth LE devices will be able to communicate from anywhere on Earth—no gateways required.

🚀
Try it yourself: The Hubble SDK works with standard Bluetooth LE chipsets—we used the nRF54L15 DK here, but you can use any supported platform. Head over to dash.hubble.com, sign up for a free Sandbox account, and start building.

Read next