Help Shape What We Build Next: Take the 2026 Blues Developer Survey

Blues Developers
What’s New
Resources
API Reference
Notecard and Notehub API documentation
Blog
Technical articles for developers
Connected Product Guidebook
In-depth guides for connected product development
Developer Certification
Get certified on wireless connectivity with Blues
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Webinars
Listing of Blues technical webinars
Blues.comNotehub
Shop
Docs
Help
Support DocsNotehub StatusSecurity AdvisoriesVisit our Forum
Sign In
Docs Home
What’s New
Resources
API Reference
Notecard and Notehub API documentation
Blog
Technical articles for developers
Connected Product Guidebook
In-depth guides for connected product development
Developer Certification
Get certified on wireless connectivity with Blues
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Webinars
Listing of Blues technical webinars
Blues.comNotehub
Shop
Docs
Example Apps
Samples
Building a Simple Asset Tracker
Building Edge AI Applications
Continuous Asset Tracking with External GPS and Immediate Location Sync
Controlling Device State and Receiving Acknowledgment
Taking an Immediate GPS Reading
IntroductionGeneral InformationSummaryTechnical ImplementationReading Location on DemandComplete FirmwareAdditional Resources
Managing a Notecard's WiFi Network Remotely
Putting a Host to Sleep Between Sensor Readings
Routing Data from Notehub to a Custom Cloud Endpoint
Using LEDs and NeoPixels to Monitor Notecard Status
Accelerators
Asset Location Tracking
Heavy Equipment Hours-of-Use & Utilization Tracker
Returnable Container / Tote Pool Tracker
Untethered Trailer and Chassis Fleet Tracker
Asset Performance Optimization
Legacy Diesel Generator Fleet Performance Uplift
Solar Array String-Level Performance Dashboard
Battery Management Systems
Aerial Lift / Rental Equipment Battery Health Monitor
Off-Grid Solar Battery Site Controller
Remote Cabinet Backup Battery Sentinel
Downtime Prevention
Municipal Wastewater Lift Station Monitor
Rooftop HVAC Predictive Maintenance
VFD Pump Predictive Maintenance
Energy Monitoring Solutions
Commercial Tenant Sub-Metering Bridge
EV Charger Session & Utilization Monitor
Utility Distribution Transformer Load Monitor
Energy Savings
Commercial Plug-Load & After-Hours Waste Dashboard
Demand-Response Solar + Battery Dispatcher
Multi-Site Walk-In Cooler Energy & Setpoint Monitor
Industrial Equipment Monitoring
CNC Machine Spindle Load and Cycle Time Tracker
Injection Molding Shot-to-Shot Process Monitor
Trailer Manufacturer Connected Trailer Platform
Loss Prevention
Construction Equipment Anti-Theft Tracker with Immobilizer
Reefer Trailer Cold-Chain & Door-Event Monitor
Remote Patient Monitoring
Cellular Medication Adherence Pillbox
Post-Discharge Vitals Relay Hub
Remotely Monitored Assets
Off-Grid Livestock Water Tank Monitor
Remote Apiary Hive Health Monitor
Safety Assurance
Construction Site Environmental & Noise Exposure Monitor
Lone Worker Panic and Fall Detection Beacon
Regulatory-Grade Pharmacy and Lab Cold Storage Audit Monitor
Supply Chain Tracking
Pallet-Attached Cold Chain Logger
Rail Car Condition & Interchange Tracker
Truck Roll Reduction
Commercial Grease Interceptor Level Monitor
Propane / LPG Tank Fill Telemetry
homechevron_rightDocschevron_rightExample Appschevron_rightSampleschevron_rightTaking an Immediate GPS Reading

Taking an Immediate GPS Reading

Introduction

This sample app shows how to make a Notecard-based tracker take a GPS/GNSS reading on demand. Most trackers sample their location on a schedule to save power, but some events can't wait for the next scheduled reading. A lone worker pressing a panic button, a vehicle detecting a crash, or a technician asking a device to check in all need an accurate location right away.

The sample's firmware waits for a button press, takes an immediate location reading, sends an SOS Note with the result to the cloud, and then returns the tracker to its normal, power-saving location schedule.

Wireless Connectivity with Blues

This sample app is built around the Blues Notecard and Blues Notehub.

The Blues Notecard is the easiest way for developers to add secure, robust, and affordable pre-paid wireless connectivity to their microcontroller or single-board computer of choice. Notecard is a System-on-Module (SoM) that combines pre-paid data, low-power hardware (~8μA-18μA when idle), and secure communications. It acts as a device-to-cloud data pump to communicate with the Blues cloud service Notehub.

Notehub is the Blues cloud service for routing Notecard-provided data to third-party cloud applications, deploying OTA firmware updates, and securely managing fleets of Notecards. Notehub allows for secure communications between edge devices and the cloud without certificate management or manual provisioning of devices.

General Information

System Hardware

This sample's pattern works with any Notecard that has access to a GPS/GNSS module, and any host microcontroller or single-board computer. For demonstration purposes, this sample uses the following hardware.

ComponentPurpose
Blues Notecard Cell+WiFiWireless connectivity module with built-in GNSS for location tracking.
Blues Notecarrier CXCarrier board with an onboard STM32L433 host MCU (Cygnet), a programmable USER_BTN button, and a LiPo connector.
Single-cell 3.7V LiPo battery with a 2-pin JST PH connectorPower source.

The same steps apply if your Notecard gets its location from an external GPS/GNSS module or a paired Starnote.

List of Acronyms

AcronymDefinition
MCUMicrocontroller
SoMSystem-on-Module
GPSGlobal Positioning System, a satellite-based radio navigation system
GNSSGlobal Navigation Satellite System, a generic term for any satellite constellation that provides positioning and timing services
SOSA distress signal, used here for a high-priority alert that includes the device's location

Summary

A battery-powered tracker usually runs Notecard's location sampling in periodic mode, where Notecard powers on its GPS/GNSS module at an interval you choose, and only when its accelerometer says the device has moved. That schedule is what lets a tracker last for months on a battery, but it also means the most recent location can be minutes or hours old.

Notecard doesn't have a single "read my location now" request. Instead, a host can get the same result by temporarily switching Notecard's location mode to continuous, which starts a GPS/GNSS search immediately, and then switching it back once a new reading arrives. The pattern has four steps:

  1. Record the time of Notecard's last location reading.
  2. Switch Notecard to continuous location mode.
  3. Poll Notecard until it reports a reading with a newer time, or until the search times out.
  4. Restore Notecard's periodic location mode.

Because continuous mode keeps the GPS/GNSS module powered, the host should only stay in it long enough to get the reading it needs.

Requirements

  1. A Notehub project to receive the SOS Notes. Create a free project at notehub.io.
  2. A host microcontroller or single-board computer that controls Notecard, and some event that should trigger a reading. This sample uses a button press.
  3. A GPS/GNSS antenna with a clear view of the sky.

Technical Implementation

tip

Let AI write your firmware. Blues Expert MCP connects your AI coding assistant (Claude Code, Codex, GitHub Copilot, Cursor) directly to our API docs, providing live request validation and firmware best practices for Arduino, C, Zephyr, and Python. Install the Blues Expert MCP →

The sections below walk through the pattern one step at a time, then put it together in a complete firmware sample. The Notecard requests are the same no matter which language your host runs, so you can implement this pattern with any of the Notecard SDKs. This sample's host firmware uses the Notecard Arduino library.

Hardware Setup

This sample assumes you know how to connect Notecard to the Notecarrier CX, and how to flash firmware to the Notecarrier CX's host. If not, start with the Notecard Quickstart and the Notecarrier CX Quickstart.

Notecard Configuration

Let's start with a standard Notecard configuration for a battery-powered tracker: syncing with Notehub periodically, and sampling its location on a schedule. This is the configuration the tracker runs most of the time, and the one it returns to after each immediate reading. The firmware sends these requests every time it boots, and Notecard saves them to flash.

First, the hub.set API associates Notecard with your Notehub project. periodic mode keeps the cellular modem off between syncs, which saves power and leaves the modem free of the built-in GPS/GNSS module, since the two can't run at the same time.

{
  "req": "hub.set",
  "product": "<your-product-uid>",
  "mode": "periodic",
  "outbound": 60,
  "inbound": 240
}
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "product", "<your-product-uid>");
JAddStringToObject(req, "mode", "periodic");
JAddNumberToObject(req, "outbound", 60);
JAddNumberToObject(req, "inbound", 240);

NoteRequest(req);
req = {"req": "hub.set"}
req["product"] = "<your-product-uid>"
req["mode"] = "periodic"
req["outbound"] = 60
req["inbound"] = 240

rsp = card.Transaction(req)

Next, the card.location.mode API sets the tracker's normal location schedule. Here, Notecard samples its location at most once an hour, and only if it has moved.

{
  "req": "card.location.mode",
  "mode": "periodic",
  "seconds": 3600
}
J *req = NoteNewRequest("card.location.mode");
JAddStringToObject(req, "mode", "periodic");
JAddNumberToObject(req, "seconds", 3600);

NoteRequest(req);
req = {"req": "card.location.mode"}
req["mode"] = "periodic"
req["seconds"] = 3600

rsp = card.Transaction(req)

Reading Location on Demand

Now that you know the configuration to use, let's look at the steps you need to take to get an immediate reading.

Step 1: Store the Time of the Last Location Reading

Notecard stores its last-known location so that you can retrieve it with a card.location request.

{
  "req": "card.location"
}
J *req = NoteNewRequest("card.location");

NoteRequest(req);
req = {"req": "card.location"}

rsp = card.Transaction(req)

The response includes a time, which is when Notecard captured that location:

{
 "status": "GPS updated (478 sec, 27/33 dB SNR, 4/7 sats, HDOP 1) {gps-active} {gps-signal} {gps-sats} {gps}",
 "mode": "periodic",
 "lat": 43.96320156666668,
 "lon": -83.24814393333334,
 "time": 1657306363
}

Store that time on your host. In a later step, a different time tells you Notecard has taken a new reading. If Notecard has never taken a reading, the response has no time, and the code below stores 0.

J *rsp = notecard.requestAndResponse(notecard.newRequest("card.location"));
JTIME lastFixTime = JGetInt(rsp, "time");
notecard.deleteResponse(rsp);

Step 2: Turn On Continuous GPS/GNSS Mode

Next, force Notecard to take a new reading as quickly as possible by setting its location mode to "continuous".

{
  "req": "card.location.mode",
  "mode": "continuous"
}
J *req = NoteNewRequest("card.location.mode");
JAddStringToObject(req, "mode", "continuous");

NoteRequest(req);
req = {"req": "card.location.mode"}
req["mode"] = "continuous"

rsp = card.Transaction(req)

Step 3: Wait for the Reading

In continuous mode, Notecard starts a GPS/GNSS search immediately. A reading isn't instantaneous, though, and can take anywhere from seconds to minutes depending on your antenna and its view of the sky.

To wait for it, make card.location requests in a loop. While Notecard is searching, the response only contains status information:

{
 "status": "GPS search (201 sec, 34/34 dB SNR, 0/1 sats, HDOP 0) {gps-active} {gps-signal} {gps-sats}",
 "mode": "continuous"
}

Once Notecard has a reading, the response includes the new latitude, longitude, and time. When that time differs from the one you stored in step 1, you have a new reading. The code below also checks that time is present, because a request that fails returns no time at all.

If the tracker can't see the sky, the search may never succeed, and an endless loop would drain its battery. So the loop below gives up after five minutes, or as soon as Notecard returns "stop": true, which it does in continuous mode when it can't find a GPS/GNSS signal.

const uint32_t timeoutMs = 5 * 60 * 1000;
const uint32_t startMs = millis();

while (millis() - startMs < timeoutMs) {
  J *rsp = notecard.requestAndResponse(notecard.newRequest("card.location"));

  if (JIsPresent(rsp, "time") && (JTIME)JGetInt(rsp, "time") != lastFixTime) {
    double lat = JGetNumber(rsp, "lat");
    double lon = JGetNumber(rsp, "lon");
    // Use the new coordinates here.
    notecard.deleteResponse(rsp);
    break;
  }

  bool noSignal = JGetBool(rsp, "stop");
  notecard.deleteResponse(rsp);
  if (noSignal) {
    break;
  }

  delay(2000);
}

Step 4: Restore Your GPS/GNSS Configuration

Once you have a reading, or have given up on one, restore the tracker's normal location mode, as staying in continuous mode uses a considerable amount of battery.

{
  "req": "card.location.mode",
  "mode": "periodic"
}
J *req = NoteNewRequest("card.location.mode");
JAddStringToObject(req, "mode", "periodic");

NoteRequest(req);
req = {"req": "card.location.mode"}
req["mode"] = "periodic"

rsp = card.Transaction(req)

card.location.mode remembers the arguments you passed in previous calls, so you don't need to pass seconds again.

Complete Firmware

The sketch below combines the configuration and the four steps above. When you press the Notecarrier CX's USER_BTN button, it lights LED_BUILTIN, takes an immediate reading, restores periodic mode, and adds an SOS Note to sos.qo with "sync": true so that Notecard sends it to Notehub right away. If the search fails, the Note is still sent, without coordinates.

Replace <your-product-uid> with your Notehub project's ProductUID before flashing. To see the sketch's Serial output, power the board over USB with the DIP switch next to the USB-C connector in the HST position.

#include <Notecard.h>

#define PRODUCT_UID "<your-product-uid>"

// How often Notecard samples its location when it isn't handling an SOS.
#define LOCATION_INTERVAL_SECONDS 3600

// How long to wait for an immediate reading before giving up.
#define FIX_TIMEOUT_MS (5 * 60 * 1000UL)

Notecard notecard;
volatile bool buttonPressed = false;

void onButtonPress() {
  buttonPressed = true;
}

JTIME getLastFixTime() {
  J *rsp = notecard.requestAndResponse(notecard.newRequest("card.location"));
  JTIME time = JGetInt(rsp, "time");
  notecard.deleteResponse(rsp);
  return time;
}

void setLocationMode(const char *mode) {
  J *req = notecard.newRequest("card.location.mode");
  JAddStringToObject(req, "mode", mode);
  notecard.sendRequest(req);
}

// Polls card.location until it reports a reading newer than lastFixTime.
// Returns false on timeout, or if Notecard reports it can't find a signal.
bool waitForNewFix(JTIME lastFixTime, double *lat, double *lon) {
  const uint32_t startMs = millis();

  while (millis() - startMs < FIX_TIMEOUT_MS) {
    J *rsp = notecard.requestAndResponse(notecard.newRequest("card.location"));

    if (JIsPresent(rsp, "time") && (JTIME)JGetInt(rsp, "time") != lastFixTime) {
      *lat = JGetNumber(rsp, "lat");
      *lon = JGetNumber(rsp, "lon");
      notecard.deleteResponse(rsp);
      return true;
    }

    bool noSignal = JGetBool(rsp, "stop");
    notecard.deleteResponse(rsp);
    if (noSignal) {
      return false;
    }

    delay(2000);
  }

  return false;
}

void sendSOS() {
  JTIME lastFixTime = getLastFixTime();
  setLocationMode("continuous");

  double lat = 0;
  double lon = 0;
  bool located = waitForNewFix(lastFixTime, &lat, &lon);

  setLocationMode("periodic");

  J *req = notecard.newRequest("note.add");
  JAddStringToObject(req, "file", "sos.qo");
  JAddBoolToObject(req, "sync", true);
  J *body = JAddObjectToObject(req, "body");
  JAddBoolToObject(body, "located", located);
  if (located) {
    JAddNumberToObject(body, "lat", lat);
    JAddNumberToObject(body, "lon", lon);
  }
  notecard.sendRequest(req);

  Serial.println(located ? "SOS sent with location." : "SOS sent without a GPS fix.");
}

void setup() {
  Serial.begin(115200);
  delay(1000);

  notecard.begin();
  notecard.setDebugOutputStream(Serial);

  J *req = notecard.newRequest("hub.set");
  JAddStringToObject(req, "product", PRODUCT_UID);
  JAddStringToObject(req, "mode", "periodic");
  JAddNumberToObject(req, "outbound", 60);
  JAddNumberToObject(req, "inbound", 240);
  notecard.sendRequest(req);

  req = notecard.newRequest("card.location.mode");
  JAddStringToObject(req, "mode", "periodic");
  JAddNumberToObject(req, "seconds", LOCATION_INTERVAL_SECONDS);
  notecard.sendRequest(req);

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(USER_BTN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(USER_BTN), onButtonPress, FALLING);
}

void loop() {
  if (!buttonPressed) {
    delay(50);
    return;
  }

  digitalWrite(LED_BUILTIN, HIGH);
  sendSOS();
  digitalWrite(LED_BUILTIN, LOW);

  // Ignore any presses that arrived while the SOS was in progress.
  buttonPressed = false;
}

Expected Results

Notecard needs to complete its first sync with Notehub before it enables GPS/GNSS, so give a newly-configured tracker a few minutes before pressing the button.

After you press USER_BTN, the red LED stays on while Notecard searches for a location. Once it turns off, an sos.qo event appears in your Notehub project:

{
  "file": "sos.qo",
  "body": {
    "located": true,
    "lat": 43.96320156666668,
    "lon": -83.24814393333334
  }
}

If located is false, Notecard couldn't get a reading within the timeout. Notehub still adds a tower-based location to every event in its best_* fields, so you know roughly where the device was.

Potential Issues

  1. No GPS/GNSS fix: Confirm the GPS/GNSS antenna is connected and has a clear view of the sky. The first reading in a new location can take several minutes. See Diagnosing GPS Issues on the Notecard for more information.
  2. SOS Note doesn't reach Notehub: Verify the cellular antenna is connected and that the device is within cellular coverage. See Diagnosing Cellular Connectivity Issues for more information.

Additional Resources

  • Asset Tracking with GPS Guide
  • Working with GPS on the Notecard
  • Diagnosing GPS Issues on the Notecard
  • Building a Simple Asset Tracker
  • Notecarrier CX Quickstart
Can we improve this page? Send us feedback
© 2026 Blues Inc.
© 2026 Blues Inc.
AboutDocsAPI ReferenceTermsPrivacy