AnsweredAssumed Answered

PID loop for LED driver

Question asked by Ranjith Shanbhag on Oct 24, 2017
Latest reply on Oct 31, 2017 by jeremyzhou

i am working on LED 40W driver with Fly-back followed by Digital Buck topology.

Operating output Current - 300mA to 1050mA

Operating output Voltage- 28V to 54V

i am finding 100Hz ripple contents at the LED output.

Buck current ADC conversation triggered with PWM. Every 7.69uS ADC will be sampled and 8 sample average will be calculated. Further moving average calculation of 13 samples will be done using 8 samples averaged value.

PID sampling time: 200uS

PID processing time: ~50-60uS

Can any one help me how to remove the 100Hz contents at LED output?

I attached High level circuit diagram, output current waveform and PID code.

 

 

 

 

// Count that gives the minimum target current of 20mA.
#define MINIMUM_ALLOWED_TARGET_

CURRENT_COUNT    (54 * 13)

 

uint32_t PI_output_current(uint32_t set, uint32_t actual)
{
    static int32_t previous_error = 0;

    static int32_t error_accumulated = 0;
    int32_t integral = 0;
    int32_t output = 0;
    int32_t derivative;
    static uint32_t previous_set = 0;

 

 

    // Cap the target current to minimum allowable current.
    if (set < MINIMUM_ALLOWED_TARGET_CURRENT_COUNT)
    {
        set = MINIMUM_ALLOWED_TARGET_CURRENT_COUNT;
    }

 

    if(set > 0)
    {

        if(previous_set != set)
        {
            previous_set = set;
            error_ignore = set * error_ignore_percentage;      // calculate 5% of the set point. Ignore if the error is less than that.
            error_ignore = error_ignore / 100;
        }
        error = set - actual;
        if(abs(error) > error_ignore) // only if the error is not acceptable do PID
        {
            error_accumulated += error;
            integral = (error_accumulated * (ADC_PI_Sample_time / 2)) / 10;

 

            derivative = error - previous_error;
            derivative = (derivative / (ADC_PI_Sample_time / 2)) / 10;

 

            if(integral > integral_limit)
            {

                integral = integral_limit;
            }

 

            if(integral < (int32_t)(0 - integral_limit))
            {
                integral = (int32_t)(0 - integral_limit);
            }

 

            output = (((int32_t)(KP * error) / (int32_t)10000) +
                      ((int32_t)(KI * integral) / (int32_t)10000) +
                      ((int32_t)(KD * derivative) / (int32_t)10000));

 

            if(abs(output) > MAX_DIFFERENCE_OF_OUTPUT)
            {
                if(output > 0)
                {
                    output = MAX_DIFFERENCE_OF_OUTPUT;
                }
                else
                {
                    output = (0 - MAX_DIFFERENCE_OF_OUTPUT);

                }
            }
            if((output < 0) && (output_to_set < abs(output)))
            {
                output_to_set = 0;
            }
            else
            {
                output_to_set += output;
            }
        }
        previous_error = error;

    }
    else
    {
        output_to_set = 0;
        previous_error = 0;
        integral = 0;
        error_accumulated = 0;
    }

    return output_to_set;
}

Outcomes