Help Inverting PWM wave

For a timing circuit I need to invert one of 3 PWM waves I'm outputting. I have figured out how to get the waves to generate synchronously by my arduino due using its internal clocks, but I have to invert one of them ...

I thought a PNP transistor would do the job, but when the signal is brought up by the PWM wave the signal coming out of the transistor doesn't fall off immediately. I need it inverted, but it has to be a remain a clean square wave.

My question is what type of circuit do I need to cleanly do this?

I have attached a picture of my oscilloscope to show you my issue. Please any help would be much appreciated as I should be able to get my Linear CCD running after this.

Spent all day bashing my head against a wall wondering what wasn't working then noticed one of the waves was inverted .... this should fix my issue.

74AC04

Built an inverter/NOT-gate out of a PNP and NPN transistor and it inverts the signal well.

Trying to do it this with only hardware timers because I have to use ADC's at near their max sampling rate to work with the CCD as it requires a minimum sampling rate of 250 kS/s on the due.

Project is having to do a lot of bare bone stuff to get it to work unfortunately, but it's a learning experience.

ChaseRLewis73003:
Built an inverter/NOT-gate out of a PNP and NPN transistor and it inverts the signal well.

Does this mean your problem is solved?

Another good chip is 74F125 - just 3 to 5 nS of delay to switch High & Low.

Your PNP-NPN is similar to the outputs of logic devices that TI describes here, see figures 2-3-4.

Unfortunately, everyone seems to be trimming their data sheets, and typical input and output circuit is no longer shown.

TI does have some nice guides, like this Pocket Data Book that summarizes electrical function and electrical characteristics for a large number of logic families:
http://www.ti.com/lit/sl/scyd013b/scyd013b.pdf

By invert do you mean that instead of being 30% ON and 70% OFF it would be 30% OFF and 70% ON?

Because.... think.

KenF:
Does this mean your problem is solved?

Well not yet, it was late last night and called it a night shortly after I made the not gate. For some reason my NOT gate is lowering the voltage from 5V or 3.3V to around 1.5V so need to get it back up above 3V.

Been messing with it a bit and if I adjust the resistor value I get more voltage, but I expect the transistor has an internal resistance also that is causing some issue that is some function of current. Also if I lower the resistance value to low, below about 47 ohm. I stop getting a waveform altogether and the resistor gets VERY hot.

Here is my circuit and any help would be appreciated. Do I need a NPN transistor to step it up from 1.5V to 3.3 V or is there another way?

Not gate diagram (in my best chicken scratch) and current oscilloscope readings attached.

GoForSmoke:
By invert do you mean that instead of being 30% ON and 70% OFF it would be 30% OFF and 70% ON?

Because.... think.

Not sure how you would do this and maintain my timing alignments by setting the frequency/duty on the PWM pins. I am trying to do this without doing it in my loop() method as I am going to need to be doing a whole lot of processing and polling the ADC alot. Doing this is going to push the Due pretty hard and don't see the purpose in doing it in the loop if the due + some simple components will do it without wasting processing power that likely is going to be in short demand. Plus if I can take multiple samples per pixel rather then a single one then that will reduce the amount of time it takes to resolve each sample dramatically. Trying to build a spectrometer.

Resolving a sample is going to take ~1000 samples to get a decent reading because of noise so at 64 Hz That is ~15.65 s. Each additional pixel sampling per pass will reduce that. 15.65->7.813->3.906->1.953. I would like to get 2-3 samples per pass though theoretical limit with the due is 4. If the noise is on the collection end I can up my collections up to 256 Hz by adjusting my pwm frequencies and get it that way.

Wouldn't something like this work?

thing.JPG

KenF:
Wouldn't something like this work?

Perfect!!! Need to mess with the resistor values a tad bit because the up edge isn't perfect but it should be workable.

John Lincoln's post and that diagram make sense. Most of the arduino stuff I've done before is plug and chug, so this is my first real foray into building my own circuits and pcb's. It works like a charm and only uses 1 transistor instead of 2. CrossRoads mentioned an inverter which made sense and that circuit I built was one I found on the internet for making a NOT gate. Never done hardware based logic before, but his post made me to face palmed "Duh". Will keep in mind in the future resistor values control how quickly the signal falls off.

I have to head out, but I'll post up tomorrow if I get it working.

Also need to calibrate one of my oscilloscope probes because >.> yeah there aren't any 30V sources on the board only 1 of them read voltages correctly the other just gets the waveform right.

How do you synch the signals now? I'm guessing that there's a close enough to tolerate level?

I don't know about the DUE but default AVR PWM is about 490 Hz, over 2000 usec per cycle. So all you need to do is start that channel in time to synch the LOW to the other's HIGH, which can be done in setup in about 2 ms or less without building any circuit at all.

If all you really want is frequency then use digital hysteresis and debounce techniques to eliminate noise effects. 50 Hz is 20 millis per cycle. It wouldn't be a challenge to an AVR.

The Due has built in complimentary PWM - no external components needed. It can give you 16-bit duty cycle control, dead time control and much more.

I've done some register level programming and set up 4 PWM signals complete with their inverted signals.
You'll find them on pins P34, P35, P36, P37, P38, P39, P40, P41. The PWM frequency is 1.281 KHz.

It's easy to control these signals by changing appropriate values in this sketch (please refer to the datasheet for changing other PWM parameters).

//declare variables
unsigned short duty0 = 15000;
unsigned short duty1 = 30000;
unsigned short duty2 = 45000;
unsigned short duty3 = 60000;

void setup() {
  pwmc_setup();
}

void loop() {
  pwmc_duty(duty0, duty1, duty2, duty3);
}

void pwmc_setup()
{
  //Configure PWM channels 0,1,2,3 (PWML0,PWMH0,PWML1,PWMH1,PWML2,PWMH2,PWML3,PWMH3), (port C.2,C.3,C.4,C.5,C.6,C.7,C.8,C.9), (pins P34,P35,P36,P37,P38,P39,P40,P41)
  REG_PIOC_PDR = 0x3FC;  //B1111111100, PIO Disable Register
  REG_PIOC_ABSR = REG_PIOC_ABSR | 0x3FCu; //B1111111100, Peripheral AB Select Register
  REG_PMC_PCER1 = REG_PMC_PCER1 | 16; //Peripheral Clock Enable Register 1 (activate clock for PWM, id36, bit5 of PMC_PCSR1)
  REG_PWM_ENA = REG_PWM_SR | B1111; //PWM Enable Register | PWM Status Register (activate channels 0,1,2,3)

  REG_PWM_CMR0 = 0x10000; //Channe0 Mode Register: Dead Time Enable DTE=1
  REG_PWM_CMR1 = 0x10000; //Channe1 Mode Register: Dead Time Enable DTE=1
  REG_PWM_CMR2 = 0x10000; //Channe2 Mode Register: Dead Time Enable DTE=1
  REG_PWM_CMR3 = 0x10000; //Channe3 Mode Register: Dead Time Enable DTE=1

  REG_PWM_DT0 = 0xA800A8; //Channe0 Dead Time Register (168=2us for outputs PWML0,PWMH0)
  REG_PWM_DT1 = 0xA800A8; //Channe1 Dead Time Register (168=2us for outputs PWML1,PWMH1)
  REG_PWM_DT2 = 0xA800A8; //Channe2 Dead Time Register (168=2us for outputs PWML2,PWMH2)
  REG_PWM_DT3 = 0xA800A8; //Channe3 Dead Time Register (168=2us for outputs PWML3,PWMH3)

  REG_PWM_CPRD0 = 65535; //Channe0 Period Register (84mhz/65535=1.281khz=780.64us period)
  REG_PWM_CPRD1 = 65535; //Channe1 Period Register (84mhz/65535=1.281khz=780.64us period)
  REG_PWM_CPRD2 = 65535; //Channe2 Period Register (84mhz/65535=1.281khz=780.64us period)
  REG_PWM_CPRD3 = 65535; //Channe3 Period Register (84mhz/65535=1.281khz=780.64us period)
}

//Set the PWM duty-cycle
inline void pwmc_duty(unsigned short duty0, unsigned short duty1, unsigned short duty2, unsigned short duty3) {
  REG_PWM_CDTY0 = duty0;
  REG_PWM_CDTY1 = duty1;
  REG_PWM_CDTY2 = duty2;
  REG_PWM_CDTY3 = duty3;
}

dlloyd:
Due stuff

Awesome, I couldn't figure out how to do dead time control when reading around, I'll look deeper into the datasheet. I built a library for Due PWM frequency that works between 21 MHz and 0.05 Hz (technically more but that is the default settings of the clocks but the clocks are adjustable). I'll mess around with that code so I can add dead-time control to it and see if I can get it to work. I was using some helper functions inside Arduino.h, but guess I need to go a step lower-level then even that for even more control.

What header are those register parameters in you are writing to? Arduino.h?

Directly writing to the registers comes easy for me as I'm more familiar with FPGAs, VHDL and LabVIEW. However, I'm quite new with Ardiuno and C ... haven't yet written a library or even used interrupts in my code. I've looked under the hood and played around a bit and here's what I've found.

On my PC, I find PWM information in the following header files:

C:\Program Files\Arduino\hardware\arduino\sam\system\CMSIS\Device\ATMEL\sam3xa\include\sam3x8e.h

C:\Program Files\Arduino\hardware\arduino\sam\system\CMSIS\Device\ATMEL\sam3xa\include\component\component_pwm.h

Mostly all registers in the datasheet can be directly accessed in Arduino. To find information on any register name in the datasheet, I just search for the main part of the name less the REG_ part and channel number. For instance, if searching for deadtime and you have REG_PWM_DT0, just search for PWM_DT.

In the sketch provided, I've set deadtime to 168 of a 12-bit control range.
So for channel0, I used REG_PWM_DT0 = 0xA800A8;

Details for this 32bit register is found on page 1066. Here's how it maps out:

[size=0.8em]31 30 29 28 [color=blue]27 26 25 24 23 22 21 20 19 18 17 16[/color] 15 14 13 12 [color=blue]11 10  9  8  7  6  5  4  3  2  1  0[/color]
 X  X  X  X [color=blue]DTL[/color]                                  X  X  X  X [color=blue]DTH[/color]
            [color=blue]PWML0[/color]                                          [color=blue] PWMH0[/color]
            [color=blue]port C.2[/color]                                        [color=blue]port C.3[/color]
            [color=blue]pin 34[/color]                                          [color=blue]pin 35[/color][/size]

I think deadtime control is limited to the PWMH and PWML pins on the due. Some pins are used for other purposes may not be broken out from the IC ... check the pinout diagram.

A while back, I've created some pinout tables here:
http://forum.arduino.cc/index.php?topic=209034.0