Boostconverters Current Control


garden electronics LED 3d soldering

Motivation #

The current electrical setup for the garden LED lights has DC to DC voltage boost converters. I always wanted to add brightness control, which is why I initially switched to those converters instead of connecting the LEDs directly to the 12v PSU at full brightness.

That solution did allow for controlling the brightness, namely by using a screwdriver to turn a potentiometer which would increase or decrease the output voltage (when the boost converter is in CV mode).

Problem is, I’m not always sitting next to it and want to control the brightness in some automated way. This would for example allow making a sunrise and sunset effect every day when the lights turn on or off. Also it’s an interesting electronics project, for learning.

general simplified overview

Here, the DC-DC boost converters determine brightness by their output voltage: lower voltages for low brightness, as low as 35V. For higher brightness, higher voltage. The LEDs should be albe to handle 60V but that would heat up too much, so I set an upper limit of 50V and they usually operate at 45V.

Previous approach #

I spent the previous month trying to produce a reference voltage in various ways, to override the potentiometer, and conceptually just send some microcontroller a “set brightness to X%” message.

To put that exploration in a short sentence: it didn’t produce good enough control. The setup would be slightly flickering, it couldn’t reach the low brightness range without sacrificing the top end of the range, and it had some safety problems: when the microcontroller is disconnected or powered off, the boost converter could damage itself or produce voltages at unexpected places.

The CC potentiometer #

This is why I decided to explore modifying the CC potentiometer instead. The CC potentiometer is a second setting on the boost converter, used to set a Constant Current upper limit. The boost converter has been previously working in Constant Voltage mode, but I now try to control the brightness of the LEDs connected to it by lowering the maximal allowed current, instead of the maximal voltage (which will still be set by screwdriver as the absolute allowable max).

It turned out that this potentiometer sets a very low voltage: the control pin has between 1mV and 60mV while the current limit goes from 400mA to 6A.

This does pose a challenge because the arduino does not have a high milivolt-level resolution, so using an analog output voltage directly gives very little resolution of control.

Arduino analog output voltage #

To make an analog output voltage channel, use a digital PWM output (D_OUT) and low-pass filter it (resistor and capacitor like in the diagram). To make an even more stable voltage, build a feedback loop! Connect the analog output (A_FDB) to an analog input for measuring it. The idea is to slightly speed up when the measured voltage is slightly too low, and slow down if it’s too high.

circuit diagram analog output

What to do with A_IN measurement ? #

Implement a PID controller. Basically, we slow down the pulsing when the analog output voltage measures too high compared to the set-target, and speed up pulsing when too low. No need for a full PID though (but for learning effect, yes): just a P controller or even a stepped P controller is good enough to get a voltage controlled by a microcontroller, that can later be set by messages to it.

// full PID simple example
double K_P,K_D,K_I;
int target=300;
int prev_err=0;
int tot_err=0;
int cycles;

void loop() {
    int measured=analogRead(A_IN);
    int err=target-measured;
    tot_err+=err;
    int delta_err=err-prev_err;
    // proportional term + derivative term + integral term
    cycles=round(K_P*err+K_D*delta_err+K_I*tot_err);
    prev_err=err;

    cycles=min(199,cycles);
    digitalWrite(D_1,HIGH);

    for (int i=0;i>200;i++) {
        if (i==cycles) {
            digitalWrite(D_1,LOW);
        }
        delayMicroseconds(1);
    }
}

Note: increase the 200 cycles for a higher resolution.

Its actuation range is about as much as the digital output PWM can do: from 0V to ~4.5V.

There are some losses from the 5V supply, and around 0V the resolution is also not completely linear; for a more in depth comparison, see here.

Resistor Divider #

Now we have an analog output voltage in the range 0V to ~5V. But we need a range up to about 20mV. The problem of having a too high analog voltage is solvable with just a resistor divider, as long as a few conditions are met:

The principle is that we make a chain of resistors between the input voltage and ground. Then at any junction point, there will be a voltage in the range from input to 0V. The simplest case is built with two resistors:

circuit diagram resistor divider

Practical solution #

For a pragmatic solution I knew I don’t yet know the exact divider ratio I need anyways. So I make it adjustable: the 5K resistor is a potentiometer that can be adjusted from ~0 Ohm to ~ 5KOhm.

Putting it all together #

The current solution enables precise control over a milivolt-level analog voltage from the microcontroller:

circuit diagram with potentiometer

This works well and can control the boost converter’s CC limit between 470mA and 2.5A output!

There’s certainly progress, but one last thing still bugs me: this lowest reachable limit of 470mA is quite high. After a short test, the boost converter can also lower the CC limit below 470mA, but only when a small negative voltage is applied to the potentiometer pin. So the next step is: How do we make negative milivolts?

Negative voltage #

To make a negative voltage I use an inverting charge pump. It’s a way to generate a low-power negative voltage using two capacitors and two diodes.

The negative output V- will be two diode drops closer to GND than in the ideal case, but that was good enough. After some experimentation, I found that an easy way to generate a stable negative voltage (though it’s not very powerful) is to use the arduino’s analogWrite(pin=D2,128) function which sends a PWM signal and sets it to 50% duty cycle.

circuit diagram inverting charge pump

The smaller capacitor is charged up while D2 is high. When D2 switches to low while the 10uF is full, its voltage will be blocked by one diode and allowed through by the lower diode, thus charging the bigger capacitor.

The negative voltage is produced when the 10uF is “shifted down” by D2 going low: the diode towards GND will block its voltage from discharging and because its positive leg is pushed to 0V by D2, the negative leg must have an even lower voltage (-4.4V if we assume D2 is 5V at high and a 0.6V diode drop).

The job of the second capacitor is mostly to smooth the voltage out over time.

Some more resistor dividers #

The main challenge is to “dim” the voltage up and down precisely. I tried varying the D2 PWM to “dim” the V- negative voltage, but it wouldn’t be very stable, or linear.

Instead, we make a resistor divider between the negative voltage (constant) and the analog V_OUT (variable) as the high point: that allows us to finely control the voltage, and with correct tuning of the potentiometer R5, also to reach negative voltages on the low end of the range.

circuit diagram invert and potentiometer

This works because A_FDB can be set by the microcontroller to be between 0V and 5V. As an example with a 2:1 resistor divider, where we set the potentiometer to 3.4K:

If the potentiometer is instead set at 1:5, or 1.36K:

Adding the R5 potentiometer instead of a fixed resistor allows to tune the range of actuation!

I drew two connections with dotted lines: they are the connector between the arduino and the boost converter. The singal there is moved over up to 50cm of wire. On the boost converter, there is a second potentiometer (R3) as well, for tuning the width in milivolts of A_OUT’s range.

Experimentally, I found that R3 can set the maximum actuatable constant current. To calibrate it, simply tell the microcontroller to make the highest possible A_FDB, and then turn R3 lower or higher until the boost converter reaches the desired max current consumption.

Amplification #

The above circuit doesn’t work well, because the load put on it by an active boost converter is too high. The signal on A_OUT is quite low impedance, and the boost converter will just pull it to GND. This is in part because of the 22 Ohm resistor, and the boost converter internally as well.

To solve this problem, I added an operational amplifier (opamp) after a helpful suggestion. It’s set up as a unity gain amplifier, also called a voltage follower. The main point is that the opamp gets a negative feedback from its output, and will match the output to be equal to the + input.

In this context, the opamp is used to increase the impedance of the generated voltage so that it controls the boost converter instead of being controlled by the boost converter.

circuit diagram with opamp

Conclusion #

3d soldering of the above diagram, two channels

3D soldering with the arduino. That's two channels of the above diagram

This is quite a fun project, and I’m still not completely happy about it. The last circuit diagram has too much complexity and I think I can still simplify it.