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

NRF52 Dim LED with PWM Driver

I am migrating from nrf51 to nrf52. Using SDK12.1

On NRF51, I used the PWM Library to use 2 buttons on the DK to dim up or down onboard LED1 (called OUTPUT_LED). It worked great (not sure if it did it properly or not). The code was fairly simple.

I set up the PWM

APP_PWM_INSTANCE(PWM1,1);

I then initialize PWM:

app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000L, OUTPUT_LED);

app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);

app_pwm_enable(&PWM1);

while (app_pwm_channel_duty_set(&PWM1, 0, pwm_value) == NRF_ERROR_BUSY);

I then call the code in the button handler to dim up or down.

if (button_action == APP_BUTTON_PUSH)  { 

switch (pin_no)
{
    case DIM_UP_BUTTON:
        if (pwm_value<100)
        {
           ++pwm_value; 
        }
            
        while (app_pwm_channel_duty_set(&PWM1, 0, pwm_value) == NRF_ERROR_BUSY);
        break;

    case DIM_DOWN_BUTTON:
        if (pwm_value >1)
        {
            --pwm_value;    
        }
        
        while (app_pwm_channel_duty_set(&PWM1, 0, pwm_value) == NRF_ERROR_BUSY);
        
        break;
        
    default:
        APP_ERROR_HANDLER(pin_no);
        break;}

I am looking at the examples for using the hardware PWM driver that the nrf52 has. They look super confusing! So many parameters.I just want to dim an LED at a set frequency. Can someone help me with a code example for the PWD driver that will work similarly? I would like to do this using the nrf52 hardware PWM versus using the extra resources needed with the PWM library method. I appreciate the help!, Bryan

Parents
  • Hi Bryan

    Yeah, I must agree with you, the pwm_driver example in SDK 12.1.0 has a lot of parameters. I figured out how things worked by looking at image 2 in the PS PWM chapter to realize that there is a counter that counts up to the specified top value, which is one pwm period, and then repeats the sequence.

    I have attached a simplified (hopefully) example which is more or less the code presented in the pwm_driver documentation. Example output: Light intensity on LED_1 on the nRF52-DK is gradually increased and that sequence is repeated 4 times.

    How it works:

    • base_clock runs at 1MHz and the top value is 1000. This means that the base clock ticks every 1 us and the top value is reached every 1us*1000=1ms
    • The seq_values array includes 10 values. The first value in the array (value 0) is repeated 100 times (.repeats = 100), this means that the duty cycle is 0% for 1us* 1000* 100=100ms
    • The next value is also repeated 100 times, i.e. for 100ms, namely the value 100, which gives 10% duty cycle
    • After the last value has run for its 100ms, we delay it extra 500ms (end_delay = 500) before repeating the whole sequence

    We can make this sequence repeat forever by setting

    nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 4, NRF_DRV_PWM_FLAG_LOOP);
    

    or play the sequence only 4 times with

    nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 4, NRF_DRV_PWM_FLAG_STOP);
    

    There is not much more to this example. The BSP is initialized and the bsp_evt_handler is defined so you can insert any code for desired button action into this handler.

    pwm_driver_simple.zip

    An updated version of the example that compiles in SDK v13 can be found here:
    pwm_driver_simple_sdk13.zip

  • Hi Bndit

    I just updated the answer with a new version of the example that compiles under SDK v13.

Reply Children
No Data
Related