How to obtain four PWM outputs at 100 kHz using an arduino uno board? The requirement is that all four PWM outputs should have controllable duty ratios individually.

  • 3
    There's a ton of examples in the web. Google doesn't bite, use it.
    – Jakub Rakus
    Commented Mar 28, 2017 at 6:16
  • 1
    This is a arduino user level question, nothing about electrical engineering.
    – Olin Lathrop
    Commented Mar 28, 2017 at 11:30

2 Answers 2


In a comment to Dmitry Grigoryev’s answer you wrote:

void setup()
    TCCR2A = 0x23;
    TCCR2B = 0x09;
    OCR2A = 159;
    pinMode(3, OUTPUT);

void loop()
    OCR2B = 80;

It seems you already have the solution to your problem: that's exactly the way to do it!

Well, there is a catch: since you are using OCR2A to define the period of your timer, this means you are left with a single PWM channel, where the duty cycle is controlled by OCR2B. Given that the Arduino Uno has only three timers, it would seem you can only have up to three PWM channels at 100 kHz.

But there is a solution. Timer 1 has a feature the other timers don't have: you can define its period using using the input capture register ICR1 instead of OCR1A. This leaves you both output compare registers available for PWM. For this you have to set the timer into waveform generation mode 14, i.e. fast PWM with TOP = ICR1. Now you can have your four channels, with Timer 0 driving pin 5, Timer 2 driving pin 3, and Timer 1 driving pins 9 and 10.

Some caveats:

  • As already pointed out by Dmitry Grigoryev, your PWM resolution is slightly reduced.

  • By reconfiguring Timer 0, you loose the Arduino Timekeeping function millis(), micros() and, delay(). You could write your own ISR to count the overflows of some other timer, but it would be called every 10 µs: even if it is very short it would eat a non-trivial fraction of your CPU power.

  • Great answer. Thanks for the help. I'm trying to implement as you mentioned. I'll get back to you with some results. Commented Mar 30, 2017 at 6:24

You can't squeeze 100kHz out of an Arduino without a major software rewrite (at which point you will be using an AtMega chip rather than Arduino). analogWrite defaults to ~500Hz and can be boosted to 62.5kHz on some Arduino models, and only for 2 pins. Other PWM pins are capped at 31.4kHz.

You can achieve 100kHz PWM by toggling pins manually and busy-waiting, but you won't be able to do anything else during this. Or you can make use of interrupts, which is a big leap from Arduino ecosystem as I already said.

  • setup() {TCCR2A = 0x23; TCCR2B = 0x09; OCR2A = 159; pinMode(3, OUTPUT); } loop() { OCR2B = 80; Commented Mar 28, 2017 at 15:41
  • I used the following code to generate 100 khz pwm signal- setup() { TCCR2A = 0x23; TCCR2B = 0x09; OCR2A = 159; pinMode(3, OUTPUT); } loop() { OCR2B = 80; I have to drive 4 MOSFET's simultaneously for my project to achieve multiple O/P dc-dc converter. Probably an arduino Mega would work? Commented Mar 28, 2017 at 15:57
  • @ParikshitDeshmukh You're sacrificing resolution for speed here. You get your 100 kHz, but only 160 distinct PWM duty cycles instead of 256. Commented Mar 28, 2017 at 16:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.