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

sometimes PWM signal is reversed .

Hi Nordics!

I am using app_pwm.c file in SDK 8.1, and when I use it with softdevice(advertising or data transfer event), sometimes pwm signal is reversed.

I guess, reversed signal's reason is the BLE interrupt. Because this problem is not occurred, when I don't use softdevice ( advertising or data transfer event)

And I need your advice for overcome this problem.

These are my development environment.


SDK 8.1

SD 8.0

nRF51822 AA G0

custom board

Timer1- 2channels

Timer2-1 channel.

3 PWM channels - Red led, Green led, Blue led.


first, I used app_pwm library. (100Hz )

/* */

static void pwm_init(void)

{

    ret_code_t err_code;
    
    /* 2-channel PWM, 100Hz, output on LED pins. */
    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(10000L, GPIO_LED_RED, GPIO_LED_GREEN);
    app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_1CH(10000L, GPIO_LED_BLUE);
    
    /* Set the polarity of the channel. */
    pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
    pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
    pwm2_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
        
    /* Initialize and enable PWM. */
    err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_1_ready_callback);
    APP_ERROR_CHECK(err_code);
    err_code = app_pwm_init(&PWM2,&pwm2_cfg,pwm_2_ready_callback);
    APP_ERROR_CHECK(err_code);
    
    app_pwm_enable(&PWM1);
    app_pwm_enable(&PWM2);
}



void pwm_1_ready_callback(uint32_t pwm_id)   

{
    pwm_1_ready_flag = true;
}

void pwm_2_ready_callback(uint32_t pwm_id)   
{
    pwm_2_ready_flag = true;
}





second, I set the pwm chanel duty by using below code. 

(in this function, I didn't wait callback. I just keep trying until PWM is ready)

static void color_setting(uint8_t red, uint8_t green, uint8_t blue)
{
    
    color_red=red;
    color_green=green;
    color_blue=blue;
    
    pwm_1_ready_flag = false;
    pwm_2_ready_flag = false;
    
    /* Set the duty cycle - keep trying until PWM is ready... */    
    while (app_pwm_channel_duty_set(&PWM1, 0, (uint32_t)(sin_table[color_red]/2.55)) == NRF_ERROR_BUSY);
    while (app_pwm_channel_duty_set(&PWM1, 1, (uint32_t)(sin_table[color_green]/2.55)) == NRF_ERROR_BUSY);
    while (app_pwm_channel_duty_set(&PWM2, 0, (uint32_t)(sin_table[color_blue]/2.55)) == NRF_ERROR_BUSY);

    /* ... or wait for callback. */
   //    while(!pwm_1_ready_flag);


}

sin_table's value is from 0 to 255. so I divided it by 2.55

And this color_setting function is called in app_timer call_back function.

my app timer's interval is 40ms.

In other words, PWM values is changed in every 40ms, and it repeat 0~100 value.

This "PWM signal reversed" issue is not appeared, when I don't use softDevice.

Is there any idea for avoiding this problem??

This problem is critical issue on my project.

Please help me.

Thanks.

  • New software included. Waiting any feedback. I hope the problem would be solved for good - no error detected during tests on our side.

  • I have been testing the updated PWM library in my code and it is better, but I still get frequent 'glitches' when updating the PWM signal. If I have the period set to 64us I have glitches, if I set the period to 128us then it runs fine. I however have not ruled out that there might be some error in my code that is causing these glitches. Certainly the work you have done to improve the PWM library has helped. It has reduced these glitches in general, but I am still having some. My hunch is it could be the frequency and method I am using to set the duty cycle on the PWMs? I am using two PWM instances, each with one channel. Do you have any best practices for setting channels on two instances?

  • What do you mean by "glitches"? If it is possible - please include some waveforms. Is the signal inverting? On what channel this "glitches" can be seen? How often it happens? The method you use to update the PWM seems OK.

  • Ok, so I ran the signal through an logic analyzer to see exactly what is happening. And the 'glitches' I described before are in fact the PWM polarity reversing. It is actually reversing back and forth several times in a row, sometimes like 50 times in a row. I made a few observations: 1. The signal reverses at a predicable timing. When a pattern of reversal starts it happens every 10ms on the dot. I am updating the PWM duty every 10ms, so that timing seems to align. For example: I have one recording where the flipping started at 1s 354ms into the recording, at 364ms it would reverse polarity, at 374ms reverse again, and like that for 40 times and then it was fine. During that pattern the duty value is just gradually changing from ~6% to 11%, so no big changes (besides the polarity). 2. The problem doesn't seem to correspond to the set duty, I've seen it at 33% 6%, etc.

    1. Sometimes it flips once. Sometimes 100 times in a row. But always at that 10ms interval, so it is easy to see on the signal trace. In case you have access to Saleae Logic, here is adropbox link to a logic file with the recorded signal, the flipping is right at the beginning. Logic File
Related