Go Down

### Topic: 10-bit PWM with Arduino mega (Read 8125 times)previous topic - next topic

#### lampmaker

##### Aug 25, 2010, 11:59 am
Hi,
I've been reading and searching, but couldn't find a solution.

How can I get 10-bit PWM on my Arduino mega?  I need 4 pins with 10-bit resolution.

I've understood that I'll have to play with the timers, but that's way over my head.

Anybody willing to show me how this can be done?   Much appreciated!

#### lampmaker

#1
##### Aug 25, 2010, 05:22 pm
The current PWM frequency of ~500Hz works, it could be slower as well. This is an LED application that requires very subtle color differences. 8 bits turned out to be insufficient resolution.

#### mpeuser

#2
##### Aug 25, 2010, 06:32 pm
Just an idea: One could try to change the PWM duty cycle very fast to accomplish intermediate values.
You interrupt every 6ms; the eye will average what it sees during 24ms, so you have four time slots of 6 ms to fine tune.

Assume you have around 50% duty cycle, this could be 128, 128.25, 128.5 or 128.75 to cover a 1.1024 resolution
What to chose for slot 1,2,3,4:
case 128:  all 128
case 128.25:  3x128+1x129
case 128.5: 2x 128+2x129
case 128.75: 1x 128+3x129

#### lampmaker

#3
##### Aug 25, 2010, 09:45 pm
pretty cool idea. However, I have quite a bit of other code running communications and calculations. Not sure if this would work nicely.

I'm sure it can be done by playing around with the timers. The Arduino Mega has a few. Unfortunately, there isn't much documentation about the Arduino Mega timers.    Guess I'll have to spend some time learning this.

#### mpeuser

#4
##### Aug 25, 2010, 11:24 pm
This mgiht also interest you, but has to be adapted for the Mega...
http://forums.adafruit.com/viewtopic.php?t=5133&highlight=pwm

#### Grumpy_Mike

#5
##### Aug 26, 2010, 10:46 am
Quote
Unfortunately, there isn't much documentation about the Arduino Mega timers

Yes there is, it's all in the processors data sheet. You can achieve PWM of between 2 and 16 bits precision on 12 channels.
All you need to do is to poke a few values into registers, the data sheet tells you what they are. As far as I know they haven't been incorporated into the Arduino wrapper yet.

#### lampmaker

#6
##### Aug 26, 2010, 09:09 pm
Ok, I guess I should have phrased differently.. There isn't much _easy_ documentation about this :-).  Don't forget, for people like me (no experience with microcontrollers), Arduino is a blessing. I just spent some time reading the 16-bit timer section (Chapter 17) of the datasheet.   Pretty heavy stuff.

I'll have to spend some serious time here, have no idea how the analogwrite is implemented with arduino and if messing with the timers will require re-coding it.

#### AWOL

#7
##### Aug 26, 2010, 09:25 pm
Quote
have no idea how the analogwrite is implemented with arduino

One of the great things about the Arduino is you can actually look at the source of how analogWrite is implemented.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### lampmaker

#8
##### Aug 26, 2010, 10:21 pm
Ok, this is where I'm at:

From the datasheet: Timers 1,3,4 and 5 are 16-bit timers.
http://www.atmel.com/dyn/resources/prod_documents/doc2549.PDF

from Arduino wiring.c:

// set timer 3, 4, 5 prescale factor to 64
sbi(TCCR3B, CS31);      sbi(TCCR3B, CS30);
sbi(TCCR4B, CS41);      sbi(TCCR4B, CS40);
sbi(TCCR5B, CS51);      sbi(TCCR5B, CS50);
// put timer 3, 4, 5 in 8-bit phase correct pwm mode
sbi(TCCR3A, WGM30);
sbi(TCCR4A, WGM40);
sbi(TCCR5A, WGM50);

I can find these values in the datasheet as well (table 17-2), so I think I understand what is being done.    I only need to add

sbi(TCCR3A, WGM31);
sbi(TCCR4A, WGM41);

to set the Timers 3 and 4 in 10-Bit PWM mode.  These timers work with the following pins:
from pins_arduino.c:
TIMER3B      , // PE 4 ** 2 ** PWM2
TIMER3C      , // PE 5 ** 3 ** PWM3
TIMER3A      , // PE 3 ** 5 ** PWM5
TIMER4A      , // PH 3 ** 6 ** PWM6
TIMER4B      , // PH 4 ** 7 ** PWM7
TIMER4C      , // PH 5 ** 8 ** PWM8
TIMER5C      , // PL 5 ** 44 ** D44
TIMER5B      , // PL 4 ** 45 ** D45
TIMER5A      , // PL 3 ** 46 ** D46

Interestingly, pins 44,45 and 46 can apparently also be used for PWM on the Arduino Mega.

Is this correct?  If so, it's much easier than I anticipated. Should be easy to add some functions to set the PWM resolution to the Arduino code.

Setting the PWM frequency should be similarly simple.. by setting CS32, CS31, CS30, CS42, CS41, CS40, etc.  I'll play with this as well.

When I've figured it all out, I'll post some simple functions that should help other idiots like me without having to revert to the datasheet.

#### oscarcar

#9
##### Aug 27, 2010, 02:19 am
Might want to check these links:

http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1242738248
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238817116
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559

#### lampmaker

#10
##### Aug 27, 2010, 06:58 am
Thanks,   I found those as well but I didn't understand the timers fully until I read the datasheet.   Also, I wasn't sure how to implement this for the mega.

Go Up