One of the most common and valuable use cases for IoT is asset tracking. Whether for a vehicle, trailer, or shipping container, asset tracking is a powerful way for developers and companies to understand where an asset has been, where it is, and where it’s headed; all while monitoring the conditions of the asset itself.
The Cellular Notecard package contains nearly everything you need to build a cellular-powered asset tracker. This guide provides instructions for configuring your Notecard as a standalone asset tracker as well as an MCU host-controlled tracker.
This guide provides instructions for using the Notecard as both a standalone tracker, and with an MCU host. For both approaches, you’ll need the following:
- A Cellular Notecard.
- A Notecarrier with Cellular and GPS/GNSS antennas, and battery support. The Notecarrier-A and Notecarrier-AF have both antennas on-board, and provide a connector for a LiPo battery.
- A Micro USB cable.
If you’re building a standalone Notecard tracker, you’ll need the following:
- The Notecard CLI or the provided browser-based serial terminal for configuring the Notecard.
If you’re building a host-driven tracker, you’ll need the following:
- A microcontroller or single-board computer for communicating with the Notecard. The code samples in this guide target the Feather-compatible Swan running Arduino code, but can easily be adapted for your board of choice.
- Optional: An external sensor for gathering additional information about your asset. This guide uses a Bosch BME680 temperature and humidity sensor.
- A text editor for writing firmware, such as the Arduino IDE or VS Code.
To configure your Notecard as a tracker, you’ll need to do the following:
Perform a factory restore on the Notecard. This step is optional, but recommended as
card.restore
will perform a factory reset on the Notecard and clear out Notes and Notefiles from previous applications. Setting"delete":true
will also clear out all configuration settings.{"req":"card.restore","delete":true}
Set a Product UID, mode, and sync times with
hub.set
.periodic
is recommended for cases where your tracker will need to operate on battery power for extended periods of time. Theoutbound
andinbound
fields specify the interval, in minutes, that the Notecard should process outbound and inbound requests. These values also affect battery life, so use a value that makes sense for your application’s power and data sync needs. The Notecard will only sync on theoutbound
interval if un-synced tracking information is available, but will always sync on theinbound
interval in order to process new Notes and environment variables from Notehub.{ "req": "hub.set", "product": "com.veritas.delivery-fleet.tracker", "mode": "periodic", "outbound": 60, "inbound": 720 }
Set the Notecard to use
periodic
orcontinuous
location mode.periodic
is recommended for battery-powered applications, andcontinuous
for cases where low-latency location tracking is needed and power consumption is not a concern. When usingperiodic
, theseconds
field defines the interval at which to activate GPS and capture a location sample. Note: When inperiodic
mode, the GPS module will only activate to take a reading if the Notecard detects movement through its onboard accelerometer between interval periods.{ "req": "card.location.mode", "mode": "periodic", "seconds": 3600 }
Configure the Notecard to store tracking results in a tracking file that will be synced to Notehub, and set a heartbeat to check-in even if the device has not moved.
card.location.track
will store tracking-related data like location and temperature (as well as velocity, bearing, and distance ifcard.location.mode
is set tomode:continuous
, ormode:periodic
andseconds
< 300). This data is saved in a Notefile that will be sent to Notehub on each sync. The default file is_motion.qo
, but you can specify your own name with thefile
field. If you anticipate that your asset may be stationary for long periods of time, you can useheartbeat
andhours
to instruct the Notecard to create a tracking entry at a defined interval, regardless of motion. The Notecard does not switch on the GPS for heartbeats, since no movement has occurred. However the heartbeat provides confirmation that the Notecard tracker is still functioning correctly.{ "req": "card.location.track", "start": true, "heartbeat": true, "hours": 12 }
Once these requests have been sent to the Notecard, your tracker is ready to be deployed! The following two sections provide the specific steps for sending these requests for a standalone or host-controlled tracker.
To further customize your tracker, you can consult the Advanced Tracker Configuration section below.
The above commands will only work if the Notecard accelerometer is enabled. The
{"req":"card.restore","delete":true}
request enables the accelerometer, or
it can be enabled with the following request if previously disabled.
{"req":"card.motion.mode","start":true}
There are times where you simply want to track the location of your Notecard-connected asset and don’t need to gather data from an external sensor, or control how and when your Notecard should track and sync after deployment. In these cases, you can configure your Notecard as a standalone tracker by issuing a few requests from a connected computer, connect a battery, and deploy it to the asset to be tracked.
The fastest way to configure the Notecard in this way is with the
Notecard CLI,
which allows you to connect to a Notecard over USB Serial and issue
requests. The requests above can be sent individually using the req
or play
flag, or you can place all of the requests into a file with a json
extension
and use the setup
flag to send them all at once. This is a handy approach
when configuring multiple trackers for deployment.
notecard -setup configure-standalone-tracker.json
The Notecard will send each request in turn and output the result, like so:
{"req":"card.restore","delete":true} {} {"req":"hub.set","product":"com.veritas.delivery-fleet.tracker","mode":"periodic","outbound":60,"inbound":720} {} {"req":"card.location.mode","seconds":3600,"mode":"periodic"} {"seconds":3600,"mode":"periodic"} {"req":"card.location.track","start":true,"heartbeat":true,"hours":12} {"start":true,"hours":12,"heartbeat":true}
Once these requests complete, your Notecard will self-provision with Notehub and start tracking location and movement.
If your application needs to capture and sync additional location-tagged data during tracking, or you wish to control tracking modes and intervals at runtime, you can build a host-controlled tracker. In this scenario, the Notecard receives the same requests as above, with the difference being that these requests are sent from a host MCU and can be adjusted by that host depending on the needs of your application.
When host-controlled, you’ll configure the tracker in firmware after boot, and before entering the application loop. For instance, assume that you’re working with an Arduino-style host that will configure the Notecard as a tracker, and capture environmental readings from a BME680. You’ll start by making a serial connection to the Notecard, and sending each tracker configuration request:
#include <Notecard.h> #include <Wire.h> #include <seeed_bme680.h> #define usbSerial Serial #define txRxPinsSerial Serial1 #define productUID "com.veritas.delivery-fleet.tracker" #define IIC_ADDR uint8_t(0x76) Seeed_BME680 bmeSensor(IIC_ADDR); Notecard notecard; long previousMillis = 0; long interval = 60000 * 10; void setup() { usbSerial.begin(115200); notecard.setDebugOutputStream(usbSerial); notecard.begin(); J *req = notecard.newRequest("hub.set"); JAddStringToObject(req, "product", productUID); JAddStringToObject(req, "mode", "periodic"); JAddNumberToObject(req, "outbound", 60); JAddNumberToObject(req, "inbound", 720); notecard.sendRequest(req); req = notecard.newRequest("card.location.mode"); JAddStringToObject(req, "mode", "periodic"); JAddNumberToObject(req, "seconds", 3600); notecard.sendRequest(req); req = notecard.newRequest("card.location.track"); JAddBoolToObject(req, "sync", true); JAddBoolToObject(req, "heartbeat", true); JAddNumberToObject(req, "hours", 12); notecard.sendRequest(req); if (!bmeSensor.init()) { usbSerial.println("Could not find a valid BME680 sensor..."); } else { usbSerial.println("BME680 Connected..."); } }
This sample does not perform a card.restore
because doing so would wipe the
Notecard on each reset. The
full firmware source in GitHub
does show an example for performing a restore only when the Device's ProductUID
doesn't match the intended ProductUID.
Then, your application loop will capture readings, and add them as location-tagged Notes to the Notecard.
void loop() { unsigned long currentMillis = millis(); if ((currentMillis - previousMillis > interval) && notecardProductSet) { previousMillis = currentMillis; if (bmeSensor.read_sensor_data()) { usbSerial.println("Failed to obtain a reading..."); } else { J *req = notecard.newRequest("note.add"); if (req != NULL) { JAddStringToObject(req, "file", "sensors.qo"); J *body = JCreateObject(); if (body != NULL) { JAddNumberToObject(body, "temp", bmeSensor.sensor_result_value.temperature); JAddNumberToObject(body, "humidity", bmeSensor.sensor_result_value.humidity); JAddNumberToObject(body, "pressure", bmeSensor.sensor_result_value.pressure / 1000.0); JAddNumberToObject(body, "gas", bmeSensor.sensor_result_value.gas / 1000.0); JAddItemToObject(req, "body", body); } notecard.sendRequest(req); } } } }
Once the application firmware has been deployed to your device and tested, you can add a battery to your project and deploy it to your asset.
The host-controlled tracker has the added benefit of allowing you to adjust Notecard tracking settings in response to sensor readings or certain external conditions. For instance, you can change the mode or increase reading interval when the asset is in motion, and decrease it when the asset is idle for a period of time.
To further customize your tracker, you can consult the Advanced Tracker Configuration section below.
The complete source for both configuration approaches can be found in the Blues note-tutorials repository.
Once your tracker is deployed and the Notecard is provisioned,
it will synchronize tracking data in accordance with the configuration
settings you specified. Upon synchronization, you will be able to view your data in Notehub.io. For
both types, tracking entries will show up as Notes from the _motion.qo
Notefile (or the Notefile name you specified).
If you open an individual Note, you can view the Device location and Time Zone under the location tab.
In the JSON tab, you can see tracking data like bearing
, distance
and
velocity
in the Note body (which appear if the card.location.mode
is set to
mode:continuous
, or mode:periodic
and seconds
< 300), as well as the
location fields, all of which begin with where
and are available whenever a
GPS location is acquired.
If you’re using a host-controlled tracker and sending sensor readings in a Notefile, each Note is also tagged with the same where fields as tracking Notes.
Once your tracker is deployed and is synching to Notehub, you can use Routes to send tracker data to any third-party service (including your own custom endpoint) for additional processing and visualization. Notehub Routes can be configured to connect to any external service. Routes also give you the ability to send everything from all your Notecards, targeted fleets, or even Notefiles, and to transform event data before you route it to an external service.
For example, if you wanted to
create a Route to send only the data you need from a _motion.qo
Note to an
external service, you could use a JSONata transformation like this:
{ "location": { "where": where, "latitude": where_lat, "longitude": where_lon, "location": where_location, "country": where_country, "time_zone": where_timezone }, "motion": { "bearing": body.bearing, "distance": body.distance, "seconds": body.seconds, "velocity": body.velocity }, "captured_time": when, "sync_time": routed }
JSONata is a powerful data-transformation language built into Notehub, and you can learn more about it in our JSONata 1-2-3 guide and learn about the process of creating third-party Routes in the Route Tutorials.
The Notecard API commands provided above allow you to configure a basic asset tracker with settings applicable to the most common tracking scenarios. However, your scenario may be unique, which is why diving into the Notecard APIs can reveal additional customizations to optimize your trackers.
You can specify how frequently you would like the device to sample its GPS
location with the
card.location.mode
API and its seconds
parameter:
{"req":"card.location.mode","mode":"periodic","seconds":5}
When in periodic
mode, the Notecard will only attempt to sample its GPS
location when the onboard accelerometer has detected motion. You can increase
the sensitivity of the accelerometer with the
card.motion.mode API
and its sensitivity
parameter:
{"req":"card.motion.mode","sensitivity":2}
In order to save battery life, the Notecard will only attempt to sync
accumulated tracking data on the intervals provided in the outbound
parameter
of your hub.set
request. However, if you would like to attempt to sync data
with Notehub immediately, you can set the "sync":true
parameter of the
card.location.track
API:
{"req":"card.location.track","sync":true}
Since asset trackers are often in the field for extended periods of time, it is
generally wise to optimize battery consumption. By using the
card.voltage API's mode
parameter, you can specify the type of battery being used:
{"req":"card.voltage","mode":"lipo"}
The mode
value is subsequently used in both the hub.set
and
card.location.track
calls to specify the frequency at which outbound, inbound,
and GPS location sampling should occur (i.e. you want the device to make these
calls less frequently as battery voltage decreases).
To set the frequency of syncing outbound data with Notehub:
{"req":"hub.set","voutbound":"usb:30;high:60;normal:120;low:240;dead:0","vinbound":"usb:30;high:360;normal:720;low:1440;dead:0"}
To set the frequency of gathering GPS location data:
{"req":"card.location.mode","mode":"periodic","vseconds":"usb:1800;high:3600;normal:7200;low:43200;dead:0"}
The Low Power Design guide dives into additional configuration options that can be used to optimize power consumption on the Notecard.
When prototyping an asset tracking solution, it may be useful to gather as much
data about the device as possible in the field. To do so, you can set the _log
environment variable
to all
. Note that this will use additional cellular data on your Notecard due
to the extensive log data sent to Notehub.
{"req":"env.default","name":"_log","text":"all"}