I'm building a high power lab psu with 100kHz H-bridge driving and I got stuck with the hardware PWM. I've successfully managed to get a single PWM signal or either a complementary after using some of the codes from the archive but I don't know how to make a constant phase delay between the 2 PWMs.
Could anybody please give me an idea how to extend the following code with another PWM signal that is aligned to the other signal?
void setup()
{
TCCR2A = 0x23; // fast PWM
TCCR2B = 0x09; // PWM timer2 16 MHz I/O clock
OCR2A = 79; // overflow value, 159 is 100 kHz
OCR2B = 1; // overflow value, 20 is 25% duty-cycle
pinMode(3, OUTPUT); // enable the PWM output (you now have a PWM signal on digital pin 3)
}
Thanks, but it appears to me the servo lib uses software PWM which is not good for this purpose. The minimum pulse width should be the lowest possible, which is 125ns with the 16MHz clock and the phase delay has to be absolutely stable. If not, then the FETs may open onto each other at 50% duty-cycle. That could be fatal here. The max output performance of this PSU is around 4kW which would mean a rapid meltdown.
I was planning to double the freq and implemement an external flip-flop with AND gates to split every second pulse and control the PWM through the AND gates but it's just an emergency solution. If there is a proper phase lock soultion I would prefer that.
What kind of signal do you need? I can't understand.. 125ns can be reproduces by software, with a timer interrupt,like the one you are using for PWM (ok, the PWM interrupt is handled by hardware)
If you need to "pause" the signal, you can increase the overflow value, and reduce the % (so you have the same high signal duration, only the low will change)
I made a simple diagram, please see the attachment. (I didn't know that it's handled by interrupts, hmm...)
If you need to "pause" the signal, you can increase the overflow value, and reduce the % (so you have the same high signal duration, only the low will change)
your signal is a PPM, but with servo you can simulate only one channel for pin.
the best thing to do is: launt a timer interrupt every X ms (where X is the minimum duration of the signal, and it have to be multiple of the total duration)
then, you can have an array struct, where every element is the duration and thge micros() time of the beginning of the last impulse.
then every interrupt, you look in this struct if you have to set the pin to HIGH or LOW.
with this method arduino has a precision of microsecons, 1000microseconds = 1millisecond
agentgates:
If you need to "pause" the signal, you can increase the overflow value, and reduce the % (so you have the same high signal duration, only the low will change)
Can you please clarify this?
it's a complication of the above method to use PWM. don't bother with it
The time resolution would be to high thus I can't control the output current on high range with high precision. There would be a lot of gitter and increased noise. I think I will stick to my original plan with the single PWM channel and external pulse separation.
Anyway, I appreciate your help, many thanks again.
you can chane the resolution varing the interrupt overflow and "listening" the interrupt on the timer overflow... or just use the servo libraries. Take a look at it, i think is a modded PWM to do PPM (exactly what you need)
Lesto
Servo library is software-based. This is what I referred to by the long time resolution problem. The software-based means it uses loop and direct port writing which is slow. You can't switch on and off directly a pulse with 125ns as the clock has many other things to do, e.g. reading values from arrays or flipping bits/flags/bytes, preparing the correct starting value for the next shot, doing a return from call, etc. You loose too many cycles in the meantime and therefore your time resolution will be too high. This is why I have to do it by hardware.
Coding Badly
Partially. Phase delay and dead-time. I posted a PDF above, that explains what I mean. The short time resolution is necessary for the fine current control.
you have to make 100%PWM == impulse duration, so you don't have to pause the signal (just write a 0% for always low signal)
but here again there is precision, 1% of PWM should be< of your needed precision, or you're out, and need or to use a 20MHz clak, or anoter faster micro.
Unfortunately, I don't get to look at attachments (nasty side-effect of being a moderator). If you provide it through another means, I will certainly take a look at it.
I have no idea but it very likely was not done deliberately. For some strange reason I cannot get past the captcha screen to create a normal user or I would just create a second account to access the attachments.
Ah, there we go. Can't use the same email address for both accounts.
Atmel refers to the two concepts as "inverted output" and "dead time generator". The ATtiny85 has hardware support for what you are trying to do. I suspect other ATtiny processors also have dead time generators with inverted output.
Thanks. I think I would stay with the ATmega168 as I also have a display attached to it and reads analog inputs as well, so I need the ports and I don't want to put another MCU in, especially because I don't have ATtiny at home right now.
I've been thinking about this in these days and I think I figured the theory how to solve it but I still don't understand the concept of the implementation. I would describe it and hopefully somebody could explain it to me what values to set to what.
The first PWM should capture the BOTTOM to turn on, and TCNT tells when to turn off on the rising edge and the other channel would turn on on the TOP and TCNT tells when to turn off on the falling edge. It would give exactly what I need. Prescaler sould run at 100kHz.