Instruction for invert a PWM signal

Good morning,

I'm doing a circuit for control an inverter frequency wit optocouplers, and it will be great for me get a signal that be the negative of a PWM output.

What I need is an output that gives 0V when PWM is 5V and 5V when PWM is 0V.

¿Anybody knows if there is any instruction for do it?

Thank you in advance

Why do you need a circuit (this is the Programming section, after all)?
Why not just analogWrite (pwmPin, 255 - val);?

Hi AWOL, thank you for your answer

I found I way for do this by hardware, but I'm not sure that I understand your solution.

If i'm not wrong, with your sentence I will get a PWM signal with value (255 - val), but ¿is it possible that 2 signals are high or low at the same time?. What I need is that this signal be HIGH when the other singal is LOW.

have a nice day!


Well if you do this:

analogWrite (pwmPinA, val);
analogWrite (pwmPinB, 255 - val);

When val is 0, PinA will be 0 and B will be 255. If val is 255, A is 255, and B will be 0.

A good way is to use the map() function:

invertval = map(val, 0, 255, 255, 0);

A good way is to use the map() function:

sp. “computationally expensive”

To do this you need to directly affect the relevant TCCR register for the PWM pair in question.

On the Uno and other 328 boards the PWM pairs are (5,6), (9,10) and (11,3) - for timers 0, 1 and 2 respectively. Assuming using timer1, pins 9, 10, then you can set the pins to opposite output sense thus:

TCCR1A = 0b10110000 | (TCCR1A & 0b00001111) ;

The top pairs of bits, 10 and 11 specify the output sense for pins 9 and 10, normally they are set to the same sense (10 and 10).

Then you simply ensure analogWrite to pins 9 and 10 is given the same value:

void setPwm (int val)
  analogWrite (9, val) ;
  analogWrite (10, val) ;
  TCCR1A = 0b10110000 | (TCCR1A & 0b00001111) ;

The solution of setting one analogWrite value to (255 - the other) will not work - it doesn't produce a complementary output, this method does.

There's one little caveat - if you call analogWrite with 0 or 255, analogWrite doesn't do the right thing, it calls digitalWrite instead, which will defeat this technique completely. If you want it to work whatever the value, then do this:

void setPwm (int val)
  OCR1A = val ;
  OCR1B = val ;
  TCCR1A = 0b10110000 | (TCCR1A & 0b00001111) ;

Thank you MarkT

This is the answer that I'm looking for.

Have a nice day!


If you just want one opto isolator to be off when the other is on, and vice versa, you can use the attached schematic. Drive the output pin marked Dn HIGH after initializing the PWM pin.

However, there is an issue with using opto isolators to drive transistors or mosfets in an inverter. Opto isolators take longer to turn off than they do to turn on. Depending on the configuration you use, this can lead to shoot-through.

The ATtiny25/45/85 provide complementary PWM outputs from timer 1, with programmable dead time between them - ideal for your application I think.