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/or 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 AWS IoT Core. The application is intended to be used with an instance of Asset Tracker Cloud Example for AWS running on the cloud side.
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² |
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 flashing |
LED1 flashing |
GPS fix search |
Purple flashing |
LED2 flashing |
Publishing data |
Green flashing |
LED3 flashing |
Active mode |
Light blue flashing |
LED4 flashing |
Passive mode |
Dark blue slow flashing (short on, long off) |
LED4 slow flashing (short on, long off) |
Error |
Red solid |
all 4 LEDs flashing |
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 Amazon Web Services IoT Core cloud service and the following technologies in the cloud connection:
Azure support for Asset Tracker v2 is currently under implementation.
Setting up the Asset Tracker Cloud Example for AWS¶
The application is compatible with the Asset Tracker Cloud Example for AWS, which is an open source reference implementation of a serverless backend for an IoT product. To set up the application to work with the Asset Tracker Cloud Example for AWS, see the Getting started guide for Asset Tracker Cloud Example for AWS.
Once you have finished the setup, you must provide the broker hostname to the firmware using the CONFIG_AWS_IOT_BROKER_HOST_NAME
Kconfig option.
Configure the secTag using the CONFIG_AWS_IOT_SEC_TAG
Kconfig option. For example, you can use the default value of 42
that is used in the Asset Tracker Cloud Example for AWS .
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 desiredapp-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
.
Additional configuration¶
To get the application to communicate with a specified cloud service, configure the Kconfig options specific to each cloud library. Every cloud service supported in nRF Connect SDK has a corresponding cloud library that needs to be selected and properly configured.
You must check and configure the following AWS IoT library options that are used by the application:
Additionally, 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_LTE_PDP_CMD
- Used for manual configuration of the APN. Set the option toy
to enable PDP define usingAT+CGDCONT
.CONFIG_LTE_PDP_CONTEXT
- Used for manual configuration of the APN. An example is0,\"IP\",\"apn.example.com\"
.
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
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.