With microcontrollers without DACs (Digital-to-Analogue-Converters), the PWM outputs can be used to create analogue signals.
In a nutshell, this is what do you need to know/do to configure the Arduino Uno PWM output to play analogue signals or audio:
Combining PWM outputs:
In Arduino UNO each PWM output has a resolution of up to 8 bits, so you can use one, two or even three PWM outputs to generate the output signal.
- pros: higher bit resolution and lower noise floor.
- cons: higher computational load and resistive ladder accuracy.
With Arduino Uno the sweet spot is using a 2 PWMS with 8 bit resolution, giving 16 bits in total with a simple resistor ladder.
If you want to understand all the details about the options and resistor configurations, you can read the great "Dual PWM Circuits" article by openmusic labs.
Which Switching Frequency?:
The higher the frequency the better but at the price of a higher computational load. Anything above the audio spectrum its ok, using 8 bit resolution a nice balanced point is using 31.3KHz.
If you want to understand all the posibilities and
Configuring Arduino UNO registers for PWM audio:
There are basically 3 registers that controls everything:
- PWM_QTY: Sets to 1 for Single PWM, and 2 for Dual PWM.
- PWM_FREQ: Sets the PWM frequency following the table below.
- PWM_MODE Sets the Fast Mode (1) or the Phase Correct Mode (0)
note: Fast Mode can reach higher switching frequencies (
) at the expense of higher harmonic distortion (
). By default we use Phase Correct Mode although you can try the Fast one and find the sound differences.
The works done by OpenMusicLabs in the Arduino Uno PWM generation are great. I really appreciate all the outstanding analysis and examples. THANKS.
PWM Distortion Analysis
Arduino (ATmega) PWM audio DAC