Controlling User Buttons and LEDs

Controlling User Buttons and LEDs

1. Overview

This application note describes how to configure User Buttons and LEDs in Zephyr BSP and use them in the user application.

2. Configuring User Buttons and LEDs in Zephyr BSP

2.1. Configuring User Buttons

The User Button devices are declared in nrf9151som_nrf9151_common.dtsi.dts:

buttons: buttons { compatible = "gpio-keys"; button0: button_0 { gpios = <&gpio0 18 (GPIO_ACTIVE_LOW)>; label = "Push button S3"; zephyr,code = <INPUT_KEY_0>; }; button1: button_1 { gpios = <&gpio0 19 (GPIO_ACTIVE_LOW)>; label = "Push button S4"; zephyr,code = <INPUT_KEY_1>; }; };

The devicetree node configures the following parameters:

Parameter

Value

Description

Parameter

Value

Description

buttons

compatible

"gpio-keys"

Enables the input_gpio_keys.c driver and associates it with the device.

button0

gpios

<&gpio0 18 (GPIO_ACTIVE_LOW)>

GPIO pin.

label

"Push button S3"

Descriptive name of the key.

zephyr,code

<INPUT_KEY_0>

Key code to emit, which can be used by the application to process the key input.

button1

gpios

<&gpio0 19 (GPIO_ACTIVE_LOW)>

GPIO pin.

label

"Push button S4"

Descriptive name of the key.

zephyr,code

<INPUT_KEY_0>

Key code to emit, which can be used by the application to process the key input.

2.2. Configuring User LEDs

The User LED devices are declared in nrf9151som_nrf9151_common.dtsi.dts:

pwmleds0: pwmleds0 { compatible = "pwm-leds"; label = "LED1"; user1_pwm_led: user1_pwm_led { pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; }; }; pwmleds1: pwmleds1 { compatible = "pwm-leds"; label = "LED2"; user2_pwm_led: user2_pwm_led { pwms = <&pwm1 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; }; };

Parameter

Value

Description

Parameter

Value

Description

pwmleds0

compatible

"pwm-leds"

Enables the pwm.c driver and associates it with the device.

label

"LED1"

Descriptive name of the LED.

user1_pwm_led

pwms

<&pwm0 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>

PWM associated with LED1.

pwmleds1

compatible

"pwm-leds"

Enables the pwm.c driver and associates it with the device.

label

"LED2"

Descriptive name of the LED.

user2_pwm_led

pwms

<&pwm1 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>

PWM associated with LED2

The LEDs also require the PWM to be configured in the device tree:

&pwm0 { status = "okay"; pinctrl-0 = <&pwm0_default>; pinctrl-1 = <&pwm0_sleep>; pinctrl-names = "default", "sleep"; }; &pwm1 { status = "okay"; pinctrl-0 = <&pwm1_default>; pinctrl-1 = <&pwm1_sleep>; pinctrl-names = "default", "sleep"; };

3. Handling User Buttons and LEDs in User Application

The button and LED-related modules are implemented in buttons.c, led_module.c and UI module files:

  • buttons.c defines a callback for the input_gpio_keys.c driver. Once the button is pressed or released, the callback generates one of the following events:

    • BUTTON_EVT_USER1_PRESSED and BUTTON_EVT_USER1_RELEASED for User Button 1.

    • BUTTON_EVT_USER2_PRESSED and BUTTON_EVT_USER2_RELEASED for User Button 2.

  • led_module.c makes use of the Nordic CAF library, which is able to perform complex LED effects. The LED defines the following conditions and effects for User LED1 and User LED2:

    • LED1 starts blinking with 500 ms period while the User Button 1 is pressed and the BUTTON_EVT_USER1_PRESSED event is received by the module. The LED stops blinking once the button is released and the module receives the BUTTON_EVT_USER1_RELEASED event.

    • LED2 starts blinking with 500 ms period while the User Button 2 is pressed and the BUTTON_EVT_USER1_PRESSED event is received by the module. The LED stops blinking once the button is again.

  • the ui_module.c is used to send a mask representation of the buttons state to the cloud every time when one of the button events is received by the module:

    • 0 if none of the buttons is pressed.

    • 1 if only User 1 button is pressed.

    • 2 if only User 2 button is pressed.

    • 3 if both buttons are pressed.

3.1. User Button Shell Commands

The application also defines a set of shell commands in button_shell.c, which can be used to emulate button events:

Command

Parameters

Comments

button

 <usr1|usr2>

<pressed|released>

Generate an appropriate event for User Button 1 or 2.

4. Validating User Buttons and LEDs

4.1. Validating Hardware Buttons and LEDs

  1. Press and hold the User 1 button and verify.

  2. Verify that the following messages are printed to the console and the User LED 1 on the baseboard started blinking:

    ... [00:32:38.469,451] <inf> ui_module: BUTTON_EVT_USER1_PRESSED [00:32:38.469,543] <inf> led_module: BUTTON_EVT_USER1_PRESSED ...
  3. Release the User 1 button.

  4. Verify that the following messages are printed to the console and the User LED 1 on the baseboard stopped blinking:

    ... [00:33:10.949,310] <inf> ui_module: BUTTON_EVT_USER1_RELEASED [00:33:10.949,371] <inf> led_module: BUTTON_EVT_USER1_RELEASED ...
  5. Press and release the User 2 button.

  6. Verify that the following messages are printed to the console and the User LED 2 on the baseboard started blinking:

    ... [00:37:36.719,238] <inf> ui_module: BUTTON_EVT_USER2_PRESSED [00:37:36.719,299] <inf> led_module: BUTTON_EVT_USER2_PRESSED ... [00:37:40.889,739] <inf> ui_module: BUTTON_EVT_USER2_RELEASED [00:37:40.889,831] <inf> led_module: BUTTON_EVT_USER2_RELEASED ...
  7. Press and release the User 2 button.

  8. Verify that the following messages are printed to the console and the User LED 2 on the baseboard stopped blinking:

    ... [00:37:36.719,238] <inf> ui_module: BUTTON_EVT_USER2_PRESSED [00:37:36.719,299] <inf> led_module: BUTTON_EVT_USER2_PRESSED ... [00:37:40.889,739] <inf> ui_module: BUTTON_EVT_USER2_RELEASED [00:37:40.889,831] <inf> led_module: BUTTON_EVT_USER2_RELEASED ...

4.2. Validating GPIO integration with nRF Cloud

  1. Check the board uuid from the nRF9151 console (it is assumed that the nRF Device provisioning procedure has been performed earlier):

    uart:~$ nrf_provisioning uuid 50343959-3733-4c71-806b-202470cee0bf
  2. Check that the board has successfully connected to the cloud over LTE:

    [00:00:02.824,615] <inf> app_event_manager: MODEM_EVT_LTE_CONNECTING [00:00:04.110,168] <inf> app_event_manager: MODEM_EVT_LTE_CELL_UPDATE [00:00:15.095,916] <inf> app_event_manager: MODEM_EVT_LTE_CONNECTED [00:00:15.234,283] <inf> cloud_module: DEVICE CERTIFICATE IS PRESENT [00:00:15.236,907] <inf> app_event_manager: CLOUD_EVT_CONNECTING [00:00:15.237,426] <inf> app_event_manager: MODEM_EVT_LTE_PSM_UPDATE [00:00:15.237,915] <inf> app_event_manager: DATA_EVT_DATE_TIME_OBTAINED [00:00:22.080,871] <inf> net_mqtt: Connect completed
  3. Press and hold the User 1 button (the button emulation from the nrf9151 console can be used):

    uart:~$ button usr1 pressed Button usr1 pressed [00:10:26.663,482] <inf> ui_module: BUTTON_EVT_USER1_PRESSED [00:10:26.663,543] <inf> led_module: BUTTON_EVT_USER1_PRESSED [00:10:26.663,635] <inf> app_event_manager: UI_EVT_BUTTON_DATA_READY [00:10:26.664,031] <inf> app_event_manager: DATA_EVT_UI_DATA_READY [00:10:26.665,405] <inf> app_event_manager: DATA_EVT_UI_DATA_SEND [00:10:26.666,198] <inf> app_event_manager: CLOUD_EVT_DATA_SEND_QOS
  4. Press and release the User 2 button (the button emulation from the nrf9151 console can be used):

    uart:~$ button usr2 pressed Button usr2 pressed [00:10:32.105,346] <inf> ui_module: BUTTON_EVT_USER2_PRESSED [00:10:32.105,438] <inf> led_module: BUTTON_EVT_USER2_PRESSED [00:10:32.105,529] <inf> app_event_manager: UI_EVT_BUTTON_DATA_READY [00:10:32.106,018] <inf> app_event_manager: DATA_EVT_UI_DATA_READY [00:10:32.107,360] <inf> app_event_manager: DATA_EVT_UI_DATA_SEND [00:10:32.108,184] <inf> app_event_manager: CLOUD_EVT_DATA_SEND_QOS uart:~$ button usr2 released Button usr2 released [00:10:38.058,990] <inf> ui_module: BUTTON_EVT_USER2_RELEASED [00:10:38.059,051] <inf> led_module: BUTTON_EVT_USER2_RELEASED [00:10:38.059,143] <inf> app_event_manager: UI_EVT_BUTTON_DATA_READY [00:10:38.059,478] <inf> app_event_manager: DATA_EVT_UI_DATA_READY [00:10:38.060,852] <inf> app_event_manager: DATA_EVT_UI_DATA_SEND [00:10:38.061,645] <inf> app_event_manager: CLOUD_EVT_DATA_SEND_QOS
  5. Release the User 1 button:

    uart:~$ button usr1 released Button usr1 released [00:10:45.128,936] <inf> ui_module: BUTTON_EVT_USER1_RELEASED [00:10:45.128,997] <inf> led_module: BUTTON_EVT_USER1_RELEASED
  6. Press and release the User 2 button again:

    uart:~$ button usr2 pressed Button usr2 pressed [00:10:48.296,203] <inf> ui_module: BUTTON_EVT_USER2_PRESSED [00:10:48.296,264] <inf> led_module: BUTTON_EVT_USER2_PRESSED uart:~$ button usr2 released Button usr2 released [00:10:52.516,571] <inf> ui_module: BUTTON_EVT_USER2_RELEASED [00:10:52.516,632] <inf> led_module: BUTTON_EVT_USER2_RELEASED
  7. Login to the nRF Cloud and go to the DEVICE MANAGEMENT / Devices page. Find the board by the uuid ID and open the board page.

  8. Scroll down to Custom App: BUTTON graph and observe that BUTTON value has changed:

    image-20250228-150429.png

Related content