· Nordic  · 4 min read

Beginner's Guide to Handling Button Inputs on nRF7002 DK with VS Code and nRF Connect SDK

In this guide, we’ll walk you through the process of setting up a project to handle button inputs on the nRF7002 DK. Using the nRF Connect SDK and VS Code, you’ll learn how to configure GPIO, write interrupt-driven button input code, and flash your board. Whether you're just starting with Nordic Semiconductor’s development kits or looking to enhance your embedded projects, this tutorial covers all the essential steps, from environment setup to writing functional code and testing it in action.

Table of Contents

  1. Introduction
  2. Creating a New Project in VS Code
  3. Adding Button Input Code
  4. Code Breakdown
  5. Building and Flashing the Project
  6. Conclusion

Introduction

If you’re working with Nordic’s nRF7002 DK, you’re likely using it alongside a host like the nRF5340 SoC. While the nRF7002 handles Wi-Fi, GPIOs (including buttons) are handled by the host. In this post, we’ll show you how to handle button inputs using Zephyr RTOS, the nRF Connect SDK, and the nRF Connect extension in VS Code.


Creating a New Project in VS Code

Inside VS Code:

  1. Click the nRF Connect icon in the sidebar.
  2. Select “Create a new application”
  3. Fill out:
    • Application Name (e.g., button_example)
    • Template: choose empty
    • SDK Version: the version you installed

Once created, you’ll see your project structure in the Explorer.


Adding Button Input Code

Edit prj.conf:

CONFIG_GPIO=y

Replace main.c with:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>

#define BUTTON_NODE DT_ALIAS(sw0)

static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(BUTTON_NODE, gpios, {0});
static struct gpio_callback button_cb_data;

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    printk("Button pressed at pin %d\n", button.pin);
}

void main(void)
{
    int ret;

    if (!device_is_ready(button.port)) {
        printk("Error: button device %s is not ready\n", button.port->name);
        return;
    }

    ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
    if (ret != 0) {
        printk("Error %d: failed to configure %s pin %d\n", ret, button.port->name, button.pin);
        return;
    }

    ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
    if (ret != 0) {
        printk("Error %d: failed to configure interrupt on %s pin %d\n", ret, button.port->name, button.pin);
        return;
    }

    gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
    gpio_add_callback(button.port, &button_cb_data);

    printk("Set up button at %s pin %d\n", button.port->name, button.pin);
}

Code Breakdown

Let’s go through the code step by step to understand how it works.

1. Include Necessary Headers

The necessary Zephyr headers are included at the top of the file:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
  • kernel.h is for Zephyr’s kernel functionality.
  • device.h gives access to the device model, allowing interaction with hardware like GPIOs.
  • gpio.h provides functions specific to GPIO pins, which is crucial for interacting with buttons.

2. Device Tree Alias for Button

We define the device tree alias for the button using Zephyr’s device tree macros:

#define BUTTON_NODE DT_ALIAS(sw0)
  • The button sw0 is referenced using DT_ALIAS(sw0), which connects to the device tree definition for the button, usually defined in the board’s .dts file.

3. Declare GPIO Spec and Callback

We declare the GPIO device specification (gpio_dt_spec) and a GPIO callback structure:

static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(BUTTON_NODE, gpios, {0});
static struct gpio_callback button_cb_data;
  • button specifies the GPIO pin configuration for sw0.
  • button_cb_data will hold the callback function triggered by the button press event.

4. Button Press Callback Function

The callback function button_pressed() gets triggered whenever the button is pressed:

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    printk("Button pressed at pin %d\n", button.pin);
}
  • This function prints a message when the button is pressed, using printk(), which is Zephyr’s logging function.

5. Main Function – GPIO Setup

The main function does several important things:

a. Check if Device is Ready

if (!device_is_ready(button.port)) {
    printk("Error: button device %s is not ready\n", button.port->name);
    return;
}
  • This checks if the button device (button.port) is ready for use. If not, it logs an error and returns.

b. Configure GPIO Pin as Input

ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
if (ret != 0) {
    printk("Error %d: failed to configure %s pin %d\n", ret, button.port->name, button.pin);
    return;
}
  • This sets up the button GPIO pin as an input pin. The function gpio_pin_configure_dt() is used to configure the pin based on the device tree specification.

c. Configure Interrupt for Button Press

ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
if (ret != 0) {
    printk("Error %d: failed to configure interrupt on %s pin %d\n", ret, button.port->name, button.pin);
    return;
}
  • This configures the button to generate an interrupt on a rising edge (button press). The interrupt will trigger the callback function defined earlier.

d. Initialize the GPIO Callback

gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
gpio_add_callback(button.port, &button_cb_data);
  • gpio_init_callback() initializes the callback function for the button press.
  • gpio_add_callback() registers the callback function with the GPIO device, so it gets invoked on interrupt.

6. Logging Information

At the end of the main function, a log message is printed to confirm that the button is set up correctly:

printk("Set up button at %s pin %d\n", button.port->name, button.pin);

Building and Flashing the Project

To Build:

  • Create a new build configuration, and choose nRF7002dk board
  • Click the “Generate and Build” button

To Flash:

  • Plug in the board via USB
  • Click the “Flash” button in the sidebar
  • You’ll see log output from the board via the “Terminal” or “Serial Monitor”

Press the sw0 button and watch your log say:

Button pressed at pin 8

Conclusion

Handling GPIO button inputs on the nRF7002 DK is simple once your development environment is properly set up. Using the nRF Connect SDK with VS Code provides a smooth workflow, and Zephyr’s powerful APIs make hardware interaction clean and readable.

Now that you’ve mastered basic input, you can expand into LEDs, sensors, and eventually Wi-Fi-enabled logic with the nRF7002’s companion features.

Happy building!

  • nrf7002-dk
  • nordic-semiconductor
  • nrf-connect-sdk
  • iot-development
  • button

Related articles

View All Articles »

Getting Started with the nRF7002: Blink an LED Using the nRF Connect SDK

In this tutorial, we’ll walk you through everything you need to get started with the nRF7002 Development Kit—from setting up your development environment to writing and flashing your first embedded application. We'll use the classic “blinky” example to demonstrate how to blink an LED using Zephyr RTOS and the nRF Connect SDK. By the end of this guide, you’ll have a solid foundation for working with Nordic Semiconductor’s powerful dual-core nRF5340 SoC, which powers the nRF7002 DK.

Understanding Semaphores in Zephyr OS on nRF7002DK

Semaphores are powerful synchronization primitives in Zephyr OS, enabling efficient task coordination and resource management in real-time embedded systems. In this blog post, we explore how semaphores work in Zephyr OS, with a practical example on the nRF7002DK board. Learn how to implement a producer-consumer pattern using semaphores to synchronize threads, and discover best practices for embedded development.

Zephyr OS Logging Module: A Guide with nRF7002DK Example

Discover how to leverage the Zephyr OS logging module for efficient debugging and diagnostics in embedded systems. This guide dives into the module’s features, configuration, and practical implementation using the nRF7002DK, a versatile development kit for IoT applications.

Your Practical Roadmap to Mastering Zephyr OS with the nRF7002DK

Jumping into Zephyr OS development on the nRF7002DK can feel overwhelming — but it doesn't have to be. In this step-by-step roadmap, we'll guide you from your first blinking LED to full-fledged Wi-Fi-connected sensor devices, so you can become a confident embedded developer.