# 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;
}