Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@

## Overview

The Asset Tracker Template is a modular framework for developing IoT applications on nRF91-based devices. Built on [nRF Connect SDK](https://www.nordicsemi.com/Products/Development-software/nRF-Connect-SDK) and [Zephyr RTOS](https://docs.zephyrproject.org/latest/), it provides an event-driven architecture for battery-powered IoT use cases with cloud connectivity, location tracking, and sensor data collection.
The Asset Tracker Template is a modular framework for developing IoT applications on nRF91-based devices.
It is built on the [nRF Connect SDK](https://www.nordicsemi.com/Products/Development-software/nRF-Connect-SDK) and [Zephyr RTOS](https://docs.zephyrproject.org/latest/), and provides a modular, event-driven architecture suitable for battery-powered IoT use cases.
The framework supports features such as cloud connectivity, location tracking, and sensor data collection.

The system uses modules that communicate through [zbus](https://docs.nordicsemi.com/bundle/ncs-latest/page/zephyr/services/zbus/index.html) channels for loose coupling and maintainability. It's suitable for asset tracking, environmental monitoring, and other IoT applications requiring modularity and power efficiency.
The system is organized into modules, each responsible for a specific functionality, such as managing network connectivity, handling cloud communication, or collecting environmental data.
Modules communicate through [zbus](https://docs.zephyrproject.org/latest/services/zbus/index.html) channels, ensuring loose coupling and maintainability.

**Supported hardware**: [Thingy:91 X](https://www.nordicsemi.com/Products/Development-hardware/Nordic-Thingy-91-X), [nRF9151 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF9151-DK)

> **Note**: If you're new to nRF91 series and cellular IoT, consider taking the [Nordic Developer Academy Cellular Fundamentals Course](https://academy.nordicsemi.com/courses/cellular-iot-fundamentals).
> [!NOTE]
> If you're new to nRF91 series and cellular IoT, consider taking the [Nordic Developer Academy Cellular Fundamentals Course](https://academy.nordicsemi.com/courses/cellular-iot-fundamentals).

## Quick Start

Expand All @@ -29,9 +33,9 @@ For detailed setup instructions using the [nRF Connect for VS Code extension](ht
For pre-built binaries, refer to the latest tag and release artifacts documentaion; [release artifacts](docs/common/release.md).

> [!TIP]
> Use the [Download nRF Connect for Desktop Quick Start application](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop/download#infotabs) for a guided setup and provisioning process.
> Download and run the [Quick Start app](https://docs.nordicsemi.com/bundle/nrf-connect-quickstart/page/index.html) in the [nRF Connect for Desktop](https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Connect-for-desktop) for a guided setup and provisioning process.
>
> You can also refer to [Exercise 1](https://academy.nordicsemi.com/courses/cellular-iot-fundamentals/lessons/lesson-1-cellular-fundamentals/topic/lesson-1-exercise-1/) in [Nordic Developer Academy Cellular Fundamentals Course](https://academy.nordicsemi.com/courses/cellular-iot-fundamentals).
> You can also refer to [Exercise 1](https://academy.nordicsemi.com/courses/cellular-iot-fundamentals/lessons/lesson-1-cellular-fundamentals/topic/lesson-1-exercise-1/) in [Nordic Developer Academy Cellular Fundamentals Course](https://academy.nordicsemi.com/courses/cellular-iot-fundamentals) for more details.

### Prerequisites

Expand Down
6 changes: 3 additions & 3 deletions docs/common/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This document provides an overview of the architecture and explains how the diff
The Asset Tracker Template is built around a modular architecture where each module is responsible for a specific functionality. The template consists of the following modules:

- **[Main module](../modules/main.md)**: The central coordinator that implements the business logic and controls the overall application flow.
- **[Storage module](../modules/storage.md)**: Forwards or stores data from enabled modules.
- **[Network module](../modules/network.md)**: Manages LTE connectivity and tracks network status.
- **[Cloud module](../modules/cloud.md)**: Handles communication with nRF Cloud using CoAP.
- **[Location module](../modules/location.md)**: Provides location services using GNSS, Wi-Fi, and cellular positioning.
Expand Down Expand Up @@ -224,9 +225,8 @@ In the image, the black dots and arrow indicate initial transitions.
In this case, the initial state is set to `STATE_RUNNING`. In the state machine definition, initial transitions are configured, such that the state machine ends up in `STATE_DISCONNECTED_SEARCHING` when first initialized.
From there, transitions follows the arrows according to the messages received and the state machine logic.

!!! important "Important"

In a hierarchical state machine, the run function of the current state is executed first, and then the run function of the parent state is executed, unless a state transition happens, or the child state marks the message as handled using `smf_state_handled()`.
> [!IMPORTANT]
> In a hierarchical state machine, the run function of the current state is executed first, and then the run function of the parent state is executed, unless a state transition happens, or the child state marks the message as handled using `smf_state_handled()`.

### State machine context

Expand Down
36 changes: 18 additions & 18 deletions docs/common/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,19 @@ curl -X PATCH "https://api.nrfcloud.com/v1/devices/$DEVICE_ID/state" \

*For shadow structure details, see `Asset-Tracker-Template/app/src/cbor/device_shadow.cddl`*

### Configuration Flow
### Configuration flow

* **Initial Setup**
* **Initial setup**

- The device starts with default interval from `CONFIG_APP_MODULE_TRIGGER_TIMEOUT_SECONDS`.
- Upon cloud connection, the device automatically requests shadow configuration.

* **Runtime Configuration**
* **Runtime configuration**

- Cloud module receives and processes shadow updates.
- Device maintains last known configuration during offline periods.

* **Impact on Device Behavior**
* **Impact on device behavior**

The `update_interval` configuration controls the frequency of:

Expand All @@ -78,17 +78,17 @@ curl -X PATCH "https://api.nrfcloud.com/v1/devices/$DEVICE_ID/state" \

The Asset Tracker supports multiple location methods that can be prioritized based on your needs. Configuration is done through board-specific configuration files.

### Available Location Methods
### Available location methods

The following are the available location methods:

- GNSS (GPS)
- Wi-Fi® positioning
- Cellular positioning

### Configuration Examples
### Configuration examples

* **Thingy91x Configuration** (Wi-Fi available):
* **Thingy91x configuration** (Wi-Fi available):

```
CONFIG_LOCATION_REQUEST_DEFAULT_METHOD_FIRST_WIFI=y
Expand All @@ -97,21 +97,21 @@ The following are the available location methods:
CONFIG_LOCATION_REQUEST_DEFAULT_WIFI_TIMEOUT=10000
```

* **nRF9151 DK Configuration** (Wi-Fi unavailable):
* **nRF9151 DK configuration** (Wi-Fi unavailable):

```
CONFIG_LOCATION_REQUEST_DEFAULT_METHOD_FIRST_GNSS=y
CONFIG_LOCATION_REQUEST_DEFAULT_METHOD_SECOND_CELLULAR=y
```

## Storage Mode Configuration
## Storage mode configuration

The storage module handles collected data in two modes: **Passthrough** (forward immediately, default) or **Buffer** (store and transmit in batches for lower power consumption).
See [Storage Module Documentation](../modules/storage.md) for details.

**Basic configuration** in `prj.conf`:

Passthrough mode is the default mode, to enable buffer mode use:
Passthrough mode is the default mode. To enable buffer mode use:

```bash
CONFIG_APP_STORAGE_INITIAL_MODE_BUFFER=y
Expand All @@ -124,7 +124,7 @@ CONFIG_APP_STORAGE_MAX_RECORDS_PER_TYPE=8 # Records per data type
CONFIG_APP_STORAGE_BATCH_BUFFER_SIZE=256 # Batch buffer size
```

For minimal use include the `overlay-storage-minimal.conf` overlay
For minimal use, include the `overlay-storage-minimal.conf` overlay.

**Runtime control** (shell commands when `CONFIG_APP_STORAGE_SHELL=y`):

Expand Down Expand Up @@ -156,7 +156,7 @@ The Asset Tracker supports both LTE Cat NB1 (NB-IoT) and LTE Cat M1 (LTE-M) cell
- Mobile applications.
- Lower latency requirements.

#### Network Mode Selection
#### Network mode selection

The following network modes are available (`LTE_NETWORK_MODE`):

Expand All @@ -168,7 +168,7 @@ The following network modes are available (`LTE_NETWORK_MODE`):
- **LTE-M and NB-IoT**: Both LTE-M and NB-IoT enabled.
- **LTE-M, NB-IoT and GPS**: Both LTE modes with GPS .

#### Network Mode Preference
#### Network mode preference

When multiple network modes are enabled (LTE-M and NB-IoT), you can set preferences (`LTE_MODE_PREFERENCE`):

Expand All @@ -188,11 +188,11 @@ CONFIG_LTE_NETWORK_MODE_LTE_M_NBIOT_GPS=y
CONFIG_LTE_MODE_PREFERENCE_LTE_M_PLMN_PRIO=y
```

### PSM (Power Saving Mode)
### Power Saving Mode (PSM)

PSM allows the device to enter deep sleep while maintaining network registration. Configuration is done through Kconfig options:

#### PSM Parameters
#### PSM parameters

* **Periodic TAU (Tracking Area Update)**

Expand Down Expand Up @@ -223,7 +223,7 @@ The following are the Key aspects:
- Stays active for the duration specified by RAT.


### APN (Access Point Name)
### Access Point Name (APN)

The Access Point Name (APN) is a network identifier used by the device to connect to the cellular network's packet data network. Configuration options:

Expand All @@ -243,7 +243,7 @@ Common scenarios for APN configuration:
> [!NOTE]
> In most cases, the default APN provided by the carrier should work without additional configuration.

## LED Status Indicators
## LED status indicators

The Asset Tracker Template uses LED colors to indicate different device states:

Expand All @@ -252,7 +252,7 @@ The Asset Tracker Template uses LED colors to indicate different device states:
- **Blue** (Blinking, 10 repetitions): Device is in lower power mode state between samples.
- **Purple** (Blinking, 10 repetitions): FOTA download in progress.

### Example: Setting LED Colors
### Example: Setting LED colors

You can control the LED colors through the LED module using zbus messages. The following is an example of how to set different LED patterns:

Expand Down
36 changes: 18 additions & 18 deletions docs/common/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ To add a new zbus event, complete the following procedure:
};
```

2. Implement publishing of VBUS connected and disconnected events by modifying the existing `event_callback()` function in `power.c`:
1. Implement publishing of VBUS connected and disconnected events by modifying the existing `event_callback()` function in `power.c`:
```c
if (pins & BIT(NPM13XX_EVENT_VBUS_DETECTED)) {
LOG_DBG("VBUS detected");
Expand Down Expand Up @@ -70,7 +70,7 @@ To add a new zbus event, complete the following procedure:
}
```

3. Make sure the channel is included in the subscriber module (for example, `main.c`). Add the channel to the channel list:
1. Make sure the channel is included in the subscriber module (for example, `main.c`). Add the channel to the channel list:

```c
# define CHANNEL_LIST(X) \
Expand All @@ -84,7 +84,7 @@ To add a new zbus event, complete the following procedure:
X(POWER_CHAN, struct power_msg) \
```

4. Implement a handler for the new events in the subscriber module (for example, in the main module's state machine in `running_run`):
1. Implement a handler for the new events in the subscriber module (for example, in the main module's state machine in `running_run`):

```c
if (state_object->chan == &POWER_CHAN) {
Expand Down Expand Up @@ -136,7 +136,7 @@ To add a new zbus event, complete the following procedure:
}
```

5. Test the implementation by connecting and disconnecting VBUS to verify the LED patterns change as expected.
1. Test the implementation by connecting and disconnecting VBUS to verify the LED patterns change as expected.

## Add environmental sensor

Expand Down Expand Up @@ -171,7 +171,7 @@ Thingy:91 X is used as an example, as it is a supported board in the template wi
};
```

2. Update the environmental module's state structure to include the magnetometer device reference and data storage:
1. Update the environmental module's state structure to include the magnetometer device reference and data storage:

```c
struct environmental_state_object {
Expand All @@ -187,7 +187,7 @@ Thingy:91 X is used as an example, as it is a supported board in the template wi
};
```

3. Initialize the device reference using the devicetree label:
1. Initialize the device reference using the devicetree label:

```c
struct environmental_state_object environmental_state = {
Expand All @@ -196,7 +196,7 @@ Thingy:91 X is used as an example, as it is a supported board in the template wi
};
```

4. Update the sensor sampling function signature to include the magnetometer device:
1. Update the sensor sampling function signature to include the magnetometer device:

```c
static void sample_sensors(const struct device *const bme680, const struct device *const bmm350)
Expand All @@ -208,7 +208,7 @@ Thingy:91 X is used as an example, as it is a supported board in the template wi
sample_sensors(state_object->bme680, state_object->bmm350);
```

5. Implement sensor data acquisition using the Zephyr Sensor API:
1. Implement sensor data acquisition using the Zephyr Sensor API:

```c
err = sensor_sample_fetch(bmm350);
Expand Down Expand Up @@ -241,7 +241,7 @@ Thingy:91 X is used as an example, as it is a supported board in the template wi
};
```

6. Update the `environmental_msg` structure in `environmental.h` to include the magnetic field data:
1. Update the `environmental_msg` structure in `environmental.h` to include the magnetic field data:

```c
struct environmental_msg {
Expand All @@ -254,9 +254,9 @@ Thingy:91 X is used as an example, as it is a supported board in the template wi
};
```

The magnetometer data is now part of the environmental message and will be automatically handled by the storage module through the existing `ENVIRONMENTAL` data type. No changes to `storage_data_types.h` or `storage_data_types.c` are needed since the existing `environmental_check()` and `environmental_extract()` functions will handle the entire structure including the magnetic field data.
The magnetometer data is now part of the environmental message and will be automatically handled by the storage module through the existing `ENVIRONMENTAL` data type. No changes to `storage_data_types.h` or `storage_data_types.c` are needed since the existing `environmental_check()` and `environmental_extract()` functions will handle the entire structure, including the magnetic field data.

7. Add cloud integration in the `send_storage_data_to_cloud()` function in `cloud.c` to send magnetometer data to nRF Cloud. Add this code after the existing environmental sensor data handling:
1. Add cloud integration in the `send_storage_data_to_cloud()` function in `cloud.c` to send magnetometer data to nRF Cloud. Add this code after the existing environmental sensor data handling:

```c
#if defined(CONFIG_APP_ENVIRONMENTAL)
Expand Down Expand Up @@ -316,14 +316,14 @@ To add your own module, complete the following steps:
mkdir -p app/src/modules/dummy
```

2. Create the following files in the module directory:
1. Create the following files in the module directory:

- `dummy.h` - Module interface definitions.
- `dummy.c` - Module implementation.
- `Kconfig.dummy` - Module configuration options.
- `CMakeLists.txt` - Build system configuration.

3. In `dummy.h`, define the module's interface:
1. In `dummy.h`, define the module's interface:

```c
#ifndef _DUMMY_H_
Expand Down Expand Up @@ -363,7 +363,7 @@ To add your own module, complete the following steps:
#endif /* _DUMMY_H_ */
```

4. In `dummy.c`, implement the module's functionality:
1. In `dummy.c`, implement the module's functionality:

```c
#include <zephyr/kernel.h>
Expand Down Expand Up @@ -521,7 +521,7 @@ To add your own module, complete the following steps:
K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0);
```

5. In `Kconfig.dummy`, define module configuration options:
1. In `Kconfig.dummy`, define module configuration options:

```kconfig
menuconfig APP_DUMMY
Expand Down Expand Up @@ -557,20 +557,20 @@ To add your own module, complete the following steps:
endif # APP_DUMMY
```

6. In `CMakeLists.txt`, configure the build system to include the source files of the module:
1. In `CMakeLists.txt`, configure the build system to include the source files of the module:

```cmake
target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/dummy.c)
target_include_directories(app PRIVATE .)
```

7. Add the module to the main application's CMakeLists.txt:
1. Add the module to the main application's CMakeLists.txt:

```cmake
add_subdirectory(src/modules/dummy)
```

8. Increase `CONFIG_TASK_WDT_CHANNELS` in the `prj.conf` file to accommadate for the new module's task watchdog integration.
1. Increase the value of the `CONFIG_TASK_WDT_CHANNELS` Kconfig option in the `prj.conf` file to accommadate for the new module's task watchdog integration.

The dummy module is now ready to use. It provides the following functionality:

Expand Down
Loading