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.
2 Answers
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. 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; 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? 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. Mar 28, 2017 at 16:06