Feedback
Feedback

If you are having issues with the exercises, please create a ticket on DevZone: devzone.nordicsemi.com
Click or drag files to this area to upload. You can upload up to 2 files.

Exercise 1 – Controlling an LED with PWM

In this exercise, we will use a generated PWM signal to control an LED on the DK.

You will practice using the PWM API in nRF Connect SDK to initialize a PWM device and learn how changing the PWM period and pulse affects the behavior of the LED.

This exercise will show you how to use Zephyrs API to get and use a predefined pwm compatible node.

Exercise steps

Open the code base of the exercise by navigating to Create a new application in the nRF Connect for VS Code extension, select Copy a sample, and search for Lesson 4 – Exercise 1.

Alternatively, in the GitHub repository for this course, go to the base code for this exercise, found in lesson4/inter_less4_exer1.

1. Enable the PWM module in your application.

1.1 Enable the PWM module and set the logging level.

Add the following lines to the prj.conf file

CONFIG_PWM=y
CONFIG_PWM_LOG_LEVEL_DBG=y
Kconfig

1.2 Enable LED and LED PWM.

Add the following lines to the prj.conf file

CONFIG_LED=y
CONFIG_LED_PWM=y
Kconfig

1.3 Include the relevant PWM header files

Add the following lines in main.c

#include <zephyr/device.h>
#include <zephyr/drivers/pwm.h>
C

2. Define the desired PWM period and pulse

Define the PWM period and pulse, as the macros PWM_PERIOD_NS and PWM_PULSE_NS

Add the following lines to main.c

#define PWM_PERIOD_NS 20000000
#define PWM_DUTY_CYCLE 1400000
C

3. Initialize the PWM LED device on the hardware.

3.1 Get the node identifier through its alias pwm_led0.

Using DT_ALIAS(), which takes an alias and returns the device’s node identifier.

#define PWM_LED0    DT_ALIAS(pwm_led0)
C

3.2 Initialize and populate the struct pwm_dt_spec using PWM_DT_SPEC_GET().

We want to get the device pointer, pin number, and pin configuration flags through pwm_dt_spec. This can be done using the API-specific PWM_DT_SPEC_GET(), which takes the node identifier, and populates the struct pwm_dt_spec with the information from that device.

static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(PWM_LED0);
C

3.3 Check if the device is busy.

Now we need to verify if the device is ready to use, using pwm_is_ready_dt(), which has the following signature

Add the following code snippet in main.c

if (!pwm_is_ready_dt(&pwm_led0)) {
	LOG_ERR("Error: PWM device %s is not ready\n", pwm_led0.dev->name);
	return 0;
}
C

4. Control the LED with the control signal generated from the PWM.

We will use pwm_set_dt() to set the period and pulse width of the device after initializing it.

Add the following code snippet in main.c

err = pwm_set_dt(&pwm_led0, PWM_PERIOD_NS, PWM_DUTY_CYCLE);
if (err) {
    LOG_ERR("Error in pwm_set_dt(), err: %d", err);
    return 0;
}
C

5. Build and flash the application to your device.

LED1 on your device should glow slightly.

Try changing the pulse and/or period and observe the changes. If the value is set too high or too low, it may be out of range of what your hardware can reach.

For instance, let’s set the parameters to

#define PWM_PERIOD_NS 100000000
#define PWM_DUTY_CYCLE 14000000
C

Notice that the LED is now blinking very quickly.

The solution for this exercise can be found in the GitHub repository, lesson4/ncs-inter_less4_exer1_solution.

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

  • 8 or more characters
  • Upper and lower case letters
  • At least one number or special character

Forgot your password?
Enter the email associated with your account, and we will send you a link to reset your password.