This guide was updated on 2/8/17
There are a few ways to get audio from the Pi Zero. The easiest is just to use an HDMI display, but that’s not always an option. The next option is to use a USB audio adapter. That works fine, but takes up the only available USB port unless you have room in your project for a microUSB hub. There is also I2S over GPIO, but that requires some software tweaks that make it a little more complicated (a guide is coming for it later this year) There is a another option, and this guide explains the the process of getting PWM audio working.
The Raspberry Pi is able to create audio using a pair of GPIO pins. The problem is that the audio is badly distorted. The low notes are too low and cause the speaker to rumble and sound blown, and the high notes have lots of unwanted noise. To assist with removing these noises, this audio filter circuit was added to the original Raspberry Pi.
An audio filter serves to remove unwanted frequencies. A low-pass filter removes high frequencies, and a high-pass filter removes low frequencies. The names say it all.
Here is an image to help visualize the process. The Pass Band is the range of frequencies you want to reach your speaker, and you want everything else removed. The HPF (high-pass filter) in this image is removing most of the frequencies under 100Hz. The LPF (low-pass filter) is doing the same for frequencies above 5kHz.
The filters in the original Raspberry Pi did the exact same thing. The schematic above shows both PWM audio channels, so let’s trim everything down and look at just one of them.
The PWM0_OUT is the unfiltered audio signal, and this comes directly from GPIO pin 13 or GPIO pin 18 (one for left audio and one for right audio). Since I’m showing the right side only, let’s say that this is coming from GPIO pin 13.[spacer height=”1px”]
Now we know that PWM0_OUT is coming from GPIO pin 13, so let’s move further into the schematic. We immediately get to the first part of the circuit, which is the low-pass filter.[spacer height=”1px”]
Here is a Low-Pass Filter (link to Wikipedia) for visualization. Our’s consists of a 270 Ohm Resistor connected in line, followed by a 33nF Capacitor connected to ground. The ground is any negative pin or connection on the Pi Zero. The high frequencies are now filtered out.
Moving further into the circuit, we get to the high-pass filter.
Here is a High Pass Filter (Wikipedia). Our’s consists of a 10uF Capacitor connected in line, followed by a 150 Ohm Resistor connected to ground. The low frequencies are now filtered out. You might notice that the capacitor in this filter is positioned before the resistor, so that’s exactly what we are going to do with our’s.[spacer height=”1px”]
Here is the modified schematic that makes this a correct high-pass filter. The capacitor is now positioned before the resistor.
That completes the right side, and now we have to do the same for the left side. Instead of connecting to GPIO pin 13, the left channel starts from GPIO pin 18. Once the left and right channel filters are built, you will have working audio. Connect the filtered audio to the positive side of the speaker, and connect GND to the negative side. Again, this can be any GND connection from the Pi.
We aren’t done yet though. The audio coming from the PWM is very weak, and it’s made weaker by passing it through the filter. This is plenty if you only need to power headphones, but it really isn’t enough to power speakers. We need an amplifier if we plan to do that.
The yellow L and R pads on the amplifier are the positive left and right PWM audio inputs. Between them is a shared ground input, which can be any of the grounds on the Pi. The red pad is the 5v power input, which should come directly from the Pi’s power source. The orange and blue pads on the right are the audio output leading to the speakers.[spacer height=”1px”]
There is one final detail related to the hardware that needs to be covered. The PWM audio is good, but it does have one drawback. There is some unwanted noise on the PWM line, even when using the filter, and the amplifier amplifies this noise as well. There is a pretty simple method we can use to minimize it though.
The noise on the PWM line is constant, and it doesn’t increase as you increase the volume of the operating system. To use this to our advantage, we start by increasing the operating system volume to the maximum 100% volume. This creates an audio output from the amplifier that is incredibly loud. Now that we have an output that is too loud, but we can limit it using one more trick.
[spacer height=”1px”]This final image shows that trick. A resistor has been added to each of the speaker outputs. I’ve labeled it as 100 Ohm, but anything from 100 Ohm to 200 Ohm works well, and you may prefer something different depending on the volume level you need. Increasing the resistor will lower the volume, and that will also lower the amount of noise you get from the PWM.
That covers the hardware portion, so let’s move to the software.
The last part of the process is telling the Pi Zero to use PWM for audio. This part is very simple. All that’s required is that you add one line of code to the bottom of your config.txt file on your SD card:
What to Purchase
The audio filter on a small PCB is available here.
The audio amplifier is available here.
To simplify the process and purchase the improved audio amplifier that has the audio filter already integrated, visit the store page here.