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

Flicker LEDs to indicate full brightness

I am working on a project and have successfully implemented single channel PWM to dim leds (using a transistor FET). The pwm init code is below:

uint32_t err_code;
nrf_drv_pwm_config_t const config0 =
{
    .output_pins =
    {
        outputLED, // channel 0
        NRF_DRV_PWM_PIN_NOT_USED, // channel 1
        NRF_DRV_PWM_PIN_NOT_USED, // channel 2
        NRF_DRV_PWM_PIN_NOT_USED  // channel 3
    },
    .irq_priority = APP_IRQ_PRIORITY_LOW,
    .base_clock   = NRF_PWM_CLK_1MHz,
    .count_mode   = NRF_PWM_MODE_UP,
    .top_value    = mode8,
    .load_mode    = NRF_PWM_LOAD_COMMON,
    .step_mode    = NRF_PWM_STEP_AUTO
};
err_code = nrf_drv_pwm_init(&m_pwm0, &config0, NULL);
APP_ERROR_CHECK(err_code);

I then increment the PWM value when a button is pressed (up or down depending on the button). That function [ void update_pwm(int16_t duty_cycle) ] is below:

m_seq_values = duty_cycle;
pwmValue = duty_cycle;
nrf_drv_pwm_simple_playback(&m_pwm0, &m_seq, 1, 0);

I would like to flicker the lights (go from full brightness down to a dimmer setting back and forth with a delay between the different PWM settings) for a second or 2 when they are full brightness as a form of feedback to let the user know that the lights will not brighten any more. I did it successfully with the following code:

for (int k = 1; k <= 10; k = k + 1) 
{
	m_seq_values = mode6;
	nrf_drv_pwm_simple_playback(&m_pwm0, &m_seq, 1, 0);
	nrf_delay_ms(25);
	m_seq_values = mode8;
	nrf_drv_pwm_simple_playback(&m_pwm0, &m_seq, 1, 0);
	nrf_delay_ms(25);		
}
  update_pwm(pwmValue);

The problem is, I am using a timer that is driving a 2 digit 7 segment display. During the delay functions, the display stops on 1 digit because of the delay. Is there a better way to easily make these lights flicker without using a delay?

Parents
  • For completeness, I ended up using a timer to call the flicker code below.

    if (myData.powerState == 1)
    {
    	if (flickerNumber <= 11 && flickerNumber !=0)
    		{
    		if (pwmValue[myData.pwmIndex] >= 50)
    			{
    			if (flickerNumber % 2)
    				{
    				app_pwm_channel_duty_set(&PWM1, 0, pwmValue[(sizeof pwmValue / sizeof *pwmValue - 1)]);
    				}
    			else
    				{
    				app_pwm_channel_duty_set(&PWM1, 0, 35);
    				}
    			++flickerNumber;
    			}
    		if (pwmValue[myData.pwmIndex] < 50)
    			{
    			if (flickerNumber % 2)
    				{
    				app_pwm_channel_duty_set(&PWM1, 0, 0);
    				}
    			else
    				{
    				app_pwm_channel_duty_set(&PWM1, 0, pwmValue[myData.pwmIndex]);
    				}
    			++flickerNumber;
    			}
    
    		}
    	if (flickerNumber >= 12)
    	{
    		flickerNumber = 0;
    		if (outputLedState == false)
    		{
    			switchLedsOff();
    		}
    		else if (outputLedState == true)
    		{
    			switchLedsOn();
    		}
    	}
    }
    
Reply
  • For completeness, I ended up using a timer to call the flicker code below.

    if (myData.powerState == 1)
    {
    	if (flickerNumber <= 11 && flickerNumber !=0)
    		{
    		if (pwmValue[myData.pwmIndex] >= 50)
    			{
    			if (flickerNumber % 2)
    				{
    				app_pwm_channel_duty_set(&PWM1, 0, pwmValue[(sizeof pwmValue / sizeof *pwmValue - 1)]);
    				}
    			else
    				{
    				app_pwm_channel_duty_set(&PWM1, 0, 35);
    				}
    			++flickerNumber;
    			}
    		if (pwmValue[myData.pwmIndex] < 50)
    			{
    			if (flickerNumber % 2)
    				{
    				app_pwm_channel_duty_set(&PWM1, 0, 0);
    				}
    			else
    				{
    				app_pwm_channel_duty_set(&PWM1, 0, pwmValue[myData.pwmIndex]);
    				}
    			++flickerNumber;
    			}
    
    		}
    	if (flickerNumber >= 12)
    	{
    		flickerNumber = 0;
    		if (outputLedState == false)
    		{
    			switchLedsOff();
    		}
    		else if (outputLedState == true)
    		{
    			switchLedsOn();
    		}
    	}
    }
    
Children
Related