Tutorial how to create an application on the nRF9160 DK

This chapter will take you through the steps required for creating an application in NCS for nRF9160.

This blog is based on the Nordic Connect SDK v1.2.0 version. It may have need to change on the other versions (later). The propose of this blog is to show the idea how to run such example on NCS.

nRF9160 DK board

The virtual COM ports are the following:
• VCOM0 – Connected to nRF9160 (default)
• VCOM1 – Connected to nRF52840 (nonconfigurable)
• VCOM2 – Not connected to nRF9160 (default)

Performance measurement mode

By measuring the current consumption of the nRF9160 through nRF9160 DK board,

The performance measurement mode can be selected by moving the IFMCU DISCONN switch (SW1) to the right position, which disconnects the interface MCU from the nRF9160 SiP using analog switches.

This is done to isolate the nRF9160 SiP as much as possible and can be of use when measuring currents on
low-power applications.

Block diagram

GPIO interfaces

GPIO signals are also available on connectors P5, P6, P12, P17, and P25, which are on the bottom side of the board. By mounting pin lists on the connector footprints, the nRF9160 DK board can be used as a shield for Arduino motherboards.

Zephyr Building System


Environment Variables


You can use the setx program in cmd.exe or the third-party RapidEE program.

To use setx, type this command, then close the terminal window. Any new cmd.exe windows will have MY_VARIABLE set to foo.

setx MY_VARIABLE foo

To install RapidEE, a freeware graphical environment variable editor, using Chocolatey in an Administrator command prompt:

choco install rapidee

Important Environment Variables

Here are some important environment variables and what they contain. This is not a comprehensive index to the environment variables which affect Zephyr’s behavior.

  • BOARD: allows set the board when building an application; see Important Build System Variables.
  • CONF_FILE: allows adding Kconfig fragments to an application build; see Important Build System Variables.
  • DTC_OVERLAY_FILE: allows adding devicetree overlays to an application build; see Important Build System Variables.
  • ZEPHYR_BASE: the absolute path to the main zephyr repository. This is set whenever you run the zephyr-env.sh or zephyr-env.cmd scripts mentioned above.
  • ZEPHYR_TOOLCHAIN_VARIANT: the current toolchain used to build Zephyr applications.

Important Build System Variables

You can control the Zephyr build system using many variables. This section describes the most important ones that every Zephyr developer should know about.


The variables BOARDCONF_FILE, and DTC_OVERLAY_FILE can be supplied to the build system in 3 ways (in order of precedence):

  • As a parameter to the west build or cmake invocation via the -D command-line switch
  • As Environment Variables.
  • As a set(<VARIABLE> <VALUE>) statement in your CMakeLists.txt
  • ZEPHYR_BASE: Sets the path to the directory containing Zephyr, which is needed by the build system’s boilerplate file. This is an environment variable set by the zephyr-env.sh script on Linux/macOS or zephyr-env.cmd on Windows, as you learned when getting started with Zephyr in Build the Blinky Application. You can also set ZEPHYR_BASE explicitly, but then you won’t get the other features provided by those scripts.
  • BOARD: Selects the board that the application’s build will use for the default configuration. See Supported Boards for built-in boards, and Board Porting Guide for information on adding board support.
  • CONF_FILE: Indicates the name of one or more configuration fragment files. Multiple filenames can be separated with either spaces or semicolons. Each file includes Kconfig configuration values that override the default configuration values.See The Initial Configuration for more information.
  • DTC_OVERLAY_FILE: Indicates the name of one or more devicetree overlay files. Multiple filenames can be separated with either spaces or semicolons. Each file includes devicetree values that override the default DT values. See Devicetree Overlays below for details on devicetree overlays, and Devicetree for an overview on devicetree and Zephyr.
  • ZEPHYR_MODULES: A CMake list containing absolute paths of additional directories with source code, Kconfig, etc. that should be used in the application build. See Modules (External projects) for details.

Rebuilding an Application

Application development is usually fastest when changes are continually tested. Frequently rebuilding your application makes debugging less painful as the application becomes more complex. It’s usually a good idea to rebuild and test after any major changes to the application’s source files, CMakeLists.txt files, or configuration settings.


The Zephyr build system rebuilds only the parts of the application image potentially affected by the changes. Consequently, rebuilding an application is often significantly faster than building it the first time.

Sometimes the build system doesn’t rebuild the application correctly because it fails to recompile one or more necessary files. You can force the build system to rebuild the entire application from scratch with the following procedure:

  1. Open a terminal console on your host computer, and navigate to the build directory <home>/app/build.
  2. Enter one of the following commands, depending on whether you want to use west or cmake directly to delete the application’s generated files, except for the .config file that contains the application’s current configuration information.
    • west build -t clean
    • or
    • ninja clean
  3. Alternatively, enter one of the following commands to delete all generated files, including the .config files that contain the application’s current configuration information for those board types.
    • west build -t pristine
    • or
    • ninja pristine
  4. If you use west, you can take advantage of its capability to automatically make the build folder pristine whenever it is required.
  5. Rebuild the application normally following the steps specified in Building an Application above.

Example 1:Hello World on nRF9160 DK

The first section (Your first “Hello World”) will show you how to create a minimal working example which function is to log “Hello World”, both using Segger Embedded Studio (SES) and the Zephyr extension commands in west. At the end of the section I will show you how to manage a multi repository environment using west, specifically how to update NCS and how to preserve you application when going from one revision of nrf to another.


#include <zephyr.h>
#include <misc/printk.h>

void main(void)
        printk("Hello World!\n");


# Copyright (c) 2019 Nordic Semiconductor ASA
# SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
# General config


Example 2 – Blinky LED

This example is to configure a particular LED for blinky on nRF9160 DK board. My target is to change the LED 0 to LED 3 for blinky.

Based on the Hello world example and add the LED blinky code inside the main.c.

#include <zephyr.h>
#include <device.h>
#include <stdio.h>
#include <misc/printk.h>
#include <drivers/gpio.h>


/* 1000 msec = 1 sec */
#define SLEEP_TIME  200

void main(void)
        printk("Hello World with LED!\n");

        u32_t cnt = 0;
        struct device *dev;

        dev = device_get_binding(LED_PORT);

        if (dev == NULL) {
                printf("Device not found\n");
        /* Set LED pin as output */
        gpio_pin_configure(dev, LED, GPIO_DIR_OUT);

        while (1) {
                /* Set pin to HIGH/LOW every 1 second */
                gpio_pin_write(dev, LED, cnt % 2);

Modify the prj.conf (add CONFIG_GPIO=y)

# Copyright (c) 2019 Nordic Semiconductor ASA
# SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
# General config





Add the overlay file (nrf9160_pca10090ns.overlay)

nRF9160 DK LED3 blinky

Example 3 – Detect the Button pressing

This example is to show how to configure the button from 1 to 2 and get the system tick.

  • Use the example from zephyr\samples\basic\button and copy it to nrf\github_xxx\nrf9160_pca10090
  • add the main.c and modify the prj.conf to enable the printk
  • main.c file as below
 * Copyright (c) 2016 Open-RnD Sp. z o.o.
 * SPDX-License-Identifier: Apache-2.0

#include <zephyr.h>
#include <device.h>
#include <drivers/gpio.h>
#include <sys/util.h>
#include <sys/printk.h>
#include <inttypes.h>

/* change this to use another GPIO port */
#ifdef SW0_GPIO_NAME
#error SW0_GPIO_NAME or DT_ALIAS_SW0_GPIOS_CONTROLLER needs to be set in board.h

/* change this to use another GPIO pin */
#error DT_ALIAS_SW0_GPIOS_PIN needs to be set in board.h

/* change to use another GPIO pin interrupt config */
 * If DT_ALIAS_SW0_GPIOS_FLAGS not defined used default EDGE value.
 * Change this to use a different interrupt trigger

/* change this to enable pull-up/pull-down */

/* Sleep time */
#define SLEEP_TIME 500

void button_pressed(struct device *gpiob, struct gpio_callback *cb,
                    u32_t pins)
        printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32());

static struct gpio_callback gpio_cb;

void main(void)
        struct device *gpiob;

        printk("Press the user defined button on the board\n");
        gpiob = device_get_binding(PORT);
        if (!gpiob) {

        gpio_pin_configure(gpiob, PIN,
                           GPIO_DIR_IN | GPIO_INT |  PULL_UP | EDGE);

        gpio_init_callback(&gpio_cb, button_pressed, BIT(PIN));

        gpio_add_callback(gpiob, &gpio_cb);
        gpio_pin_enable_callback(gpiob, PIN);

        while (1) {
                u32_t val = 0U;

                gpio_pin_read(gpiob, PIN, &val);
  • Add the overlay file (nrf9160_pca10090ns.overlay)

By pressing the button 2, it would show the result as below.

Example 4 — SSD1306 LCD 128 x 64

This example is to show how to port the SSD1306 LCD on the nRF9160 DK board. It is similar to the example which I did on the nRF52 DK board.


Zephyr has already supported multiple display drivers.


I plan to use the example character frame buffer as the baseline to do this demo. (https://docs.zephyrproject.org/latest/samples/display/display.html)

Basically, there is a display SSD1306 module on the zephyr project.


I used the nRF52840 DK (nrf52840_pca10056) to work with SSD1306 128×32 as example for testing.

Step 1: Modify the CMakeLists.txt

  • Add the SHIELD ssd1306_128x32
  • Add the nrf52840_pca10056

Step 2: Add the overlay to reconfigure the TWI pin

Command line on the nRF52840 DK board


SDA – GPIO 26, SCL – GPIO 27 on nRF52840 DK board

Example 5 — SD Card with nRF9160

Example 6 – SSD 1306 Display with nRF9160

Example 7 — 240×320 Display with nRF9160

If you have any suggestion which examples are interested, you can leave comments here.

I plan to continuous try on the example 5, 6, 7 on the next blog.

Continue …..on the Next Blog later……

4 thoughts on “Tutorial how to create an application on the nRF9160 DK

  1. Hi,
    I needed an application based help on the nRF9160DK. I am trying to schedule events based on real clock time. I want to turn on my modem everyday at 10:00 am in the morning and turn my modem off at 10:05 am. Can you help me out with a code for this kind of application.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.