Arduino Uno - Changing PWM frequency out of audible frequency

Hi to All,
I am finally testing a new machine which has a viper motor 12 Vdc driven by Arduino Uno which generate the PWM to drive a power shield.
The power shield I am using is this one: http://openmicros.org/index.php/articles/257-pwmmosfet-shield-document-index.
Obviously I am using external power at 12 volts to feed the power shield.

I simply adjust the PWM by a custom window application which I have coded but this is not the problem.
I am experiencing that the motor is making a hell of a noise due to the default PWM frequency around 500 Hz when I control the speed which is approx. at 170/255.

I would like to increase the Arduino PWM frequency out of the audible frequency, lets say 62.5 kHz.
I am working with pin 5 and pin 6, which are associated to the same timer (Timer 0), pin 6 is not used so I don't care about it.

To increase the PWM frequency of pin 5 and 6, would it be enough if I add this line of code to the Arduino setup?

TCCR0B = TCCR0B & 0b11111000 | 0x01;

Do you think the mosfet/power shield will be able to run at such frequency?

I would appreciate your comments.
Thank you,
Felice

You may find that the higher frequency is too much for the motor. Motors are inductive and an inductor resists the rate of change of current in a circuit, so at high frequencies it might not get enough current through it to move.

Hi,
thanks for your comment.
Actually I did some experiment and I noted that higher is the frequency of the PWM and less control I have on the motor.
At 62 kHz I can control the motor only between 10 and 12 V
At 32 kHz I can control the motor only between 8,2 and 12 V
and so on.
Also the Mosfet on the power shield became hotter with high frequency. I have installed a small fan on them and should be fine now.

Actually I think that the right balance between noise, heat and control would be to have the PWM at 10 kHz but looking at the tables here Arduino Playground - TimerPWMCheatsheet, I don't think is possible.

Any suggestion about how to set the PWM at 10 kHz?

You don't actually have to use analogWrite() to produce PWM. You could 'roll your own' PWM function and set the frequency to anything you want by toggling a digital pin. More work, of course.

UKHeliBob:
You don't actually have to use analogWrite() to produce PWM. You could 'roll your own' PWM function and set the frequency to anything you want by toggling a digital pin. More work, of course.

http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

Thanks, actually I visited that page before posting but I have not understood how to manage the code to get 10 kHz PWM.
Could you help with some line of code example?

Hi,
@ UHEliBob, actually I have checked which are the frequencies I can set and it looks to me that is not correct to say "you could 'roll your own' PWM function and set the frequency to anything you want by toggling a digital pin".
The frequency settable are as per attached excel sheet.

Arduino PWM sets.xlsx (69.7 KB)

I cannot open that file so cannot see the contents. If I have got your hopes up and you cannot do what you want I apologise.

felicemassaro:
I am experiencing that the motor is making a hell of a noise due to the default PWM frequency around 500 Hz when I control the speed which is approx. at 170/255.

Have you tried putting a 0.5uF ceramic capacitor across the motor terminals?

What is the source of the spreadsheet?

My reading of the AVR328 datasheet suggests (but no more than that) that you can use Timer1 in a very flexible manner to produce PWMs at very high frequency.

...R

Hi,

@UKHeliBob, sorry was not my intention to be rude. There is no need to apologize. :wink:

I have attached the file I elaborated with the information from the url you suggested me and looks like there are several frequencies that can be set but not so many because it depends from the timer and the channel basic frequency.
I do not know if there is a different method that can be used to set the frequency at 10kHz.

@Henry_Best, I suspect that a capacitor across the motor terminal may blowout the mosfet.

@Robin2, have a look at the spreadsheet I attached. I have reprinted it in pdf. Those should be the frequencies obtainable according to Arduino Playground - TimerPWMCheatsheet.

Why I m looking for 10 kHz? Because a lower frequency would produce ugly noise, higher frequency would limit the control of the motor speed only to the top range of the supplied volts.
As I mentioned before, at 500 Hz I can control the motor from 4 to 12 V; at 32 kHz the control is limited from approx. 8 V to 12.
So I am trying to balance noise and control setting the frequency at 10 kHz but I have not found the way to achieve that yet.

Thanks to all your comments. If you have an idea about how to set pwm at 10 kHz I would give it a try with pleasure.

Arduino PWM sets.pdf (29.9 KB)

You might consider using Timer2 instead of Timer0 because millis() and delay() depend upon the way it is set up by the library. If you know this and it's OK, then I'm just sayin' :slight_smile: You don't really need to toss the 16 bit Timer1 at the problem.

As for getting 10kHz PWM frequency from Timer2, you want to pick a FAST PWM mode, set the divisor to 8 (16MHz crystal), set OCR2A to 200 (100uS pulse period) and that should give you exactly 10kHz. You set the duty cycle with OCR2B from 0 to 200.

This is off the top of my head, but if you need exact code I can work it up for you.

@Afremont, thanks a lot.
If you can suggest a code for this would help me a lot.

Try this, you'll have to hook your motor to Pin 3.

const int PWMPin = 3;

void setup() {

// generate 10kHz PWM pulse rate on Pin 3
  pinMode(PWMPin, OUTPUT);   // OCR2B sets duty cycle
// Set up Fast PWM on Pin 3
  TCCR2A = 0x23;     //0x23 COM2B1, WGM21, WGM20 
// Set prescaler  
  TCCR2B = 0x0C;   //0x0A WGM21, prescaler = /8
// Set TOP and initialize duty cycle to zero(0)
  OCR2A = 199;    // 199 TOP DO NOT CHANGE, SETS PWM PULSE RATE
  OCR2B = 0;    // initial duty cycle for Pin 3 (0-199) generates 1 500nS pulse even when 0 :(

}

void loop() {

   OCR2B = 100;  //  This sets duty cycle to approx 50%

}

Thank a lot. I will try this afternoon and check the output with an oscilloscope.

Thanks again.

You can play with the TOP value in OCR2A. By setting it to 100 you will double the pulse rate to 20kHz, but then you will have to keep OCR2B <=100 as well, but you'd still be able to change duty cycles by 1% increments. Changing TOP to 255 will lower the pulse rate to around 7800Hz.

The key thing to remember is that OCR2B must be less than the value in OCR2A or the PWM will be at 100%.

The cheatsheet you referred to doesn't seem to cover the additional scope you get by changing the values in the OCRxx registers. These registers contain values that the timer counts up to. For example if the value is 10 it will reach that in 10 clock cycles - approx 1.6MHz if there is no prescaling.

I presume you don't need a frequency of exactly 10kHz. Your list includes 7.8kHz - perhaps that would do?

...R

@Robin2,
you are right, that cheatsheet does not include frequencies obtainable by manipulating OCR.
I need to understand/study what I can obtain manipulating the OCR and then I will update the cheatsheet.
I tried the 7.8 kHz, but is still making noise.

If you change the OCR then you can no longer get all 255 levels of duty cycle.

I simply adjust the PWM by a custom window application which I have coded but this is not the problem.
I am experiencing that the motor is making a hell of a noise due to the default PWM frequency around 500 Hz when I control the speed which is approx. at 170/255.

I would like to increase the Arduino PWM frequency out of the audible frequency, lets say 62.5 kHz.
I am working with pin 5 and pin 6, which are associated to the same timer (Timer 0), pin 6 is not used so I don't care about it.

To increase the PWM frequency of pin 5 and 6, would it be enough if I add this line of code to the Arduino setup?

Code: [Select]
TCCR0B = TCCR0B & 0b11111000 | 0x01;

I want to get 62.4Khz. but applying above code for timer0 it isn't working. Anyone could help me?? it will be highly appriciated

I simply adjust the PWM by a custom window application which I have coded but this is not the problem.
I am experiencing that the motor is making a hell of a noise due to the default PWM frequency around 500 Hz when I control the speed which is approx. at 170/255.

I would like to increase the Arduino PWM frequency out of the audible frequency, lets say 62.5 kHz.
I am working with pin 5 and pin 6, which are associated to the same timer (Timer 0), pin 6 is not used so I don't care about it.

To increase the PWM frequency of pin 5 and 6, would it be enough if I add this line of code to the Arduino setup?

Code: [Select]
TCCR0B = TCCR0B & 0b11111000 | 0x01;

I want to get 62.4Khz. but applying above code for timer0 it isn't working. Anyone could help me?? it will be highly appriciated