Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Arduino Pwm frequency

Status
Not open for further replies.

dr pepper

Well-Known Member
Most Helpful 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.
 
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.
 
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:
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:
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 :D
 
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.
 
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.
 
Julian Ilett did a YouTube video on the pwm.h library (latest version 0.5)

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.
 
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.
 
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.
 
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.
 
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.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top