welcome: please sign in
location: Diff for "PWMDAC"
Differences between revisions 8 and 9
Revision 8 as of 2013-01-08 22:10:32
Size: 3104
Editor: guest
Comment:
Revision 9 as of 2013-01-08 22:11:46
Size: 3106
Editor: guest
Comment:
Deletions are marked like this. Additions are marked like this.
Line 14: Line 14:

Arduino (ATmega) PWM audio DAC

About PWM on the Arduino (ATmega)

This page describes all the nitty gritty of getting your Arduino set up to output decent audio on its PWM via Timer1. For more in-depth information on what the settings mean, and what values are right for your application, please check out our PWM Tutorial on the main site.

Timer1 outputs its data on pins 9 and 10 on the Arduino (pin 9/10 are OC1A/B and PORTB1/2 on the ATmega328p). For all of the following, it will be assumed that pin 9 is used for Single PWM, and is the high byte for Dual PWM. Pin 10 is not used for Single PWM, and is the low byte for Dual PWM. You can also set up for Dual PWM, and output 2 different signals, one on each output.

Other timers can be similarly setup to run PWM, but we use Timer1 because it is a 16 bit timer, so it can do greater bit depth at lower frequencies (if desired). The register settings for other timers is similar, but check the ATmega328p datasheet to be make sure its all correct. Also, be careful when using Timer0 on the Arduino, as it is already in use for the delay() and millis() functions, and its overflow interrupt can not be reused.

Register settings

The following charts all assume a microcontroller clock frequency of 16MHz (standard on the Arduino). If you are using a different oscillator, just multiply the frequencies listed by Fcpu/16MHz, where Fcpu is your oscillator frequency. For example, if you were running at 8MHz, you would multiply by 1/2, and if you were running at 20MHz, you would multiply by 5/4. Everything else stays the same.

Fast

Phase Correct

Frequency

Value

Single

Dual

Value

Single

Dual

250kHz

0x003F

6 bit

12 bit

0x001F

5 bit

10 bit

125kHz

0x007F

7 bit

14 bit

0x003F

6 bit

12 bit

62.5kHz

0x00FF

8 bit

16 bit

0x007F

7 bit

14 bit

31.3kHz

0x01FF

9 bit

N/A

0x00FF

8 bit

16 bit

15.6kHz

0x03FF

10 bit

N/A

0x01FF

9 bit

N/A

7.81kHz

0x07FF

11 bit

N/A

0x03FF

10 bit

N/A

3.91kHz

0x0FFF

12 bit

N/A

0x07FF

11 bit

N/A

1.95kHz

0x1FFF

13 bit

N/A

0x0FFF

12 bit

N/A

976Hz

0x3FFF

14 bit

N/A

0x1FFF

13 bit

N/A

488Hz

0x7FFF

15 bit

N/A

0x3FFF

14 bit

N/A

244Hz

0xFFFF

16 bit

N/A

0x7FFF

15 bit

N/A

122Hz

N/A

N/A

N/A

0xFFFF

16 bit

N/A

Example Arduino Sketch

This skecth uses the above charts to set the Arduino PWM to 31.25kHz, Dual PWM, Phase Correct, at 16 bit depth. It takes in audio on ADC0, and plays it out the PWM, so you can hear the sort of quality you can expect from 10 bit data (10 bits is the depth of the ADC). The following low-pass filter and summing circuit should be used, along with a the bias circuit for the ADC.

PWMDAC (last edited 2013-01-15 05:27:27 by guest)