100kHZ PWm on arduino UNO?

is it possible to get a 100khz PWM on a UNO?

if so does anyone have the code?

Please help…

Thanks

Emmanuel

This sets up timer2 to run 100kHz on pin 3. Its using OCR2A register to set the MAX value so pin 11 is not available for PWM.

void setup ()
{
  pinMode (3, OUTPUT) ;
  TCCR2A = 0x23 ;
  TCCR2B = 0x09 ; // mode 7, clock prescale by 1
  OCR2A = 160-1 ;  // 160 clock periods = 10us per cycle
  OCR2B =0 ;
  TCNT2 =0 ;
}

void loop ()
{
  // here you can set the duty cycle by writing values between 0 and 160 to 
  // OCR2B
}

Similar thing can be done with timer1 (pins 9 and 10) and this timer allows both pins to PWM since the period can be set with ICR1 (using a mode timer2 doesn't have). timer0 (pins 5 and 6) is used by millis(), delay() and micros() for timekeeping.

One day I’ll see an answer to this question - Why do you want 100KHz PWM?

Mark

Well you can generate audio via delta-sigma conversion, drive a DC-DC converter, ultrasonic motor, control a coreless motor, or generally have fun!

emmanuelbabu: is it possible to get a 100khz PWM on a UNO?

if so does anyone have the code?

If you'd start 30 new threads with the same question instead of 3 as you did until now, the features of the UNO would always stay the same.

The absolute maximum PWM frequency for 8-bit PWM output (range 0...255) is something like ca. 31 or ca. 62 kHz with the Arduino UNO, depending on the PWM pin number.

Higher frequencies would be available for square wave generation only, but not for variable PWM output.

As jurs said that the absolute maximum PWM frequency for 8-bit PWM output is something like ca. 31 or ca. 62 kHz with the Arduino UNO. So lets say if i want to have 62kHz frequency PWM (which would be using timer0), this would disturb my functions like millis(), delay() and micros(), as said by @MarkT.

So is there anyway that i get 62kHz out of my UNO, and i do some changes which allows me to use these functions (millis(), delay() and micros()) as well ?

yiipmann: As jurs said that the absolute maximum PWM frequency for 8-bit PWM output is something like ca. 31 or ca. 62 kHz with the Arduino UNO. So lets say if i want to have 62kHz frequency PWM (which would be using timer0), this would disturb my functions like millis(), delay() and micros(), as said by @MarkT.

So is there anyway that i get 62kHz out of my UNO, and i do some changes which allows me to use these functions (millis(), delay() and micros()) as well ?

If you want to keep the functions millis(), delay() and micros() fully functional, you are not allowed to change Timer0. So the PWM pins associated to Timer0 cannot be changed to a higher PWM frequency without affecting the timing functions.

But you can use the other timers and their PWM pins to speed things up.

Here is some example code (for Atmega328 and Atmega2560 based boards) that uses Timer1:

void arduino_FastPWM()
{
  // This will activate a PWM frequency of 62500 Hz on the 
  // PWM pins associated with Timer1
  // Arduino UNO ==> pin-9 and pin-10
  // Arduino MEGA ==>  pin-11 and pin-12
#if defined(__AVR_ATmega328P__)
  analogWrite(9,127); // let Arduino do PWM timer and pin initialization
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)  
  analogWrite(11,100); // // let Arduino do PWM timer and pin initialization
#else
  *** wrong board ***
#endif  
  // finally set fast-PWM at highest possible frequency
  TCCR1A = _BV(COM1A1) | _BV(WGM10);
  TCCR1B = _BV(CS10) | _BV(WGM12);
}

You can insert this code in your setup() function. Hopefully it works, I cannot test it very much.

But I think you then can use 'analogWrite' with PWM values 0f 1...255 as normal. But after you set a PWM value of 0, the Arduino analogWrite function has shut off PWM, so you will have to make a call to 'arduino_FastPWM()' again to restart PWM.

Just for testing, I think this code has to be worked out further for use in a real application.

Thanks alot for your code @jurs. I will be needing to use the SPI library as well to get data from external ADCs. And i just found out that in that library pin 10 is defined as SS . So i think it would be better if i get my PWM signal out of timer2 instead of timer1 (as timer2 uses pins 3 and 11, whereas pins 9 and 10 used by timer1).

Also can you please clarify me one thing, i know that PWM resolution and frequency are inversely proportional to each other (the higher the frequency, the lower the resolution gets on that PWM signal). So if i want to get 62.5kHz PWM signal using timer2, how low my resolution will get ? (as far as my knowledge goes, if i use 0x01 prescaler, my max frequency is 31.250kHz with a resolution of 256, so if ill double the frequency, my resolution will be decreasing somehow)

I dont get it, because if i use @MarkT 's code logic, i will get 256 resolution for 62.5kHz PWM signal, which doesnt seems right. As you can see in the following code line he got 160(resolution) from 16Mhz/100kHz = 160 (desired frequency = 100kHz)

"OCR2A = 160-1 ; // 160 clock periods = 10us per cycle"

And if i do the same for my case (desired frequency = 62.5kHz) 16MHz/62.5kHz i get 256, which should be the resolution for 31.25kHz frequency, as this 31.25kHz is by default the maximum frequency being offered by 8-bit timer2. So how come i get 256 resolution for an increased frequency of 62.5kHz ?

I hope i made my self clear.

yiipmann: Also can you please clarify me one thing, i know that PWM resolution and frequency are inversely proportional to each other (the higher the frequency, the lower the resolution gets on that PWM signal). So if i want to get 62.5kHz PWM signal using timer2, how low my resolution will get ?

With 62.5 kHz "fast PWM" mode you get a full 8-bit PWM resolution.

With 31.25 kHz "phase correct PWM" mode you get a full 8-bit PWM resolution.

With higher frequencies you can perhaps get PWM with a smaller resolution.

I'm not a PWM guru, so I cannot tell you.

If you want to try out Timer2 with 100 kHz PWM and less than 8-bit resolution, why not try the code that MarkT posted in reply #1 on Mar 24, 2015?

Actually i have'nt recieved my UNO yet, but once i do, i will run different scenarios and observe the output to see what i get. Anyways thanks alot for your helpful replies, 'will try to get 62.5kHz 8bit on timer2 once i get my hands on my arduino.

I'm missing something here. Using this code I can not see how to use OCR2B to change the duty cycle. I use void loop{ OCR2B = 45; analogWrite(3); }

and get a compile response that I'm missing an argument. What am I missing? Please...

Thank you, John

MarkT: This sets up timer2 to run 100kHz on pin 3. Its using OCR2A register to set the MAX value so pin 11 is not available for PWM.

void setup ()
{
  pinMode (3, OUTPUT) ;
  TCCR2A = 0x23 ;
  TCCR2B = 0x09 ; // mode 7, clock prescale by 1
  OCR2A = 160-1 ;  // 160 clock periods = 10us per cycle
  OCR2B =0 ;
  TCNT2 =0 ;
}

void loop () {   // here you can set the duty cycle by writing values between 0 and 160 to   // OCR2B }




Similar thing can be done with timer1 (pins 9 and 10) and this timer
allows both pins to PWM since the period can be set with ICR1 (using a mode
timer2 doesn't have).
timer0 (pins 5 and 6) is used by millis(), delay() and micros() for timekeeping.

analogWrite(3);

analogWrite() takes two arguments, the pin number and the duty cycle.

After taking over a timer by writing the timer control registers, you should just set the register directly when setting the duty cycle for one of the outputs of said timer, instead of using analogWrite(), since analogWrite() isn't aware of what you've done to the timer.

  OCR2B = value ;

It compiles down to a couple of bytes of assembler.

ok so i obviously didn't know that. Now ; I'm activating pwm on button press. However, reading voltage from pin 3 reads -4.20V. when I press the button nothing changes. What is wrong here? please. thank you

EDIT** I get -4.20v wit OCR2B = 45; If I change OCR2B = 10; I get nothing. Nothing at a stand still and nothing on button press.

Does it matter that I'm using a board other than arduino? It's still atmega328 and everything else is the same...

If there happens to be another way; I want to PWM a mosfet at 100kHz with a variable duty cycle... Right now Im soldered onto Digital 3

when I press the button nothing changes. What is wrong here?

Your wiring or your code.

I'm using a board other than arduino? It's still atmega328 and everything else is the same...

Is Timer2B output from the 328 connected to digital pin 3 on your board?

Volt meters sometimes get confused by PWM - either filter it with an RC, or look at it with a scope.

I have nearly 600 lines of code that have been working fine. My buttons all work fine. This is the only addition I've made. Just looked at my solder point under a magnifying glass with lots of light and it looks great. Couldn't have done a better job myself :D

leaving the pin 3 connection just like it is and going back to analogWrite(chargeMosfet, val); it's working fine.

void setup() {

  pinMode(chargeMosfett, OUTPUT);
  TCCR2A = 0x23 ;
  TCCR2B = 0x09 ; // mode 7, clock prescale by 1
  OCR2A = 160-1 ;  // 160 clock periods = 10us per cycle
  OCR2B =0 ;
  TCNT2 =0 ;
}
if(blah){
}else{
//holding pwr button

// following line from 0 - 160 to change duty cycle
// 28% of 160 is 45
OCR2B =10;
}

Well I'm waiting for the techs over at adafruit forum to get back to me on whether or not Timer2B output from the 328 connected to digital pin 3.

If anyone here knows about their Pro Trinket 3.3v feel free to chime in here. I have been through all of the data that I can find and I'm coming up a bit or a byte short. =0)

Here and there waiting...

John

Can you just buzz it out with a meter? OC2B is physical pin 5 on a DIP and physical pin 1 on a TQFP. Which would be D3.

According to this https://learn.adafruit.com/introducing-pro-trinket and this, under Download, it should be connected https://learn.adafruit.com/downloads/pdf/introducing-pro-trinket.pdf