Arduino-FOC icon indicating copy to clipboard operation
Arduino-FOC copied to clipboard

Control Half Bridge/Full bridge for Synchronous Buck/Boost?

Open JohnGalt1717 opened this issue 4 years ago • 3 comments

It looks like this code is very close to what's needed in a nice library to be able to generate the complimentary PWM for a half or full bridge synchronous DC/DC Converter.

I.e. the BLDCDriver abstract class already has The ability to define the high and low pin for each side.

Basically it looks like

Question 1 regarding this: Have you considered creating a HalfBridgeDriver and a FullBridgeDriver? (and just allowing

Question 2: If not, could you give me some tips as to how I might do this myself? I'd be happy to do a pull request once I get it going.

JohnGalt1717 avatar Nov 05 '21 19:11 JohnGalt1717

Hi James,

We're really focused on motor control, but others have used the library for other purposes, for example to control LED dimming...

So I totally see where you're coming from, and agree that we provide some interesting "building blocks" for DC/DC conversion.

Question 1 regarding this: Have you considered creating a HalfBridgeDriver and a FullBridgeDriver? (and just allowing

This sentence is unfinished :-( not exactly sure what you meant to ask in the brackets...

But regarding your primary question: because we're a motor control library for 3-phase motors, we generally assume the user wants 3 half-bridges. But we also support steppers, so there is also code for 2 half-bridges. We don't support DC motors at the moment, so we don't have a full-bridge configuration at the moment, but hey, 2 half-bridges make a full bridge if you wire them up right :-) We support controlling the half bridges with either 1 or 2 inputs. The 1-input mode (3-PWM for BLDCs or 2-PWM for steppers) assumes you want to control both high and low side with one pin, as is common for many driver ICs. The 2-input mode (6-PWM for BLDCs or 4-PWM for steppers) assumes you need to switch the high and low side FETs individually, and supports dead-time insertion.

Question 2: If not, could you give me some tips as to how I might do this myself? I'd be happy to do a pull request once I get it going.

I think you could use the BLDC Driver code more or less directly for your purposes. The driver abstraction basically lets you set a duty cycle to the PWM output for each phase, by supplying a value between 0 and 1. There's some code in there to scale the output depending on voltage_limits, but if you set voltage_limit == power supply voltage you'll use the full scale. If you only need 1 half-bridge PWM output, you can just use 6-PWM and ignore the other two (set to 0), the driver won't care.

The driver supports many different MCU architectures, including Arduino Uno (AtMega), STM32, ESP32 and more. Depending on the MCU architecture you get slightly different features in terms of PWM frequencies settable, etc...

You could also take a look at the current sensing code - it isn't really finished, although some architectures are working with what we call "inline sensing" in motor control. But the hardware-specific code is basically setting up and using the analog inputs of the MCU - something I guess you'd need to track the output voltage on the feedback side of things, in order to adjust the PWM accordingly.

And finally we have some code for PID and low pass filtering which may or may not be useful... there's also the Commander, the Monitoring Code, and the SimpleFOC Studio (for visualizing output and controlling) - again, some of this could be useful for your purposes.

Don't know if this is helpful for you?

Let me play devil's advocate though and ask a question back: what would be the point of doing this? Even the smallest, cheapest of the MCUs we support would be considerably more expensive (and use far more PCB real-estate) than an inexpensive dedicated buck, boost or buck-boost IC... Is the aim to create a more sophisticated DC/DC converter than the normal ones available? Or is your aim to create a learning tool about DC/DC conversion?

In any case, an exciting idea, and we would love to hear where you take it!

Regards from Cape Verde,

Richard

runger1101001 avatar Nov 06 '21 00:11 runger1101001

@runger1101001 Thanks so much for this, it's a great place to get started!

The reason for doing this is that most of those ICs are in the 90ish % efficiency range (and a very narrow band around 50% duty cycle) even with good mosfets. With proper micro-controller logic you can get them up into the 98%+ efficiency range across a wide portion of the duty cycle.

Also, the vast majority of those ICs only support very low power (60V is the top of the line for most of them). This doesn't work when you're doing real Power work like MPPT, battery charging, and the new wave of 384VDC DC bus work, which is what I'm working on. In this scenario, when you're working with devices that have multiple DC buses, each at different frequencies (high (384VDC) / low (48VDC)), and are controlling MPPT in which requires dual buck/boosts the cost of the ICs to be able to handle 600VDC+ from a series solar string, even if they exist becomes prohibitive. And when you want to add more complex logic to what they're doing and where they're shunting power it gets even more complex than that. And when you're create a complete ecosystem of control units that need to talk to a central controller system because of many components including AC/DC grid tie, DC/AC transformer-less inverters, MPPT solar input, battery i/o and EV charging over CCS Type 2, all of which use at least one half-bridge to be efficient, it becomes highly desirable to use an STM32 or ESP32 for all of the integration and the ability to control this over IP and/or RS484. Especially when you're doing AI and talking to external Grid power providers for intelligent supply and charging... And then there is our heat pump compressor unit that is directly linked to everything else, and has to drive BLDC compressor, BLDC fan, respond to thermoresistors and control valves and the best solution to this problem for scaling and maintainability is a microcontroller that shares code as much as possible.

So yes, in theory I could do this without microcontrollers, but the reality is that because the half-bridge is just a side effect that is directly optimized by the rest of the system, I need a quick way to efficiently control the half-bridge with exacting accuracy in context of the overall system. Which really requires a microcontroller.

My concern with the suggestions above, is that the pins are going to be grabbed even though they're set to frequency of 0 and won't be accessible by a second, separate logic half-bridge. Is that a valid issue, or will it still allow a second half-bridge to be managed at the same time?

And yes, I'll absolutely have a separate pin that is monitoring voltage (and in the case of charging, amperage for CC/CV) that the PWM duty will be adjusted to match.

It would be awesome if there was a 2 pin version add to the code that was explicitly just high/low for this and several other more simple motor cases but this will definately get me started.

If you could give me a little direction, I could do a pull request to put this functionality in, and even enable the feedback loop for voltage and current as a separate module if that would be desirable. I'm happy to contribute back.

JohnGalt1717 avatar Nov 08 '21 18:11 JohnGalt1717

My concern with the suggestions above, is that the pins are going to be grabbed even though they're set to frequency of 0 and won't be accessible by a second, separate logic half-bridge. Is that a valid issue, or will it still allow a second half-bridge to be managed at the same time?

You are absolutely right about this - the pins get set up by the code to be associated to their timer, and you could not use the same pin with a separate instance of BLDCDriver. But at the driver level you can view the pins as being completely separate. Each half-bridge is controlled by a pin, and is electrically connected only via the motor - so if in your application you want to use them in some other, independent way, that is no problem. The BLDCDriver code won't care what values you set to each phase. However, all the pins will operate at the same PWM frequency - and depending on the MCU, it isn't so simple to run the pins at different frequencies... then it depends which timer they're connected to on the MCU - all this becomes quite hardware dependent.

If you could give me a little direction, I could do a pull request to put this functionality in, and even enable the feedback loop for voltage and current as a separate module if that would be desirable. I'm happy to contribute back.

Very happy to help with this if I can! Lets see where your project takes you, and if there is something you would like to contribute back to SimpleFOC we would be very happy!

runger1101001 avatar Nov 10 '21 11:11 runger1101001

Since this has been posted, we have introduced a 1-PWM driver for some of the MCU types we support, and more will follow soon. 1-PWM is intended for DC motor driving, or possibly also the type of use-case you describe above.

We've also started on a DC motor library (in a seperate repo in the simplefoc organization. This code includes drivers for full-bridges.

We've also made improvements to our current sensing code, that effort is still on-going.

I'm going to close this (very interesting) issue now, but do let us know if you have other questions, or if we can make improvements in the code-base that would help your use-case.

runger1101001 avatar Oct 30 '22 09:10 runger1101001

This is excellent! Do you have an example of setting up 2 PWM drivers that are in opposition with dead time? This is ultimately what is needed for a half bridge.

A full bridge is just a variation on a brushed DC motor controller as you describe that would be awesome to have a sample of:

In one mode (Boost), the top left of a full bridge is ON. Then the right 2 are PWMed in opposition with adjustable deadtime. In the other (Buck), the left 2 are in PWM in opposition with adjustable dead time and the top right is ON.

In both cases the inductor is where the DC motor would be in the circuit so it's very similar, but not quite the same. (and the half bridge example is the same as the full bridge, but it's 2 half bridges but either can be pwming and the other side is on.

If you could point me in the right direction on how I'd make this work, I'd be happy to contribute code for you that would make this a few lines.

JohnGalt1717 avatar Oct 30 '22 16:10 JohnGalt1717

The code is very new, and there aren't any examples really yet... I plan to work on that over the next few weeks...

But for the independent control of a full-bridges FETs I wrote the DCDriver4PWM class, which you can find here: https://github.com/simplefoc/Arduino-FOC-dcmotor/tree/main/src/drivers

I marked it "not ready for use" because I haven't implemented the dead-time yet...

It doesn't work in exactly the way you describe, as it PWMs only the top FET, and opens the opposite bottom one, but as you will see in the code that would be fairly trivial to change.

I think all of what you need could eventually be added to DCDriver4PWM, as I believe there are also applications in motor control to do with fast decay / slow decay when coasting and braking....

runger1101001 avatar Nov 04 '22 14:11 runger1101001

PS: and sorry for the slow response, I'm on vacation :-)

runger1101001 avatar Nov 04 '22 14:11 runger1101001

Excellent! Thanks! I'll take a look and see if I can contribute when/if I have any spare time. I'm not on vacation but the day job is all consuming right now.

JohnGalt1717 avatar Nov 04 '22 17:11 JohnGalt1717