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.
-
3There's a ton of examples in the web. Google doesn't bite, use it.Jakub Rakus– Jakub Rakus2017-03-28 06:16:42 +00:00Commented Mar 28, 2017 at 6:16
-
1This is a arduino user level question, nothing about electrical engineering.Olin Lathrop– Olin Lathrop2017-03-28 11:30:24 +00:00Commented Mar 28, 2017 at 11:30
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.Parikshit Deshmukh– Parikshit Deshmukh2017-03-30 06:24:34 +00:00Commented 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;Parikshit Deshmukh– Parikshit Deshmukh2017-03-28 15:41:45 +00:00Commented 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?Parikshit Deshmukh– Parikshit Deshmukh2017-03-28 15:57:20 +00:00Commented 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.Dmitry Grigoryev– Dmitry Grigoryev2017-03-28 16:06:24 +00:00Commented Mar 28, 2017 at 16:06