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

nRF5 SDK15.0 - PWM Driver: Just set a fixed duty cycle?

The PWM Driver has all sorts of fancy stuff for dealing with clever sequences - but I can't see anything to just set a simple, steady, fixed duty cycle!

How does one just set a fixed duty cycle?

What I actually want is to be able to fade an LED up to a certain brightness; so what I really want is to be able to specify an increasing sequence, and then a steady duty cycle to last indefinitely once the fade-up sequence completes.

Is there a simple way to do that?

Parents
  • Hello,

    I would agree to some degree of what you are saying. The PWM driver example is good for fancy PWM LEDs, but if you want a simple PWM with a fixed period and a dimmed LED that is easily controllable, it might be easier to use the PPI module with a timer.

    Attached is a simple PPI example that does this. If you run it on an nRF52DK, it shouldn't need any modifications. It should dim 2 LEDs in a pattern.

    The PPI setup might look a bit scary, but the function that is actually controlling the LEDs duty cycle is controlled from the main() function. Note that for simplicity, the example uses nrf_delay_ms(), which is not a good approach, power consumption vise. 

    ppi_double_channel_pwm.zip

    Note that the pwm[0/1]_set_duty_cycle() doesn't need to use the sin_scaled() function. You can set it to any value between 1 and 1024 (TIMER_RELOAD), which is the number of ticks in the current setup.

    You can change the TIMER_RELOAD to change the period of your PWM signal.

    In the zip-folder attached, only a Keil project is included. But you should be able to change any of the main.c files from the projects in SDK\examples\periperal with this one, if you want to use a different IDE.

    Let me know if anything is unclear, or if you have any questions regarding the PPI, or if you want to use the PWM driver instead of this.

    Best regards,

    Edvin

  • OK -  thanks.

    So, for completeness, is it possible to use the PWM peripheral to give a simple fixed duty cycle that will continue indefinitely?

  • So what's the difference between the nrf_pwm_sequence_t.repeats setting, and the playback_count parameter in nrfx_pwm_simple_playback() ?

  • If you look in the description of the sec_values, you see that the first bit will be the polarity of the PWM signal, as described in nrf_pwm.h, line 248 (in SDK15.0.0).

    What it doesn't tell you is how it sets the polarity - does 1 set active high, or active low?

  • I agree. That is also why I didn't specify which is which. But you can do this with a simple test. Set it to e.g. 1/10th of 0x7FFF ≈ 0x0800. Then check if the light is on for 1/10th, or off for 1/10th of the period. Testing this shows that with sec_value of 0x0800 the LED is on for a very short amount of time. Since the LED is ON when the pin is LOW, this means that if the msb is 0, then the PWM signal will go from low to high when 0x0800 ticks = 2048 ticks has passed. Then it stays high until the .top_value is reached.

    Note that you will see a similar behavior if you set the value to 0x8000 (=0b1000 0000 0000 0000) + 0x7FFF-0x0800 = 0xF7FF.

    This is because the signal will start high, and stay high until the value reaches 0xF7FF-0x8000 = 0x77FF ticks, and switch to LOW (LED ON) for the rest of the period, which is 0x8000 ticks.

    But to summarize:

    msb = 0, signal goes low to high on seq_values.

    msb = 1, signal goes high to low on seq_values.

    Best regards,

    Edvin

  • But you can do this with a simple test

    Sadly, there seems to be far too much of that with the Nordic parts.

    Documentation is supposed to tell us these things - not leave us puzzled and having to experiment & reverse-engineer it all!

    the signal will start high

    So what is the NRF_DRV_PWM_PIN_INVERTED flag supposed to do in the config.output_pins[] settings?

    I doesn't seem to make any difference ...

  • Now I see:

    • nrf_pwm_sequence_t.repeats sets the number of times to repeat each step within the sequence;
       
    • playback_count sets the number of times to repeat the entire sequence.

    Of course, with only a single step in the sequence, they both end up as the same effect!

    EDIT

    To further clarify, nrf_pwm_sequence_t.repeats is the number of repeats after the first iteration; ie,

    • repeats = 0 runs each step once;
    • repeats = 1 runs each step once, plus 1 repeat;
    • repeats = 2 runs each step once, plus 2 repeats;
    • repeats = n runs each step once, plus n repeats

Reply
  • Now I see:

    • nrf_pwm_sequence_t.repeats sets the number of times to repeat each step within the sequence;
       
    • playback_count sets the number of times to repeat the entire sequence.

    Of course, with only a single step in the sequence, they both end up as the same effect!

    EDIT

    To further clarify, nrf_pwm_sequence_t.repeats is the number of repeats after the first iteration; ie,

    • repeats = 0 runs each step once;
    • repeats = 1 runs each step once, plus 1 repeat;
    • repeats = 2 runs each step once, plus 2 repeats;
    • repeats = n runs each step once, plus n repeats

Children
No Data
Related