nRF9160: Asset Tracker v2¶
The Asset Tracker v2 is a real-time configurable ultra-low power capable application firmware for the nRF9160 System in Package (SiP). It is a complete rework of the nRF9160: Asset Tracker application. This application introduces a set of new features, which are not present in the nRF9160: Asset Tracker application:
Ultra-low power by design - The application highlights the power saving features of the nRF9160 SiP, which is critical for successfully developing small form-factor devices and products which need very long battery lifetime.
Offline first - Highly-mobile cellular IoT products need to handle unreliable connections gracefully by implementing mechanisms to retry the failed sending of data.
Timestamping on the device - Sensor data is timestamped on the device using multiple time sources. When the device is offline (planned or unplanned), the timestamping does not rely on the cloud side.
Batching of data - Data can be batched to reduce the number of messages transmitted, and to be able to retain collected data while the device is offline.
Configurable at run time - The application behavior (for example, accelerometer sensitivity or GPS timeout) can be configured at run time. This improves the development experience with individual devices or when debugging the device behavior in specific areas and situations. It also reduces the cost for transmitting data to the devices by reducing the frequency of sending firmware updates to the devices.
Implementation of the above features required a rework of the existing application. Hence, this application is not backward compatible to the nRF9160: Asset Tracker application.
Note
The code is currently a work in progress and is not fully optimized yet. It will undergo changes and improvements in the future.
Overview¶
The application samples sensor data and publishes the data to a connected cloud service over TCP/IP via LTE. As of now, the application supports the following cloud services and the corresponding cloud-side instances:
Cloud service |
Cloud-side instance |
---|---|
Firmware architecture¶
The Asset Tracker v2 application has a modular structure, where each module has a defined scope of responsibility. The application makes use of the Event Manager to distribute events between modules in the system. The event manager is used for all the communication between the modules. A module converts incoming events to messages and processes them in a FIFO manner. The processing happens either in a dedicated processing thread in the module, or directly in the event manager callback.
The following figure shows the relationship between the modules and the event manager. It also shows the modules with thread and the modules without thread.
See Internal modules for more information.
Data types¶
Data from multiple sensor sources are collected to construct information about the location, environment, and the health of the nRF9160-based device. The application supports the following data types:
Data type |
Description |
Identifiers |
---|---|---|
Location |
GNSS coordinates |
APP_DATA_GNSS |
Environmental |
Temperature, humidity |
APP_DATA_ENVIRONMENTAL |
Movement |
Acceleration |
APP_DATA_MOVEMENT |
Modem |
LTE link data, device data |
APP_DATA_MODEM_DYNAMIC, APP_DATA_MODEM_STATIC |
Battery |
Voltage |
APP_DATA_BATTERY |
The sets of sensor data that are published to the cloud service consist of relative timestamps that originate from the time of sampling.
Device modes¶
The application can be either in an active or in a passive state depending on the applied device mode. The device mode is a part of the application’s real-time configurations. The device modes and their descriptions are listed in the following table:
Real-time Configurations |
Description |
Default values |
|
---|---|---|---|
Device mode |
Either in active or passive mode. |
Active |
|
Active |
Sample and publish data at regular intervals. |
||
Active wait time |
Number of seconds between each sampling/publication. |
120 seconds |
|
Passive |
Sample and publish data only if movement has been detected. |
||
Movement resolution |
Sample and publish data after detecting movement. Wait for a duration specified by the parameter until a movement triggers the next update. |
120 seconds |
|
Movement timeout |
Sample and publish data at a minimum of the time interval specified by the parameter. Not dependent on movement. |
3600 seconds |
|
GPS timeout |
Timeout for acquiring a GPS fix during sampling of the data. |
60 seconds |
|
Accelerometer threshold |
Accelerometer threshold in m/s². Minimal absolute value in m/s² for the accelerometer readings to be considered as a valid movement. |
10 m/s² |
See Kconfig options for default device configuration values for a list of configuration options that can set the default values of the device configuration parameters.
Note
The configurations that are used depend on the application state.
For instance, in active mode, the Movement resolution
and the Movement timeout
parameters are not used.
The following flow charts shows the functioning of the application in active and passive states. The charts also show the relationship between data sampling, publishing, and device configurations. All the configurations that are not essential to this relationship are abstracted for simplicity.
In the active state, the application samples and publishes data at regular intervals that are set by the Active wait timeout
configuration.
In the passive state, the application will only sample and publish upon movement.
This reduces the amount of data transferred over the air and the numerous processing cycles.
The flow chart does not include the timer that acts on the Movement timeout
configuration.
This timer is enabled when the application enters the passive state.
When the timer expires, the application will initiate data sampling and publishing.
The timer ensures that if there is no movement, the application still sends updates to the cloud service.
The timeout acts as a failsafe in the case of zero movement for the asset wearing the tracker over a long time.
Ideally, the Movement timeout
parameter should be set to a value much higher than the value of Movement resolution
.
The device retrieves its real-time configurations from the cloud service in either of the following ways:
Upon every established connection to the cloud service, the application will always request its cloud-side device state that contains the latest real-time configurations.
When the device exits Power Saving Mode (PSM) to publish data, and if the cloud-side device configuration has been updated while the device was in PSM, the application will request for the newly changed configuration.
The application always acknowledges any newly applied device configurations back to the cloud service.
Note
The application always stores any new configuration obtained from the cloud service to the flash memory. If the device reboots unexpectedly in areas without LTE coverage, the application will have access to the configuration that was applied last.
Data buffers¶
Data sampled from the onboard modem and the external sensors is stored in ring buffers. Newly sampled data is always published prior to the old, buffered data.
The application has LTE and cloud connection awareness. Upon a disconnect from the cloud service, the application keeps the sensor data that has been buffered and empty the buffers in batch messages when the application reconnects to the cloud service.
User interface¶
The application uses the following buttons on the nRF9160-based development kits:
Button 1 on Thingy:91
Button 1 and Button 2 on nRF9160 DK
Additionally, the application displays LED behavior that corresponds to the task performed by the application. The following table shows the purpose of each supported button:
Button |
Thingy:91 |
nRF9160 DK |
---|---|---|
1 |
Send message to the cloud service |
Send message to the cloud service. |
2 |
Send message to the cloud service. |
|
Fake movement. No external accelerometer in nRF9160 DK to trigger movement in passive mode. |
The following table shows the LED behavior demonstrated by the application:
State |
Thingy:91 RGB LED |
nRF9160 DK solid LEDs |
---|---|---|
LTE connection search |
Yellow, blinking |
LED1 blinking |
GPS fix search |
Purple, blinking |
LED2 blinking |
Publishing data |
Green, blinking |
LED3 blinking |
Active mode |
Light blue, blinking |
LED4 blinking |
Passive mode |
Dark blue, slow blinking |
LED4 slow blinking |
Error |
Red, on |
all 4 LEDs blinking |
Completion of FOTA Update |
White, rapid blinking |
all 4 LEDs on |
Requirements¶
The application supports the following development kits:
Hardware platforms |
PCA |
Board name |
Build target |
---|---|---|---|
PCA20035 |
thingy91_nrf9160 |
|
|
PCA10090 |
|
The sample is configured to compile and run as a non-secure application on nRF91’s Cortex-M33. Therefore, it automatically includes the Secure Partition Manager that prepares the required peripherals to be available for the application.
You can also configure it to use TF-M instead of Secure Partition Manager.
Configuration¶
The application has a Kconfig file with options that are specific to the Asset Tracker v2, where each of the modules has a separate submenu. These options can be used to enable and disable modules and modify their behavior and properties. See Configuring your application for information about how to permanently or temporarily change the configuration.
Setup¶
The application is designed to support communication with different cloud services, a single service at a time. Currently, the application supports the following services and technologies in the connection:
Service |
Technologies |
---|---|
By default, the application is configured to communicate with nRF Cloud using the factory-provisioned certificates on Thingy:91 and nRF9160 DK. This enables the application to function out-of-the-box with nRF Cloud. However, nRF Cloud does not fully support the application firmware and has limitations. For more information, see nRF Cloud implementation limitations. To enable all features of the Asset Tracker v2, use the other supported cloud service implementations.
Note
The Azure FOTA process is expected to change in the near future depending on the new Azure Device Update for IoT Hub that is currently in preview.
Setting up the Asset Tracker cloud example¶
To set up the application to work with a specific cloud example, see the following documentation:
nRF Cloud - Creating an nRF Cloud account and Connecting your device to nRF Cloud.
AWS IoT Core - Getting started guide for nRF Asset Tracker for AWS
Azure IoT Hub - Getting started guide for nRF Asset Tracker for Azure
For every cloud service that is supported by this application, you must configure the corresponding cloud library by setting certain mandatory Kconfig options that are specific to the cloud library. For more information, see Cloud-specific mandatory Kconfig options.
Configuration options¶
Check and configure the following configuration options for the application:
-
CONFIG_ASSET_TRACKER_V2_APP_VERSION
- Configuration for providing the application version
¶ The application publishes its version number as a part of the static device data. The default value for the application version is
0.0.0-development
. To configure the application version, setCONFIG_ASSET_TRACKER_V2_APP_VERSION
to the desired version.
-
CONFIG_CLOUD_CLIENT_ID_USE_CUSTOM
- Configuration for enabling the use of custom cloud client ID
¶ This application configuration is used to enable the use of custom client ID for the respective cloud. By default, the application uses the IMEI of the nRF9160-based device as the client ID in the cloud connection.
-
CLOUD_CLIENT_ID
- Configuration for providing a custom cloud client ID
¶ This application configuration sets a custom client ID for the respective cloud. For setting a custom client ID, you need to set
CONFIG_CLOUD_CLIENT_ID_USE_CUSTOM
toy
.
The default values for the device configuration parameters can be set by manipulating the following configurations:
-
CONFIG_DATA_DEVICE_MODE
- Configuration for the device mode
¶ This application configuration sets the device mode.
-
CONFIG_DATA_ACTIVE_TIMEOUT_SECONDS
- Configuration for Active mode
¶ This application configuration sets the Active mode timeout value.
-
CONFIG_DATA_MOVEMENT_RESOLUTION_SECONDS
- Configuration for Movement resolution
¶ This configuration sets the Movement resolution timeout value.
-
CONFIG_DATA_MOVEMENT_TIMEOUT_SECONDS
- Configuration for Movement timeout
¶ This configuration sets the Movement timeout value.
-
CONFIG_DATA_ACCELEROMETER_THRESHOLD
- Configuration for Accelerometer threshold
¶ This configuration sets the Accelerometer threshold value.
-
CONFIG_DATA_GPS_TIMEOUT_SECONDS
- Configuration for GPS timeout
¶ This configuration sets the GPS timeout value.
Mandatory library configuration¶
You can set the mandatory library-specific Kconfig options in the prj.conf
file of the application.
Configurations for AWS IoT library¶
Configurations for Azure IoT Hub library¶
Optional library configurations¶
You can add the following optional configurations to configure the heap or to provide additional information such as APN to the modem for registering with an LTE network:
CONFIG_HEAP_MEM_POOL_SIZE
- Configures the size of the heap that is used by the application when encoding and sending data to the cloud. More information can be found in Memory allocation.CONFIG_PDN_DEFAULTS_OVERRIDE
- Used for manual configuration of the APN. Set the option toy
to override the default PDP context configuration.CONFIG_PDN_DEFAULT_APN
- Used for manual configuration of the APN. An example isapn.example.com
.
The application supports Assisted GPS. To set the source of the A-GPS data, set the following options:
CONFIG_AGPS_SRC_SUPL
- Sets the external SUPL Client library as A-GPS data source. See the documentation on SUPL client library.CONFIG_AGPS_SRC_NRF_CLOUD
- Sets nRF Cloud as A-GPS data source. You must set nRF Cloud as the firmware cloud backend.
Configuration files¶
The application provides predefined configuration files for typical use cases.
You can find the configuration files in the applications/asset_tracker_v2/
directory.
It is possible to build the application with overlay files for both DTS and Kconfig to override the default values for the board. The application contains examples of Kconfig overlays.
The following configuration files are available in the application folder:
prj.conf
- Configuration file common for all build targetsboards/thingy91_nrf9160ns.conf
- Configuration file specific for Thingy:91. The file is automatically merged withprj.conf
when you build for thethingy91_nrf9160ns
build target.overlay-low-power.conf
- Configuration file that achieves the lowest power consumption by disabling features that consume extra power like LED control and logging.overlay-debug.conf
- Configuration file that adds additional verbose logging capabilities to the application
Generally, Kconfig overlays have an overlay-
prefix and a .conf
extension.
Board-specific configuration files are placed in the boards
folder and are named as <BOARD>.conf
.
DTS overlay files are named the same as the build target and use the file extension .overlay
.
When the DTS overlay filename matches the build target, the overlay is automatically chosen and applied by the build system.
Building and running¶
Before building and running the firmware ensure that the cloud side is set up. Also, the device must be provisioned and configured with the certificates according to the instructions for the respective cloud for the connection attempt to succeed.
Note
This application supports Secure bootloader chain, which is disabled by default.
To enable the immutable bootloader, set CONFIG_SECURE_BOOT=y
.
This sample can be found under applications/asset_tracker_v2
in the nRF Connect SDK folder structure.
The sample is built as a non-secure firmware image for the nrf9160dk_nrf9160ns build target. Because of this, it automatically includes the Secure Partition Manager. You can also configure it to use TF-M instead of SPM.
See Building and programming a sample application for information about how to build and program the application.
Note
For nRF9160 DK v0.15.0 and later, set the CONFIG_NRF9160_GPS_ANTENNA_EXTERNAL
option to y
when building the application to achieve the best external antenna performance.
Building with overlays¶
To build with Kconfig overlay, it must be based to the build system, as shown in the following example:
west build -b nrf9160dk_nrf9160ns -- -DOVERLAY_CONFIG=overlay-low-power.conf
The above command will build for nRF9160 DK using the configurations found in overlay-low-power.conf
, in addition to the configurations found in prj_nrf9160dk_nrf9160ns.conf
.
If some options are defined in both files, the options set in the overlay take precedence.
Testing¶
After programming the application and all the prerequisites to your development kit, test the application by performing the following steps:
Connect the kit to the computer using a USB cable. The kit is assigned a COM port (Windows) or ttyACM device (Linux), which is visible in the Device Manager.
Connect to the kit with a terminal emulator (for example, LTE Link Monitor). See How to connect with LTE Link Monitor for more information.
Reset the development kit.
Observe in the terminal window that the development kit starts up in the Secure Partition Manager and that the application starts. This is indicated by the following output:
*** Booting Zephyr OS build v2.4.0-ncs1-2616-g3420cde0e37b *** <inf> event_manager: APP_EVT_START
Observe in the terminal window that LTE connection is established, indicated by the following output:
<inf> event_manager: MODEM_EVT_LTE_CONNECTING ... <inf> event_manager: MODEM_EVT_LTE_CONNECTED
Observe that the device establishes connection to the cloud:
<inf> event_manager: CLOUD_EVT_CONNECTING ... <inf> event_manager: CLOUD_EVT_CONNECTED
Observe that data is sampled periodically and sent to the cloud:
<inf> event_manager: APP_EVT_DATA_GET_ALL <inf> event_manager: APP_EVT_DATA_GET - Requested data types (MOD_DYN, BAT, ENV, GNSS) <inf> event_manager: GPS_EVT_ACTIVE <inf> event_manager: SENSOR_EVT_ENVIRONMENTAL_NOT_SUPPORTED <inf> event_manager: MODEM_EVT_MODEM_DYNAMIC_DATA_READY <inf> event_manager: MODEM_EVT_BATTERY_DATA_READY <inf> event_manager: GPS_EVT_DATA_READY <inf> event_manager: DATA_EVT_DATA_READY <inf> event_manager: GPS_EVT_INACTIVE <inf> event_manager: DATA_EVT_DATA_SEND <wrn> data_module: No batch data to encode, ringbuffers empty <inf> event_manager: CLOUD_EVT_DATA_ACK
Known issues and limitations¶
Enabling full support for nRF Cloud is currently a work in progress. Following are the current limitations in the nRF Cloud implementation of the Asset Tracker v2:
Data that is sampled by the device must ideally be addressed to the cloud-side device state and published in a single packet for regular device updates. This is to avoid the unnecessary stack overhead associated with splitting the payload and the additional current consumption that might result from splitting and sending the data as separate packets. However, in the case of nRF Cloud implementation, the nRF Cloud front end supports only the display of APP_DATA_MODEM_DYNAMIC (networkInfo) and APP_DATA_MODEM_STATIC (deviceInfo) through the device shadow. The other supported data types (GPS, temperature, and humidity) must be sent in a specified format to a separate message endpoint for the front end to graphically represent the data. You can find the JSON protocol definitions for data sent to the message endpoint in nRF Cloud JSON protocol schemas.
The nRF Cloud web application does not support the manipulation of real-time configurations. However, this is possible by using the REST API calls described in nRF Cloud Patch Device State. To manipulate the device configuration, the
desired
section of the device state must be populated with the desired configuration of the device. The following schema sets the various device configuration parameters to their default values:{ "desired":{ "config":{ "activeMode":true, "activeWaitTime":120, "movementTimeout":3600, "movementResolution":120, "gpsTimeout":60, "movementThreshold":10 } } }
nRF Cloud does not support a separate endpoint for batch data updates. To temporarily circumvent this, batched data updates are sent to the message endpoint.
Dependencies¶
This application uses the following nRF Connect SDK libraries and drivers:
It uses the following sdk-nrfxlib library:
In addition, it uses the following sample:
Internal modules¶
The application has two types of modules:
Module with dedicated thread
Module without thread
Every module has an event manager handler function, which subscribes to one or more event types. When an event is sent from a module, all subscribers receive that event in the respective handler, and acts on the event in the following ways:
The event is converted into a message
The event is either processed directly or queued.
Modules may also receive events from other sources such as drivers and libraries. For instance, the cloud module will also receive events from the configured cloud backend. The event handler converts the events to messages. The messages are then queued in the case of the cloud module or processed directly in the case of modules that do not have a processing thread.
Thread usage¶
In addition to system threads, some modules have dedicated threads to process messages. Some modules receive messages that may potentially take an extended amount of time to process. Such messages are not suitable to be processed directly in the event handler callbacks that run on the system queue. Therefore, these modules have a dedicated thread to process the messages.
Application-specific threads:
Main thread (app module)
Data management module
Cloud module
Sensor module
Modem module
Modules that do not have dedicated threads process events in the context of system work queue in the event manager callback. Therefore, their workloads must be light and non-blocking.
All module threads have the following identical properties by default:
Thread is initialized at boot.
Thread is preemptive.
Priority is set to the lowest application priority in the system, which is done by setting
CONFIG_NUM_PREEMPT_PRIORITIES
to1
.Thread is started instantly after it is initialized in the boot sequence.
Following is the basic structure for all the threads:
static void module_thread_fn(void)
{
struct module_specific msg;
self.thread_id = k_current_get();
module_start(&self);
/* Module specific setup */
state_set(STATE_DISCONNECTED);
while (true) {
module_get_next_msg(&self, &msg);
switch (state) {
case STATE_DISCONNECTED:
on_state_disconnected(&msg);
break;
case STATE_CONNECTED:
on_state_connected(&msg);
break;
default:
LOG_WRN("Unknown state");
break;
}
on_all_states(&msg);
}
}
Memory allocation¶
Mostly, the modules use statically allocated memory. Following are some features that rely on dynamically allocated memory, using the Zephyr heap memory pool implementation:
Event manager events
Encoding of the data that will be sent to cloud
You can configure the heap memory by using the CONFIG_HEAP_MEM_POOL_SIZE
.
The data management module that encodes data destined for cloud is the biggest consumer of heap memory.
Therefore, when adjusting buffer sizes in the data management module, you must also adjust the heap accordingly.
This avoids the problem of running out of heap memory in worst-case scenarios.