This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Understanding demo1 in Nordic SDK PWM driver example code.

Hello,

I am having trouble understanding how the following function in the PWM driver example under peripherals in the SDK. Below is demo1 from the code that creates and alternating LED display on the Development Kit: 

static void demo1(void)
{
NRF_LOG_INFO("Demo 1");

/*
* This demo plays back a sequence with different values for individual
* channels (LED 1 - LED 4). Only four values are used (one per channel).
* Every time the values are loaded into the compare registers, they are
* updated in the provided event handler. The values are updated in such
* a way that increase and decrease of the light intensity can be observed
* continuously on succeeding channels (one second per channel).
*/

nrf_drv_pwm_config_t const config0 =
{
.output_pins =
{
BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED // channel 3
},
.irq_priority = APP_IRQ_PRIORITY_LOWEST,
.base_clock = NRF_PWM_CLK_1MHz,
.count_mode = NRF_PWM_MODE_UP,
.top_value = m_demo1_top,
.load_mode = NRF_PWM_LOAD_INDIVIDUAL,
.step_mode = NRF_PWM_STEP_AUTO
};
APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, demo1_handler));
m_used |= USED_PWM(0);

m_demo1_seq_values.channel_0 = 0;
m_demo1_seq_values.channel_1 = 0;
m_demo1_seq_values.channel_2 = 0;
m_demo1_seq_values.channel_3 = 0;
m_demo1_phase = 0;

(void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1,
NRF_DRV_PWM_FLAG_LOOP);
}

I want to change this code to allow for my own setting of PWM duty cycles all concurrently with no oscillations. How would I go about doing this with this section? I have other questions but the core of what I want is to edit this to be as simple and configurable as possible.

Parents
  • Hello,

    So you "don't want any patterns or oscillations, is that correct?

    So maybe something that could control a PWM motor, where you set one PWM duty cycle, which will stay until you set it again?

    If that is the case, I suggest that you check out the pwm_library example instead. Although the LEDs flash, this is all done by a counter in the main()-loop, which continuously updates the duty cycles. If you comment this out, you can set the PWM duty cycles as you like.

    Best regards,

    Edvin

Reply
  • Hello,

    So you "don't want any patterns or oscillations, is that correct?

    So maybe something that could control a PWM motor, where you set one PWM duty cycle, which will stay until you set it again?

    If that is the case, I suggest that you check out the pwm_library example instead. Although the LEDs flash, this is all done by a counter in the main()-loop, which continuously updates the duty cycles. If you comment this out, you can set the PWM duty cycles as you like.

    Best regards,

    Edvin

Children
  • Thanks, I will investigate this. I want to set all 4 PWM channels to 4 different pins but don't understand how it is done currently through this code.

  • RyanA said:
    I want to set all 4 PWM channels to 4 different pins but don't understand how it is done currently through this code.

     In the pwm_library example?

    Each PWM instance has two channels which pins are set in:

    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(5000L, BSP_LED_0, BSP_LED_1);

    BSP_LED_0 and BSP_LED_1 are the pins. If you want 4 channels, you must use two instances of PWM. 

    Then you have to actually initialize the PWM using app_pwm_init(), and then you can set the duty cycle using app_pwm_channel_duty_set(&PWM_instantce, channel_number, value);

    So if you have two instances, PWM1 and PWM2, and each have two channels, and you want to set all channels to 50% duty cycle, you would have to do:

    while(app_pwm_channel_duty_set(PWM1, 0, 50) == NRF_ERROR_BUSY);
    while(app_pwm_channel_duty_set(PWM1, 1, 50) == NRF_ERROR_BUSY);
    while(app_pwm_channel_duty_set(PWM2, 0, 50) == NRF_ERROR_BUSY);
    while(app_pwm_channel_duty_set(PWM2, 1, 50) == NRF_ERROR_BUSY);

Related