AWS IoT

The Amazon Web Services Internet-of-Things (AWS IoT) sample demonstrates how to connect an nRF91 Series, nRF70 Series, or nRF54L15 with nRF7002 EB device to the AWS IoT Core service over MQTT to publish and receive messages. This sample showcases the use of the AWS IoT library, which includes support for FOTA using the AWS FOTA library.

Cellular connectivity is supported on the nRF91 Series SiPs, while Wi-Fi® connectivity is supported on the nRF52 or nRF53 Series SoCs hosting the nRF70 Series Wi-Fi companion ICs.

The sample uses the connection manager that provides a common connectivity API for LTE and Wi-Fi stacks.

Before this sample can be used, an AWS IoT server instance needs to be setup in order for the device to connect to it. Refer to Setup to complete the necessary steps.

Requirements

The sample supports the following development kits:

Hardware platforms

PCA

Board name

Board target

Shields

Thingy:91 X

PCA20065

thingy91x

thingy91x/nrf9151/ns

Thingy:91

PCA20035

thingy91

thingy91/nrf9160/ns

nRF9161 DK

PCA10153

nrf9161dk

nrf9161dk/nrf9161/ns

nRF9160 DK

PCA10090

nrf9160dk

nrf9160dk/nrf9160/ns

nRF9151 DK

PCA10171

nrf9151dk

nrf9151dk/nrf9151/ns

nRF7002 DK

PCA10143

nrf7002dk

nrf7002dk/nrf5340/cpuapp/ns

nRF54L15 DK

PCA10156

nrf54l15dk

nrf54l15dk/nrf54l15/cpuapp

"nrf7002eb_interposer_p1;nrf7002eb"

Native Simulator

native_sim

native_sim

Additionally, the sample supports emulation using the native simulator.

When built for a board target with the */ns variant, the sample is configured to compile and run as a non-secure application with Cortex-M Security Extensions enabled. Therefore, it automatically includes Trusted Firmware-M that prepares the required peripherals and secure services to be available for the application.

Overview

The sample publishes messages in the JSON string format to the AWS IoT Device Shadow Service, addressed to the AWS IoT Device Shadow Topic: $aws/things/<thingname>/shadow/update. Messages are published once at an interval set by the CONFIG_AWS_IOT_SAMPLE_PUBLICATION_INTERVAL_SECONDS Kconfig option. The message has the following structure:

     {
             "state": {
                     "reported": {
                             "app_version": "v1.0.0",
                             "modem_version": "nrf9160-1.3.4", /* Not present for Wi-Fi builds */
                             "uptime": 2469
                     }
             }
     }

The message comprises of three parameters the application version, the modem version string, and an uptime timestamp. The firmware version strings can be used to verify that the device has updated the corresponding image post FOTA DFU. See the AWS FOTA library for information on how to create FOTA jobs.

In addition to publishing data to the AWS IoT shadow, the sample also subscribes to the following topics:

Topic

Kconfig option

Purpose

$aws/things/<thing-name>/shadow/update/delta

CONFIG_AWS_IOT_TOPIC_UPDATE_DELTA_SUBSCRIBE

Topic that receives the difference between the reported and desired shadow states. Can be used for run-time configuration of the device.

$aws/things/<thing-name>/shadow/get/accepted

CONFIG_AWS_IOT_TOPIC_GET_ACCEPTED_SUBSCRIBE

Topic that receives the shadow document whenever it is requested by the device. Auto-requesting of the shadow document after an established connection can be enabled by setting the CONFIG_AWS_IOT_AUTO_DEVICE_SHADOW_REQUEST option.

$aws/things/<thing-name>/shadow/get/rejected

CONFIG_AWS_IOT_TOPIC_GET_REJECTED_SUBSCRIBE

Topic that receives an error status message if requesting the device shadow failed.

my-custom-topic/example

NA - Non-shadow topic

Dummy application-specific topic. Can be used for anything.

my-custom-topic/example_2

NA - Non-shadow topic

Dummy application-specific topic. Can be used for anything.

The application-specific topics are not part of the AWS IoT shadow service and must therefore be passed to the AWS IoT library using the aws_iot_application_topics_set() function before connecting. How to add application-specific topics is documented in the AWS IoT library usage section.

Configuration

See Configuring and building for information about how to permanently or temporarily change the configuration.

Setup

To run this sample and connect to AWS IoT, complete the steps described in the Setup and configuration section of the AWS IoT library documentation. This is to obtain the AWS IoT broker hostname and the client ID of the device and provision a device certificate to a security tag.

The corresponding options that must be set for each of these values are:

Set these options in the project configuration file located at samples/net/aws_iot/prj.conf. For documentation related to FOTA DFU, see AWS FOTA.

Note

For nRF70 Series devices, certificates must be provisioned at runtime. This is achieved by pasting the PEM content into the respective files in the certs/ subdirectory and ensuring the CONFIG_MQTT_HELPER_PROVISION_CERTIFICATES Kconfig option is enabled.

Configuration options

Check and configure the following Kconfig options:

General options

The following lists the application-specific configurations used in the sample. They are located in samples/net/aws_iot/Kconfig.

CONFIG_AWS_IOT_SAMPLE_APP_VERSION

This configuration option sets the application version number.

CONFIG_AWS_IOT_SAMPLE_JSON_MESSAGE_SIZE_MAX

This configuration option sets the maximum size of JSON messages that are sent to AWS IoT.

CONFIG_AWS_IOT_SAMPLE_PUBLICATION_INTERVAL_SECONDS

This configuration option configures the time interval between each message publication.

CONFIG_AWS_IOT_SAMPLE_CONNECTION_RETRY_TIMEOUT_SECONDS

This configuration option configures the number of seconds between each AWS IoT connection retry. If the connection is lost, the sample attempts to reconnect at the frequency set by this option.

CONFIG_AWS_IOT_SAMPLE_DEVICE_ID_USE_HW_ID

This configuration option configures the sample to use the HW ID (IMEI, MAC) as the device ID in the MQTT connection.

Configuring Wi-Fi access point credentials

This sample uses the Wi-Fi credentials library to manage Wi-Fi credentials. Before the sample can connect to a Wi-Fi network, you must configure at least one credential set.

Once you have flashed your device with this sample, connect to your device’s UART interface and add credentials using the following command:

wifi_cred add -s NetworkSSID -k SecurityMode -p NetworkPassword

Where NetworkSSID is replaced with the SSID of the Wi-Fi access point you want your device to connect to, and NetworkPassword is its password. SecurityMode is replaced by the number as listed here:

  • 0:None

  • 1:WPA2-PSK

  • 2:WPA2-PSK-256

  • 3:SAE-HNP

  • 4:SAE-H2E

  • 5:SAE-AUTO

  • 6:WAPI

  • 7:EAP-TLS

  • 8:WEP

  • 9:WPA-PSK

  • 10:WPA-Auto-Personal

  • 11:DPP

If you are not sure which security mode to use, enable the CONFIG_NET_L2_WIFI_SHELL Kconfig option and use the wifi scan command to display a list of all accessible networks along with their corresponding security modes. Then either reboot the device or use the wifi_cred auto_connect command to manually trigger a connection attempt.

From now on, these credentials will be automatically used when the configured network is reachable.

When building as firmware image for a non-secure board target, the Wi-Fi credentials backend will be set to PSA using TF-M.

See the Wi-Fi: Shell sample document for more details on the wifi_cred command.

Wi-Fi static credential options

If you want to configure the credentials statically, set the CONFIG_WIFI_CREDENTIALS_STATIC Kconfig option to y.

Important

Do not use static credentials in production environments.

Other options for statically configuring your Wi-Fi credentials:

Configuration files

The sample includes pre-configured configuration files for the development kits that are supported:

  • prj.conf - General configuration file for all devices.

  • boards/nrf9151dk_nrf9151_ns.conf - Configuration file for the nRF9151 DK.

  • boards/nrf9161dk_nrf9161_ns.conf - Configuration file for the nRF9161 DK.

  • boards/nrf9160dk_nrf9160_ns.conf - Configuration file for the nRF9160 DK.

  • boards/thingy91_nrf9160_ns.conf - Configuration file for the Thingy:91.

  • boards/nrf7002dk_nrf5340_cpuapp_ns.conf - Configuration file for the nRF7002 DK.

  • boards/nrf54l15dk_nrf54l15_cpuapp.conf - Configuration file for the nRF54L15 DK.

  • boards/native_sim.conf - Configuration file for the native simulator board.

The following configuration and DTS overlay files are included to host the MCUboot secondary image slot on external flash for the nRF7002 DK:

  • boards/nrf7002dk_nrf5340_cpuapp_ns.overlay - DTS overlay file for the application image.

  • child_image/mcuboot/nrf7002dk_nrf5340_cpuapp.overlay - DTS overlay file for the MCUboot child image.

  • child_image/mcuboot/nrf7002dk_nrf5340_cpuapp.conf - Configuration file for the MCUboot child image.

Files that are located under the /boards folder are automatically merged with the prj.conf file when you build for the corresponding target. Files that are located under the /child_image/mcuboot folder are used to configure the MCUboot child image. To read more about child images, see Multi-image builds using child and parent images.

Sending traces over UART on an nRF91 Series DK

To send modem traces over UART on an nRF91 Series DK, configuration must be added for the UART device in the devicetree and Kconfig. This is done by adding the modem trace UART snippet when building and programming.

Use the Cellular Monitor app for capturing and analyzing modem traces.

TF-M logging must use the same UART as the application. For more details, see shared TF-M logging.

Building and running

This sample can be found under samples/net/aws_iot in the nRF Connect SDK folder structure.

When built as firmware image for a board target with the */ns variant, the sample has Cortex-M Security Extensions (CMSE) enabled and separates the firmware between Non-Secure Processing Environment (NSPE) and Secure Processing Environment (SPE). Because of this, it automatically includes the Trusted Firmware-M (TF-M). To read more about CMSE, see Processing environments.

To build the sample, follow the instructions in Building an application for your preferred building environment. See also Programming an application for programming steps and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.

Note

When building repository applications in the SDK repositories, building with sysbuild is enabled by default. If you work with out-of-tree freestanding applications, you need to manually pass the --sysbuild parameter to every build command or configure west to always use it.

Testing

After programming the sample to your development kit, complete the following steps to test it:

  1. 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.

  2. Connect to the kit with a terminal emulator (for example, nRF Connect Serial Terminal). See Testing and optimization for the required settings and steps.

  3. Reset your board.

  4. Observe that the board connects to the network and the AWS IoT broker. After the connection has been established, the device starts to publish messages to the AWS IoT shadow service. The frequency of the messages that are published to the broker can be set by CONFIG_AWS_IOT_SAMPLE_PUBLICATION_INTERVAL_SECONDS.

Sample output

The following serial UART output is displayed in the terminal emulator when running the sample. The modem_version parameter in messages published to AWS IoT will not be present for Wi-Fi builds.

*** Booting Zephyr OS build v3.3.99-ncs1-2858-gc9d01d05ce83 ***
[00:00:00.252,838] <inf> aws_iot_sample: The AWS IoT sample started, version: v1.0.0
[00:00:00.252,868] <inf> aws_iot_sample: Bringing network interface up and connecting to the network
[00:00:02.486,297] <inf> aws_iot_sample: Network connectivity established
[00:00:07.486,419] <inf> aws_iot_sample: Connecting to AWS IoT
[00:00:11.061,981] <inf> aws_iot_sample: AWS_IOT_EVT_CONNECTED
[00:00:11.062,866] <inf> aws_iot_sample: Publishing message: {"state":{"reported":{"uptime":11062,"app_version":"v1.0.0","modem_version":"nrf9160_1.3.4"}}} to AWS IoT shadow
[00:01:11.073,120] <inf> aws_iot_sample: Publishing message: {"state":{"reported":{"uptime":71063,"app_version":"v1.0.0","modem_version":"nrf9160_1.3.4"}}} to AWS IoT shadow

Note

For nRF91 Series devices, the output differs from the above example output. This is because the sample enables the AT Host library using the CONFIG_AT_HOST_LIBRARY option. This library makes it possible to send AT commands to the nRF91 Series modem and receive responses using the Cellular Monitor app from nRF Connect for Desktop. The additional logs are AT command responses that the modem sends to the application core that are forwarded over UART to be displayed on any of these nRF Connect for Desktop apps.

To observe incoming messages in the AWS IoT console, follow the steps documented in Testing and debugging.

Emulation

The sample can run on the native simulator, which simplifies development and testing and removes the need for hardware. Before you build and run on the native_sim board, you need to perform the steps documented in Networking with native_sim board.

When these steps are completed, you can build and run the sample by using the following commands:

west build -b native_sim samples/net/mqtt
./samples/net/mqtt/build/zephyr/zephyr.exe

Troubleshooting

To enable more verbose logging from the AWS IoT library, enable the CONFIG_AWS_IOT_LOG_LEVEL_DBG option.

  • If you have issues with connectivity on nRF91 Series devices, see the Cellular Monitor documentation to learn how to capture modem traces in order to debug network traffic in Wireshark. The sample enables modem traces by default.

  • If you have issues with the sample, refer to Testing and optimization.

  • For issues related to connection towards AWS IoT, refer to AWS IoT library troubleshooting.

Dependencies

This sample uses the following nRF Connect SDK and Zephyr libraries: