Raspberry Pi Pico PWM Audio Output Circuit
June 27, 2023
As discussed in class 7 of my Developing with Pi series, Sound and Music Output with the Raspberry Pi RP2040 Pico, the Raspberry Pi Pico/RP2040 is a rather impressive sound source. Not only is it able to generate programmatic beeps and boops as you might expect from an Arduino Uno and the like, but it can also play uncompressed WAV files, as well as compressed MP3s. The big restriction is that the Pico only has 2MB of Flash memory, though the RP2040 can work with up 16MB, allowing for a bit more room depending on your board.
Proper PWM Circuitry
In the previously mentioned class, I hooked the output pin and ground up to a small speaker to produce audio, and utilized an I2S amplifier. The direct GPIO connection method produces an audio output. However, it’s a DC signal, varying between 0 and 3.3V.
Proper audio line-level signals are AC, varying between ±1.736 in professional applications, and much lower for consumer equipment. While I’ve produced no apparent damage using this DC configuration in my limited testing, I don’t exactly trust it either.
Fortunately, there is a ready-made solution found on page 23 of Raspberry Pi’s RP2040 hardware design guide, shown in their Figure 22:
Caption: PWM audio circuit from RP2040 hardware design guide / Image Credit: Raspberry Pi
Via a configuration of capacitors and resistors, the circuit turns GPIO27 and GPIO28 into stereo AC signals that are fed into an audio jack. The setup uses a dedicated 3.3V audio power with a logic buffer to mitigate digital noise from the main supply. It’s a fairly simple circuit as-is, but I distilled it down even further to eliminate the external power supply for a mono output:
Caption: Simplified circuit / Image Credit: KiCad screencap
This simplified circuit produces the desired AC mono audio output. Tying the tip and ring segments of the 3.5mm jack together allows sound to emanate from both the left and right speakers on headphones at the same time. Here’s the circuit laid out on a breadboard, with GPIO15 used instead of GPIO20:
Caption: Simplified circuit on a breadboard / Image Credit: Jeremy Cook
I also made a variation of this circuit on a design that I’ve been working on. Here I used a 2k resistor that I had on hand instead of the 1.8k component specified by the design guide. Both produced audio in broadly the same manner.
Caption: PCB circuit. 2K resistor substituted for 1.8K resistor. 220 ohm resistor near Pico not shown. / Image Credit: Jeremy Cook
Listening with decent headphones, clips sound good when played at full volume. However, when the volume is low there is a noticeable hiss. Whether this is a result of not using a separate power supply, or if it’s due to another hardware and/or software issue, I’m not certain. This setup is now able to send a properly alternating audio signal, and I wouldn’t hesitate (much) to hook it up to unknown audio equipment.
Given that implementing this type of audio output is a matter of a few cents worth of components versus simply hooking an output up to a GPIO, I’d put this down as an appropriate audio solution in a range of situations. At the same time, one would want to explore different filtering methods for eliminating low-level hiss in production. One might also consider using an I2S amplifier like the MAX98357A as an alternative, though this will require the use of three GPIO pins and different programming.