Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

PWM Driver - Proper Way to Update Sequence

I am using a nRF52832 and v14.2 of the Nordic SDK.


I have a question about the PWM Driver. I have the pwm driver working and driving an LED, but it is unclear to me how to properly update the sequence. I have scanned the forum, and the answers I found did not resolve the issue I am seeing. I also saw functions like nrf_drv_pwm_sequence_update, but the issue I'm seeing still occurred.


I am only using 1 channel and for the normal mode of operation, I just need the pwm to drive at a set duty cycle, so this is how it is set up:

nrf_drv_pwm_config_t const config0 =

{
        .output_pins =
        {
                BSP_LED_PWM_PIN | NRF_DRV_PWM_PIN_INVERTED,
                NRF_DRV_PWM_PIN_NOT_USED,
                NRF_DRV_PWM_PIN_NOT_USED,
                NRF_DRV_PWM_PIN_NOT_USED
        },
        .irq_priority = APP_IRQ_PRIORITY_LOW,
        .base_clock   = NRF_PWM_CLK_4MHz,
        .count_mode   = NRF_PWM_MODE_UP,
        .top_value    = PWM_TOPVALUE,
        .load_mode    = NRF_PWM_LOAD_COMMON,
        .step_mode    = NRF_PWM_STEP_AUTO

};


static nrf_pwm_values_common_t pwm_singleSequenceValue[] = { 0 }; // Size of 1

nrf_pwm_sequence_t const seq =
{
 .values.p_common = pwm_singleSequenceValue,
 .length = NRF_PWM_VALUES_LENGTH(pwm_singleSequenceValue),
 .repeats = 100,
 .end_delay = 0
};
 
nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 2, NRF_DRV_PWM_FLAG_LOOP);



I then at another time call this from a function:

static uint16_t warning1Values1[] = { ... }; // assume 23 initial values
static flashSequence_t warning1Sequence2 = {
 .values = warning1Values1,
 .length = (sizeof(warning1Values1) / sizeof (uint16_t)),
 .stepTimeMS = 32,
 .endDelayMS = 10000
};

nrf_pwm_sequence_t const sequence1 =
{
  .values.p_common = warning1Sequence2.values,
  .length = warning1Sequence2.length,
  .repeats = pwm_convertMSToSteps(warning1Sequence2.stepTimeMS),
  .end_delay = pwm_convertMSToSteps(warning1Sequence2.endDelayMS)
};

 
nrf_drv_pwm_simple_playback(&m_pwm0, &sequence1, 2, NRF_DRV_PWM_FLAG_LOOP);


What I am experiencing is that when I do the above, is that the sequence only plays once, does the endDelay, then loops back and then it plays the sequence twice (correctly). The very first time never plays it twice.

Let me know if I need to elaborate. Some of the code above is my code, but most of it is standard from the reference examples.

Thank you,

amorgan

  • Hi 

    Just to be clear, some times you need to set the PWM to a static value, and other times you want to play a sequence?

    I modified the standard SDK example to do something similar, and you will find it attached. Pressing button 1 will start a sequence, and pressing button 2 will set the 4 LED's to static values. 

    Exactly what is wrong with your example I am not sure. If you are trying to play a sequence I would use NRF_DRV_PWM_FLAG_STOP rather than NRF_DRV_PWM_FLAG_LOOP. Otherwise there is nothing in your code that jumps out at me.

    Best regards
    Torbjørn

     

  • ovrebekk, thanks for the example code. I have modified your example to reproduce the error that I am seeing in my code.

    I set Channels 1 - 3 to NRF_DRV_PWM_PIN_NOT_USED. And modified the sequence to match what I am trying to achieve. I do want the flashing sequence to loop because I would like for this to loop until the state is changed (this will act as a warning sequence).

    The issue I am seeing is that after pressing button 2, to start the "static" sequence, that is just one value, then pressing button 1 to start the "flashing" sequence, even though the playback is set to 2, on the very first playback, it only plays it once, delays, then every sequence after that, it does playback twice, then loops.

    More succinctly :

    1) Press Button 2

    2) LED 1 is on static

    3) Press Button 1

    4) LED 1 turns off, turns on (not expected)

    5) LED 1 sequence delays

    6) LED 1 turns off, turns on, turns off, turns on (exprected)

    7) LED 1 sequence delays

    8) Sequence continues to loop

    Step 4 is what is not expected. I expect it to behave like step 6 immediately.

    Thank you,

    /cfs-file/__key/communityserver-discussions-components-files/4/8780.pwm_5F00_driver_5F00_sequence_5F00_static_5F00_modified.zip

  • Hi 

    Thanks for the project, I see the same issue here. 

    The behavior seems to be caused by two factors:

    a) The end_delay is added between each playback of the sequence, not after the sequence has looped X number of times. 

    b) On the last loop the end_delay is not added, so that the sequence is played back twice in succession. 

    This behavior is more obvious if you increase the loop count to 3. 

    I will check with the SDK guys next week if this is expected behavior, or if there is some bug in the driver. 

    As a temporary workaround I would suggest the following: Set the end_delay to 0, and use the loop value to determine how many times the sequence should loop before the delay. 

    Use an app_timer (or a dedicated RTC timer) to control the delay between sequence loops, rather than the end_delay factor. The simplest way to do this is to call nrf_drv_pwm_simple_playback(..) directly from the app_timer callback. 

    Best regards
    Torbjørn

Related