You are currently not logged in and your progress will not be saved. Register or Log in

Exercise 1

Controlling an LED through a button (polling based)

In this exercise, we will modify the blinky example so that LED1 is turned on only when button 1 is being pressed.

To do this we will use the polling method, as discussed in GPIO Generic API. This is done by continuously polling the CPU to check if the button was pressed and then update the LED accordingly. In Exercise 2 that follows, we will learn how to use GPIO interrupts, which is more power-efficient than polling.

If we recall the schematic of the nRF52833 DK, there are four push-buttons connected to the same GPIO peripheral (GPIO_0 , aka: gpio0) as the LEDs. This can be seen in the GPIO pin mapping, for instance notice that button 1 is connected to P0.11. The 0 in P0 symbolizes it is GPIO_0.

nRF52833 DK button location
nRF52833 DK button pin mapping

This is why the same driver, the GPIO_0 driver, is needed for both the LEDs and buttons. This is also evident from the DK’s devicetree file nrf52833dk_nrf52833.dts.

	buttons {
		compatible = "gpio-keys";
		button0: button_0 { 
			gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "Push button switch 0";
		};
		button1: button_1 {
			gpios = <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "Push button switch 1";
		};
/* ... */
		};
	};

/* ... */
	/* These aliases are provided for compatibility with samples */
	aliases {
/* ... */
		sw0 = &button0;
		sw1 = &button1;
		sw2 = &button2;
		sw3 = &button3;
		bootloader-led0 = &led0;
	};
};
nrf52833dk_nrf52833.dts file

Button 1 on the nRF52833 DK is given the node name button_0, which has two aliases (sw0 and button0) and is connected to GPIO_0, pin 11. Remember, indexing in the devicetree files always starts from 0, which is why button 1 on the board is called button0.

gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;

Note

If the buttons are connected to a different GPIO (ex. GPIO_1) than the LEDs, a new device driver binding is required. Luckily, this is not the case for any official Nordic Semiconductor development kits.

Exercise Steps:

1. If you haven’t already done this, create a folder close to your root directly that will hold all the exercises that we will be working on throughout this course. We will create that folder on the C drive in C:\nordic\myapps.

 Download the base exercise project and extract it in this folder. The exercise code is based on the blinky example.  

2. Open the exercise code base in VS Code.

2.1 From the Welcome window in the nRF Connect extension, click on Add an existing application.

Then, browse to the directory where you have extracted the code base and click on Select Folder.

Open main.c from the Explorer in VS Code as shown in the screenshot below:

3. Define the symbol that will represent the button on the board. This is done by calling the appropriate devicetree APIs, same way as was done in the blinky example.

In main.c , search for STEP 3 and add (copy and paste) the following lines:

#define SW0_NODE    DT_ALIAS(sw0)

#if DT_NODE_HAS_STATUS(SW0_NODE, okay)
#define SW0_GPIO_LABEL  DT_GPIO_LABEL(SW0_NODE, gpios)
#define SW0_GPIO_PIN    DT_GPIO_PIN(SW0_NODE, gpios)
#define SW0_GPIO_FLAGS  DT_GPIO_FLAGS(SW0_NODE, gpios)
#else
#error "Unsupported board: sw0 devicetree alias is not defined"
#define SW0_GPIO_LABEL  ""
#define SW0_GPIO_PIN    0
#define SW0_GPIO_FLAGS  0
#endif

4. Configure the pin connected to the button to be an input pin and set its hardware specifications.

Inside main(), search for STEP 4 and add the following lines:

    ret = gpio_pin_configure(dev, SW0_GPIO_PIN, GPIO_INPUT | SW0_GPIO_FLAGS);
    if (ret < 0) {
        return;
    }

5. In the main loop of our exercise, we will indefinitely poll the CPU to read the status (pressed = 1 , unpressed = 0) of the button and update the LED to the status of the button.

Search for STEP 5, add the following code inside the infinite loop:


        bool val; //A variable that stores the status of the button (pressed = 1 , unpressed = 0)
        val = gpio_pin_get(dev, SW0_GPIO_PIN); //Read the status of the button
        gpio_pin_set(dev, PIN, val); //Update the LED to the status of the button
        k_msleep(SLEEP_TIME_MS); // Put the CPU to sleep for 100ms so it does not consume power

6. Change the sleep time from 1000 ms to 100 ms. 100 ms is about the right time to put the main thread to sleep and still be able to respond in time when the button is pressed.

7. Add a build configuration, like we did in Lesson 1 Exercise 2.

8. Build the exercise and flash it to the board as we have done in the previous lesson. Observe that when button 1 is pressed, LED1 is turned ON.

You can download the solution for Exercise 1 below.