Skip to main content
For the complete documentation index, see llms.txt.

Hubble Network developer documentation: integrate Bluetooth devices with terrestrial and satellite connectivity.

Satellite Quick Start


Overview​

This guide takes you from an unconfigured device such as a developer kit to confirmed satellite packet reception, then to efficient transmission via pass prediction. Read alongside the Hubble Satellite Network Transmission Guidance. View supported Bluetooth® developer kits for satellite transmission.

Onboarding can run multiple days: satellite passes are periodic and brief, so end-to-end confirmation waits on real passes. However, you can validate locally (Step 5) so the device is proven well before the first pass.

Resources​

Pick your path​

  1. Pre-flashed eval device from Hubble: no software development kit (SDK), Pluto, or firmware work. Go straight to Steps 6 to 7.
  2. Supported dev board / reference platform: flash a reference sample, validate, customize payload. Steps 1 to 5 go fast (known-good hardware).
  3. Custom hardware: same path plus SDK bring-up. Run a reference sample on a supported board first (Steps 3 to 5) to see what "working" looks like, then port in Step 8.

Prerequisites​

RequirementDetail
Supported deviceA supported SoC and ≥ +20 dBm transmit power (requires a PA/FEM, or an SoC with an integrated one).
The fastest start is a developer kit validated for satellite that reaches +20 dBm out of the box.
Hubble organizationA Hubble account with Hubble Live access (Terrestrial and Satellite). Sandbox does not have Satellite access.
If your organization does not have Satellite access, reach out to support@hubble.com.
Clear sky viewAn outdoor placement with unobstructed sky. Indoor testing will not reach a satellite (see Step 6).

Optional Resources​

ResourceDetail
Pluto SDR (recommended)An ADALM-PLUTO over USB, plus Docker, to validate transmission locally in Step 5.
pyhubblenetwork CLIPython 3 and pip install pyhubblenetwork, for Pluto scans and device registration.
API token (pass prediction only)A token with the read-satellites scope, exported as HUBBLE_API_TOKEN, to fetch orbital parameters in Step 9.

1. Qualify the device​

Confirm the device can physically reach the network before any integration. Most of this cannot be fixed in firmware later.

SoC and transmit power are both covered on the Chip Compatibility page: your chip must be on the supported list and reach ≥ +20 dBm. That page also lists the developer kits validated for satellite if you want known-good hardware.

Two further requirements are specific to satellite transmission:

RequirementDetail
Antenna≥ 40% efficiency at 2.4825 GHz (standard patch recommended).
Crystal40 PPM crystal.

2. How it works​

Hubble Terrestrial Network uses a standard Bluetooth® Low Energy (BLE) advertisement that nearby gateways relay to the cloud. The Satellite Network uses a custom Hubble protocol received directly by an overflying satellite, reusing your existing BLE radio (no separate satellite radio).

One or more satellites pass overhead each day, each in view briefly. A dual-mode device pauses BLE, initiates Satellite and transmits repeatedly while the satellite is in view, then hands the radio back. An efficient device predicts passes and transmits only when a satellite is overhead (Step 9 below) instead of transmitting blind.

See a basic diagram for how Satellite Network works.

3. Register and provision​

Register a new device at dash.hubble.com to provision a secret device key (same for Satellite and Terrestrial; see Onboard devices guide).

Device Registration​

Via the Hubble dashboard (look for “Add a Device” in the top right, then "I just need a device key") or via pyhubblenetwork (see documentation on the repository README).

Device Configuration​

Register with counter mode set to DEVICE_UPTIME for development. The counter starts at zero and advances with uptime, so no time provisioning is needed, and it matches the continuous sample in Step 4. (Production devices using pass prediction (to know when a satellite is overhead to transmit to) should register with UNIX_TIME, but this quick start guide, DEVICE_UPTIME is simpler due to the lack of timing requirements.)

The firmware's counter source must match the registration or the backend cannot attribute/decrypt. Save device ID + key together. You need the device key twice: embedded in firmware, and for local Pluto SDR decryption (Step 5).

4. Build a transmitting device​

Start with the continuous-transmit sample: a simple TX loop that confirms hardware and backend config in isolation.

  1. Pull the SDK from main.
  2. Fetch the radio blob first (Nordic + SiLabs). west update does not pull it, and the build fails to link the satellite radio without it:
west blobs fetch
  1. Flash the continuous sample: Zephyr sat-continuous or TI sat-continuous. Provide your base64 device key at build time (Zephyr):
west build -b nrf54l15dk/nrf54l15/cpuapp . -- -DCONFIG_SAMPLE_HUBBLE_KEY=\"<base64 key>\"
west flash

Note: TI is make-based (not west) and you supply the crypto implementation; the sample ships a ready one. See the TI README.

Note: A clean build only proves it compiles, not that the radio transmits (confirm in Step 5). Ship the default config first: continuous TX at a fixed interval, empty 0-byte payload.

5. Validate locally with a Pluto SDR​

Validating a device using the Pluto SDR helps ensure that the radio is transmitting correctly and that the encrypted link is valid. This cannot validate the full end-to-end path, but it catches problems within minutes instead of waiting on a real pass. Requires an ADALM-PLUTO over USB and Docker running.

pip install pyhubblenetwork
hubblenetwork sat scan # stream until Ctrl+C
hubblenetwork sat scan --key "<device key>" # decrypt payload locally

Success means packets attributed to your device ID with incrementing sequence numbers. The scan sends nothing to the cloud, so it will not appear in the dashboard. Cloud reception needs a real satellite pass (Step 7).

See Test with a Pluto SDR for Pluto setup, the full scan reference, and how to capture IQ samples for Hubble support if the scan finds nothing.

6. Place the device​

Placement matters as much as firmware: the device needs a clear shot at the satellite.

  • Outdoors, clear skyview in as many directions as possible. Rooftop is ideal.
  • Test a couple of orientations (rotating one device can lose signal noticeably).
  • Clear of obstructions, large metal, and liquids.
  • Space multiple devices at least 6” (15cm) apart.

7. Confirm reception​

Cloud reception is the real confirmation and needs a transmission to a satellite during an actual pass.

Timing​

One or more passes per day for your location on a periodic schedule. Check the Pass Explorer page on dash.hubble.com for the next pass before assuming anything is wrong, and give it several passes. Packets should be available from a pass within 6 hours of the pass occurring - note that this is not instantaneous.

How to check for packet reception​

Open dash.hubble.com, select the device, look for received packets with the expected payload and a satellite icon (indicates the packet came via the satellite network).

Seeing your packet in the dashboard closes the full chain (firmware to RF to satellite to backend).

8. Integrate into your own firmware​

Fold satellite functionality into your application/RTOS. Mirror the continuous sample first (simple loop), then re-validate against Pluto and a live satellite exactly as before to isolate changes. See documentation in the Hubble Device SDK on how to perform the integration of firmware onto your device.

9. Pass prediction (transmit efficiently)​

In order to conserve power, a device can use the Hubble pass prediction algorithm to transmit only during windows when a satellite is overhead.

Prerequisites​

Real Unix time on the device at init (baked in or provisioned over BLE) and the device location (coordinates). You also need a Hubble API Token, which you can generate from your Hubble Dashboard.

Provision with Pass Prediction​

  1. Fetch current orbital parameters: SDK tools/orbital_params_fetch.py calls the Hubble API and writes them out; needs HUBBLE_API_TOKEN exported.
  2. Provision the parameters onto the device (firmware or runtime over BLE).
  3. Set time on the device (note if you are using the DEVICE_UPTIME based counter mode for encryption from previous steps you will need to use the hubble_set_time API in firmware to set the device time).
  4. Use the SDK pass-prediction calls: get the next pass, wake shortly before it, transmit across the window, sleep.

Reliability modes: higher reliability repeats the transmission more times per pass (better delivery, more power/airtime). We recommend starting with the HIGH reliability mode and moving to NORMAL if performance is acceptable.

10. Tune performance​

Once receiving end to end, run the continuous sample, check packets delivered per pass, and tune transmission count and reliability mode against your delivery and power budget. Your Hubble contact can share per-pass performance data.

11. Troubleshooting​

IssueResolution
No RF on local PlutoConfirm device is transmitting, Pluto is connected before the scan starts, and Docker is running.
Decoded locally but never in the cloudLocal scan doesn't push to the cloud (needs real pass). Confirm device is in the right org, and that firmware key, key size (16 vs 32 byte), and counter mode match the registration.
Payload rejectedLength must be exactly 0, 4, 9, or 13 bytes.
Key formation errorIf converting base64 to raw bytes, verify it. A wrong/wrong-size key is rejected at startup with a logged error.
Radio blob missing (Zephyr)Verify blob was fetched in Step 4.
Other issuesReach out to Hubble support (support@hubble.com).