# Arduino Pwm frequency

#### dr pepper

##### Well-Known Member
Before I go down this route I'll pose this question.
Would an arduino uno Pwm o/p be configurable to o/p exactly (assuming the 16mc xtal is spot on) 200 khz.

#### Pommie

##### Well-Known Member
The normal PWM output is about 400Hz!!!. There is a fast PWM library but I'm not sure how fast. Best thing is to look at the micros datasheet to ascertain the speed of PWM available and the resolution.

Mike.

#### Nigel Goodwin

##### Super Moderator
Before I go down this route I'll pose this question.
Would an arduino uno Pwm o/p be configurable to o/p exactly (assuming the 16mc xtal is spot on) 200 khz.
The standard PWM is under 1000Hz - you can increase it by altering the timer settings (but this messes up the standard delay routines) - however, it doesn't go that high (I think about 32KHz or so). If you google Arduino buck converter there are numerous examples.

The reason I know, is I've been playing with a PIC version, and using a 12F1840 with internal clock of 32MHz, using 8 bit PWM you can get 125KHz out of it. Using 10 bit PWM drops to 32KHz or so, but the Arduino is only 8 bit pwm anyway.

Last edited:

#### dr pepper

##### Well-Known Member
So it doesnt look like it.
Might look at the Attiny, I remember one of those can go very high.
I want a 200khz 50% fixed waveform thats derived from the system clock.

Edit: Some of you guys will have a problem believing this, I installed Pwm.h from github, changed the pwm freq to 200,000, set the duty to 127, connected my fluke scopemeter, and it says I have 200 khz, nope I havent got hz & khz mixed up, the period is indeed 5uS.
No idea whats going on, but I'm gonna use it as the start of my project.
Maybe its not using the prescaler or something.

Last edited:

#### Nigel Goodwin

##### Super Moderator
So it doesnt look like it.
Might look at the Attiny, I remember one of those can go very high.
I want a 200khz 50% fixed waveform thats derived from the system clock.

Edit: Some of you guys will have a problem believing this, I installed Pwm.h from github, changed the pwm freq to 200,000, set the duty to 127, connected my fluke scopemeter, and it says I have 200 khz, nope I havent got hz & khz mixed up, the period is indeed 5uS.
No idea whats going on, but I'm gonna use it as the start of my project.
Maybe its not using the prescaler or something.
Perhaps the buck/boost examples I've seen didn't want the frequency that high?, I just presumed it was turned up as fast as they could. The speed was increased by changing some registers. This is an example, actually for an ATTiny

void setup() {
TCCR0A = 2 << COM0A0 | 2 << COM0B0 | 3 << WGM00;
TCCR0B = 0 << WGM02 | 1 << CS00;
TCCR1 = 0 << PWM1A | 0 << COM1A0 | 1 << CS10;
GTCCR = 1 << PWM1B | 2 << COM1B0;
pinMode(pwm, OUTPUT);
pinMode(potinput, INPUT);
pinMode(feedbackinput, INPUT);
digitalWrite(pwm, LOW);
pwmval = 0;
}
I've no idea what the registers are

#### dr pepper

##### Well-Known Member
I have an idea, but thats about it.
I reckon the lib tests the frequency you state, then sets certain registers accordingly, I havent tried it but I bet if I put 201 khz it probably wouldnt work.

Edit: I was right, kinda I just tried 201 khz, and I got 205.1 khz, so the lib must setup the timers to give you the nearest, certain integer divisions of the clock must work & others not depending on the prescale & scale registers.

#### wkrug

##### Active Member
I want a 200khz 50% fixed waveform thats derived from the system clock.
I guess that will work.
You'll take a "normal" PWM mode that switches on comparematch.
The comparematch register should be set to 39 ( or 0x27 ).
You should use the CTC Mode of the timer.
Function:
When the timer achieves the comparematch value the output toggles.
The Timer would be set to 0 ( CTC ).
When TCNT counts up to 40 again the output toggles into the other state.

Code snippet:
Code:
/ Port D initialization
// Function: Bit7=In Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (1<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=0 Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
// Mode: CTC top=OCR0A
// OC0A output: Toggle on compare match
// OC0B output: Disconnected
// Timer Period: 2,5 us
// Output Pulse(s):
// OC0A Period: 5,00 us Width: 2,5 us
TCCR0A=(0<<COM0A1) | (1<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0x27;
OCR0B=0x00;
In Simulator it works perfect!

That all works without any load of the controller core.

#### SPDCHK

##### Member

I use this library for my PID control with PWM. The only problem is you can only configure one frequency. For example, configure Timer1 PWM pins frequency with Uno pins 9 & 10. I wanted to configure Timer2 pins as well, but that did not work so well for me.

#### dr pepper

##### Well-Known Member
A proper explanation, thanks for that.
So does the task use processor time, the code I did sets it up then runs a while(1), so it doesnt use runtime, so if its attended to by the processor it must do it with interrupts.
The code I use doesnt mess up delay() or other core functions, but I have not tested that.
And I need to output another frequency as well as count a third.
Rethinking I might use something like a Si5351 dds that can generate 3 freq's from one xtal, controlled by a processor, and commit one of its 3 o/p's to be fed back to the processor for sync.

#### gophert

##### Well-Known Member
The ESP32 can me programmed with Arduino IDE has PWM but uses an LEDcWrite command (and a few lines of setup) instead of analogWrite. That way, everything in the Arduino standard timing code delays and other still works. The LEDcWrite was poorly named but can be used for any PWM application.

The chip is very fast and can handle 12-bit PWM resolution up to, I think, 1/8 of clock speed.

#### dr pepper

##### Well-Known Member
Yes I'm familiar with the Esp32 its a cool chip.
But I'mnot so sure about the web server that comes with the core.

#### gophert

##### Well-Known Member
Yes I'm familiar with the Esp32 its a cool chip.
But I'mnot so sure about the web server that comes with the core.
You can completely ignore the web functions if you want. Just don't use the commands needed to turn it on. You'll have access to all ADC pins if you leave it off.

Also, if you elect to use wifi, it is a multi core device and one core runs the wifi so no issue with priorities or other performance. I bought a stack of them and use them for everything lately.