How to configure Push-Pull PWM?

Hi,

I want to modify an old ATX power supply (I'm aware of the risks. I've worked with high tension before, and blown my fair share of components) to step down the voltage from a 400vdc solar array to charge a 12vdc lead acid battery. I plan on removing the control IC (494 or similar) and driving the power transistors with an arduino (via the preexisting amplifiers and signal transformer) but for this I'd need to use push-pull pwm.

Since both outputs need to use the same timer and be separated 180°, I guess I should use phase correct pwm and have one output turn on when the counter is at less than a "D" value, while the other turns on when the counter is at more than "full scale minus D", with D being less than halve the full scale to avoid shoot through.

What do you think, should I set this up on the arduino by itself or should I use a simple pwm signal and alternate the output with logic gates?

If code is the best answer, how do I set that type of pwm up?

I want to replace the TL494 IC with an arduino to implement an MPPT algorithm, smart charging and current limiting, all things I've done before but never with a push-pull configuration.

Thank you very much!
Best regards,
Willy

Most of the Arduinos that I know about do not have a very sophisticated waveform generator. I would not trust it with a dangerous high-power application like this.

Since both outputs need to use the same timer and be separated 180°, I guess I should use phase correct pwm and have one output turn on when the counter is at less than a "D" value, while the other turns on when the counter is at more than "full scale minus D", with D being less than halve the full scale to avoid shoot through.

What you are trying to explain in this paragraph is "dead time". I, personally, would not trust my own micromanagement with a high power system like this. Some microcontrollers have a "Dead Timer Generator" on one of their timer peripherals that will ensure that there is always dead time between a pair of outputs. I would absolutely get a chip that has at least that.

This limits your options though. The only AVR chips commonly used here that have a Dead Time Generator are the ATmega32U4 (used by the Leonardo) and the ATtiny85 (which only has 8 pins).

There are no built in Arduino functions that manipulate the Dead Time Generator though, so you will need to read the datasheet and learn how to set the register values yourself.

For a more upscale option with better features, there are also PWM series controllers within the megaAVR line, such as AT90PWM3B, that are made for the purpose of driving lighting, motors, or power converters. As you would expect from the name, these have the most sophisticated PWM peripherals, called the Power Stage Controller. I don't know if there are any cores made one of the PWM series though, so they might be the most difficult to play with.

I would recommend starting with a Leonardo and seeing if that's good enough for what you need. Although given this list of features for the Power Stage Controller, you might want to serious consider an AT90PWM.
screenshot.108.jpg

Is there a core for the PWM series?

The ATTiny861 also has a timer with a deadtime generator, and 15 usable IO pins. Supported by my core (though ofc it won't set up dead time generation for you), at GitHub - SpenceKonde/ATTinyCore: Arduino core for ATtiny 1634, 828, x313, x4, x41, x5, x61, x7 and x8

Hi,
Sorry, I forgot to mention that I plan on using an ATMega328. It's not the best option but I have a lot of them lying around since I needed a few and bought 15. On a second stage I'll check the PWM series, as I want to control pumps also. Thanks for the heads up!
The dead time control would be made by limiting the duty cycle of both outputs to less than about 45% by software. Not a good solution but enough for a quick and dirty one. I won't be sad if the ATX power supply gets fried, they are easy to get.
What I'd like to know is how to configure the pwm output of two pins which work on the same timer, to have them:

  • in phase correct PWM
  • one output turning on when the counter is below certain value
  • the other output turning on when the same counter is above certain other value

I'm sorry to ask it like this, but I haven't found any info of this on the site nor on the forum.
I will post the full code, schematics and pictures of the proyect.
Thank you @Jiggy-Ninja and @DrAzzy for your answers!
Regards,
Willy

I'm not sure if this is the waveform you want, but here are two pwm pulses 180 degrees out of phase with a small dead band between pulses.

//Timer1 Mode 10 PWM to ICR1
//Dual pin 200KHz PWM generator
//47.5% duty cycle 125ns dead band between pulses

void setup() {
  pinMode(9, OUTPUT); //output A
  pinMode(10, OUTPUT); //output B

  TCCR1A = 0; //clear timer registers
  TCCR1B = 0;
  TCNT1 = 0;

  //ICR1 and Prescaler sets frequency
  //no prescaler .0625 us per count @ 16Mh
  //80 counts x .0625 = 5 us = 200Khz

  TCCR1B |= _BV(CS10); //no prescaler
  ICR1 = 40;//PWM mode counts up and back down for 80 counts

  OCR1A = 21; //Pin 9 match
  //output A set rising/clear falling
  //Rise at TCNT 21 upslope, High 38 counts, Fall at TCNT 21 downslope
  //47,5% Duty Cycle Pulse centered on TCNT 40. High 38 Low 42
  TCCR1A |= _BV(COM1A1) | _BV(COM1A0); //output A set rising/clear falling

  OCR1B = 19; //Pin 10 match
  //output B clear rising/set falling
  //Fall at TCNT 19 upslope, Low 42, Rise at TCNT 19 downslope
  //47.5% Duty Cycle Pulse centered on TCNT 0. High 38 Low 42
  TCCR1A |= _BV(COM1B1); //output B clear rising/set falling

  TCCR1B |= _BV(WGM13); //PWM mode with ICR1 Mode 10
  TCCR1A |= _BV(WGM11); //WGM13:WGM10 set 1010

}

void loop() {}

That's Beautiful, thank you @cattledog!

To change the duty cycle I have to change OCR1A and OCR1B instead of using analogwrite, right?

Probably I'll increase the definition of the counter, as 200khz is on the high side for these old ATX's. I understand they work with frequencies between 50khz to 150khz.

To change the duty cycle I have to change OCR1A and OCR1B instead of using analogWrite, right?

Correct.

Thanks again! I'll start posting updates as soon as I start building the converter.

Are those images from a digital oscilloscope or some kind of an arduino simulator?

Are those images from a digital oscilloscope or some kind of an arduino simulator?

They were from a logic analyser Saleae Logic Pro 8 and posted by dlloyd in this thread

http://forum.arduino.cc/index.php?topic=438667.15

how change frequensy and dutycycle ? and phase sheft to 1180 degre