PWM control

Hi ! I am new to arduino, so I hope someone can help me. I want to create a pwm with a constant frequency of 50 kHz, I want to control the duty cycle with a algorithm. Basically the duty cycle starts with 50 % and the algorithm decides to increase or decrease the duty cycle, this continues. How can I easily implement this ?

thank you ! /David

Trivial.

fm: Trivial.

Well, that didnt help...

There are several Arduino boards. Which one are you using?

[quote author=Coding Badly link=topic=117784.msg886459#msg886459 date=1344448915]

There are several Arduino boards. Which one are you using?

[/quote]

I am using a arduino UNO board, (think its an ATmega328)

Sorry, I don’t know why, I read if it was easy to do… ;(

Anyway, you will have to configure one of the PWM pins that the Arduino board has as an output. Then you will have to use analogWrite ( yourPWMPin, <value> ); // Where value is a numerical value that defines your duty cycle between 0 and 255, where 255 your duty cycle is 0 with the output high, and 0 your duty clycle is 0 with the output low.

On an Arduino UNO, the PWM pins are: 3, 5, 6, 9, 10 and 11.

The other thing that you will have to do is to modify/configure the timers used to generate the PWM and setup the frequency you want. This is a bit more tricky, but there are several places that you can find some code snippets that will help you:
http://arduino.cc/playground/Code/PwmFrequency
and
http://arduino.cc/playground/Main/TimerPWMCheatsheet

You will be limitted to the frequency range you can use though and the examples are based on the ATMega328p.

Thanks for the info, however I dont want to cause trouble in the delay function, since I am gonna use it. Other suggestions ?

"Other suggestions ?" Don't use Delay. Use blink-without-delay code design instead, monitor millis() and once enough 'time' has passed then do your intended action.

Like I said, I am new to this so forgive me if I ask some trivial questions...

Basically what I want to do is:

based on current and voltage measurements, change the duty cycle of the pwm signal.

could I just do it like this in the void loop ? :

timer1.intitialize (20) timer1.pwm (9,duty)

and then run through my if statement and then based on that change the duty ?

Only changing the pre-scaller of Timer 0, i.e. pin 5 and 6. Choose another pin. Mind you the frequency range will get you to 31KHz. If you are not concerned you will be able to use it.

I dont really follow you, I want to have a frequency above 40 kHz...

In such case, you will have to go for Timer 0. This is the timer that is used for the delay routines.

The base frequency for each timer is as follows: - The base frequency for pins 3, 9, 10, and 11 is 31250 Hz. - The base frequency for pins 5 and 6 is 62500 Hz.

If the delay routines are very important for your application and you need a frequency higher than 50KHz there are two options: 1. User timer 0 and scale your delays proportionally, for example instead of delay (100); you will have to do delay (800); 2. Use the timers to interrupt to synthesize the PWM, a SW PWM.

fm: In such case, you will have to go for Timer 0.

Or timer 1 or timer 2 can be reconfigured for Fast PWM.

I like this option 3.

I believe that there is a lot of confusion as to what the original author was trying to say.

According the the library TimerOne.h you can set certain pins to do whatever frequency you want (within capability of the board).

He is referring to this - http://playground.arduino.cc/Code/Timer1

using the coding from the website directly I had a lot of problems. You have to download the timer files, leave them in the zip and put them directly into the libraries folder, no subfolders, dont extract them. Once you are done doing this open up your sketch and import the libraries (ZIP FILE NEED TO BE IN THE LIBRARIES FOLDER) - I say all caps because I messed up several times and once I did this, everything worked perfectly. then… "#Include <TimerOne.h> which you type in or click “Sketch” and Import Library → click file and it will automatically add it.

Mine looks like this

#include <TimerOne.h>

void setup() {
// put your setup code here, to run once:
pinMode(9, OUTPUT);
Timer1.initialize(11230); // Intialize timer1, and set a 89hz frequency
Timer1.pwm(9,300); // setup pwm on pin 9, with a 50% duty cycle

}

void loop() {
// put your main code here, to run repeatedly:

}

** In my sketch it says 50% Duty cycle in the notes but right now its actually at something else i just didnt change the notes on it. It is using 10 bits so instead of 255 its like 1054 or something like that.

** Also
Figuring out HERTZ

  • go to: http://www.unitjuggler.com/convert-frequency-from-Hz-to-ms(p).html
  • Enter in desired hertz and it outputs how many milliseconds you need
  • take your milli seconds and conver them to microseconds by going to google and saying “convert milliseconds to microseconds” it will then give you a google calculator and does the calculations for you
  • Use these calculations in your sketch, for example mine says 11230 - that is the microseconds needed to create an 89hz frequency because herz is how many cycles per second the signal is 1000000(1 second in Microseconds) / 11230 = 89.04 hz

AND it works. My pin 9 is outputting an 89hz frequency.

I could not be more excited.

The the original Author, I hope you got it working… I dont know anything about creating advanced algorithms, but I hope this helps.

The arduino CAN make its own PWM frequency and is not limited like most of the posters have said. Using the Timer1 for Uno and Timer3 for Mega, you can unlock the PWM potential :slight_smile: Hope this helps someone.