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

PWM Driver duty cycle

Hi,

   I'm using PWM driver DEMO5 to change the voltage of IOs.Now I need different voltage ranges.

Here is my code:

void demoPWM(void)
{
    /*
     * This demo, similarly to demo1, plays back a sequence with different
     * values for individual channels. Unlike demo 1, however, it does not use
     * an event handler. Therefore, the PWM peripheral does not use interrupts
     * and the CPU can stay in sleep mode.
     * The LEDs (1-4) blink separately. They are turned on for 125 ms each,
     * in counterclockwise order (looking at the board).
     */

    nrf_drv_pwm_config_t const config0 =
    {
        .output_pins =
        {
            CTRL1_PIN | NRF_DRV_PWM_PIN_INVERTED, // channel 0
            NRF_DRV_PWM_PIN_NOT_USED, // channel 1  RED_PIN
            NRF_DRV_PWM_PIN_NOT_USED, // channel 2
            NRF_DRV_PWM_PIN_NOT_USED  // channel 3
        },
        .irq_priority = APP_IRQ_PRIORITY_LOWEST,
        .base_clock   = NRF_PWM_CLK_125kHz,
        .count_mode   = NRF_PWM_MODE_UP,
        .top_value    = 625, //15625 -- 125ms     626 -- 5ms
        .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
        .step_mode    = NRF_PWM_STEP_AUTO
    };
    APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
    m_used |= USED_PWM(0);

    // This array cannot be allocated on stack (hence "static") and it must
    // be in RAM (hence no "const", though its content is not changed).
		static nrf_pwm_values_individual_t /*const*/ seq_values[] =
		{
			 0x1D5  //2.5v   0.75
		};
		static nrf_pwm_values_individual_t /*const*/ mid_values[] =
		{
			 0x155  //1.8v   0.54
		};
		static nrf_pwm_values_individual_t /*const*/ low_values[] =
		{
			 0xBC   //1.0v   0.33
		};
		
			nrf_pwm_sequence_t const seq =
			{
					.values.p_individual = seq_values,
					.length              = NRF_PWM_VALUES_LENGTH(seq_values),
					.repeats             = 0,
					.end_delay           = 0
			};
			nrf_pwm_sequence_t const mid_seq =
			{
					.values.p_individual = mid_values,
					.length              = NRF_PWM_VALUES_LENGTH(mid_values),
					.repeats             = 0,
					.end_delay           = 0
			};
			nrf_pwm_sequence_t const low_seq =
			{
					.values.p_individual = low_values,
					.length              = NRF_PWM_VALUES_LENGTH(low_values),
					.repeats             = 0,
					.end_delay           = 0
			};
		
		if(cycle == 2)
		{
			(void)nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);
		}else if(cycle == 4)
		{
			(void)nrf_drv_pwm_simple_playback(&m_pwm0, &mid_seq, 1, NRF_DRV_PWM_FLAG_LOOP);
		}else if(cycle == 6)
		{
			(void)nrf_drv_pwm_simple_playback(&m_pwm0, &low_seq, 1, NRF_DRV_PWM_FLAG_LOOP);
		}
}

The voltage will change when button is pushed,but the voltage is not accurate.Is there a better way?

BTW, I need the IO to output low after reached a certain voltage value.So I used  nrf_drv_pwm_uninit(&m_pwm0), but the IO output high.

The SDK is SDK14.2.

Parents
  • Hello,

    Thank you for your patience with this.

    The voltage will change when button is pushed,but the voltage is not accurate.Is there a better way?

    Could you please elaborate more on what behavior you are currently seeing?
    How are you measuring the voltages, and how is it currently behaving? What do you mean when you say that it is not accurate?
    The nRF52810 does not have a DAC module, so unfortunately there is no better way to synthesize lower voltages on an output.

    What will you use these modulated voltages levels for? Please keep in mind that PWM only toggles between VDD and GND, so while the average voltage of a PWM waveform can be changed, there is still only VDD and GND present on the pin - so you need to make sure that whatever is on the receiving end is ok with this.

    BTW, I need the IO to output low after reached a certain voltage value.So I used  nrf_drv_pwm_uninit(&m_pwm0), but the IO output high.

    You are using the NRF_DRV_PWM_PIN_INVERTED option when configuring your PWM pin. This will inverse its polarity, and set its idle state to high.

    Best regards,
    Karl

Reply
  • Hello,

    Thank you for your patience with this.

    The voltage will change when button is pushed,but the voltage is not accurate.Is there a better way?

    Could you please elaborate more on what behavior you are currently seeing?
    How are you measuring the voltages, and how is it currently behaving? What do you mean when you say that it is not accurate?
    The nRF52810 does not have a DAC module, so unfortunately there is no better way to synthesize lower voltages on an output.

    What will you use these modulated voltages levels for? Please keep in mind that PWM only toggles between VDD and GND, so while the average voltage of a PWM waveform can be changed, there is still only VDD and GND present on the pin - so you need to make sure that whatever is on the receiving end is ok with this.

    BTW, I need the IO to output low after reached a certain voltage value.So I used  nrf_drv_pwm_uninit(&m_pwm0), but the IO output high.

    You are using the NRF_DRV_PWM_PIN_INVERTED option when configuring your PWM pin. This will inverse its polarity, and set its idle state to high.

    Best regards,
    Karl

Children
Related