I had hoped that I could set one channel to say 50% and the other at 48% to insure that they never will pulse at the same time. If this happens my mosfets will short and die quickly. I actually need a small period of time where both are off before firing the next.
I have it working ok bitbanging, but would much rather fire and forget to take care of other business.
I am using a Mega and should have plenty of options here, but I am stuck.
A good solution would be to go down to the chip level and use phase-correct PWM mode with complementary outputs. This is one of the supported timer modes, but you'll have to read the ATmega datasheet pretty carefully and do some experiments before committing to real MOSFET's.
See Section 16.9.4 of the ATmega1280 datasheet.
--
The Quick Shield: breakout all 28 pins to quick-connect terminals
You can go the hardware route this sheet has the circuit for a converter to generate two non overlapping clocks from a single clock input using two NAND gates and a few inverters. It's on page 5.
Please consider the timing involved: the gate capcitor (around 1nF) of one transistor is discharged while the other is charged. The time constant to consider is around 1k (?) * 1n = 1us. This delay is in the order of software operations...
The timer thing is making me crazy. It looks to me like I need phase correct PWM with the second output inverted. If I then run a slightly smaller duty cycle on the inverted channel, I will have a small deadband between pulses.
Am I on the right track? I found these settings on Ken Shirriffs blog to set phase correct pwm. I added the com2b1 bit to invert.
My scope won't let me see both at once in real time, but at the moment both pins just go high and stay there. I think I need another probe for the trigger. (actually I need a better scope)
Ok, I gave up on that method because it forces one pulse to be shorter than the other. I am on a new trail and for the life of me I can't figure out what is wrong.
Any ideas? -- edited to correct check of pin 43.
I know that the code at the moment should just turn off the pin that is set high at startup. As you can see I am trying different methods of bit manipulation.
It's a bit late for me to mention but I just noticed this while digging through the datasheet...
It looks like the ATtiny85 processor has exactly what you need. It supports an inverted PWM pin with "dead time". (plus a whole bunch of other PWM options)
Ok, Code that finally works! The logic in the ISR is actually improper for my purposes, but for some reason (I suspect the digitalWrite routine), the dead time between pulses does not match.
Look at the simple ISR logic, imagine the waveform you should get and then try it out.
#include <avr/interrupt.h>
#include <avr/io.h>
const int xformHV1 = 42; //;
const int xformHV2 = 43;
int state = 0;
int laststate = 0;
void setup()
{
pinMode(xformHV1, OUTPUT);
pinMode(xformHV2, OUTPUT);
//digitalWrite(xformHV1, HIGH);
delay(2);
TCCR5B = 0;
TCCR5B = _BV(WGM52); //timer5 CTC mode
TIMSK5 = _BV(OCIE5A); // Enable compare a match interrupt
sei(); // enable global interrupts
OCR5A = 9000; //sets CTC compare
TCCR5B = _BV(CS51) | _BV(CS50); //prescale of Fcpu/64
}
void loop()
{
}
ISR(TIMER5_COMPA_vect)
{
if(state == 0)
{
digitalWrite(xformHV1, HIGH); //digitalwrites waste time
laststate = 0;
state = 2;
return;
}
if(state == 1)
{
digitalWrite(xformHV2, HIGH);
laststate = 1;
state = 2;
return;
}
if(state == 2)
{
digitalWrite(xformHV1, LOW);
digitalWrite(xformHV2, LOW);
if(laststate == 0){
state = 1;
}
if(laststate == 1){
state = 0;
}
}
}