Driving a Speaker – Adding an Audio Amplifier (Adding the PAM8403 to a MCU)
Piezo speakers (see here) are great where you don’t need high quality or loud sound or indeed where space is at a premium. But for anything else a small (or even large speaker) is the only thing that will do. However our little micro-controllers (no matter which you use) do not have the power to drive these directly, so we need some additional circuitry, we need an audio amplifier.
Video : If you want to look at the companion video to this article it’s just below, else skip past for the rest of the article
Audio Amplifiers
Any amplifier makes a signal (voltage bigger) and normally (but not necessarily) it can handle larger currents through it’s circuitry. An audio amplifier is designed to do this specifically well for the range of frequencies for human hearing (i.e. around 20 -20,000Hz).
Design considerations – Making sure nothing breaks!
We need to make sure that neither the Audio Amplifier or the Speaker are driven beyond their specification, of they are they are likely to get hot and break. The MCU will not break unless you wire something wrong as the input impedance (the resistance) to the audio amplifier is extremely high meaning very little current flows from the MCU to the amp. So from an online store I purchased the following audio amp:
It takes 2.5V to 5V as it’s power (the right hand side connector) so it’s ideal for most MCU projects. On the left there is an input for the left channel audio then a common ground and then the input for the right channel. At the top there are outputs for the left and right amplified output. It’s based on the PAM8403 audio amplifier and can be purchased for just a few pennies (usually delivered!). The specs for this chip state it can deliver upto 3W RMS per channel so we need to make sure we do not exceed this, let’s do some basic calculations. These will be basic ball park calculations which will be fine for our needs, we won’t worry about excessive detail and precision using more advanced equations. Using these will certainly ensure you are driving your device well within it’s limits.
The Speaker (Limiting current draw in your circuit)
The above amplifier is capable of driving speakers as low as 4Ohms. However for our small low power (sometimes powered over USB) projects using a 4ohm speaker can cause issues. Let’s see why. If you calculate a peak current through the speaker for the two common voltages used you will start to see the issue:
For 3.3V (i.e. ESP32 etc.) using Current=Voltage/Resistance
I=3.3/4
I=0.825A
For 5V systems (i.e. Arduino etc.)
I=5/4
I=1.25A
As the USB standard is only designed for a max 0.5A and a lot of small supplies (and even batteries) may struggle with these current loads you can see why me might have an issue. The result is usually a voltage drop and the MCU will reset (a so called brown out – as compared to a black out where all voltage is lost).
So stick to a 8Ohm or above resistance for your speaker. Look at the same calcs using 8Ohm.
For 3.3V (i.e. ESP32 etc.) using Current=Voltage/Resistance
I=3.3/8
I=0.4125A
For 5V systems (i.e. Arduino etc.)
I=5/8
I=0.625A
Much less current although for the 5V system it’s still above USB spec for brief moments, depending on your usage you may want to use a speaker with a resistance greater than 8Ohm (or ensure you never drive it at it’s loudest). In practice I’ve managed to use a 4Ohm speaker on an ESP32 system where the lower voltage gives a smaller current but even then I had to connect directly to the USB supply pin on the board and still I’ve had an ESP32 fail and others be a little unpredictable sometimes, so be warned!
Ensuring you don’t exceed the power rating
If we have a 3.3V system (like the ESP8266 or ESP32) and the resistance of the speaker is 8 ohms then what power will be going through our amplifier? The equation P=V²/R will give us the power going through the device at this moment in time (not averaged out over time), let’s put some figures in;
P=3.3²/8
P=10.89/8
P=1.36W
So everything looks good so far. But what if we had a 5V system (like the Arduino), let’s run this calculation again.
P=5²/8
P=25/8
P=3.125W
A little over, but probably OK, especially as this would be an absolute peak for a very short amount of time. I must stress that actually the PAM8403 in general can cope with a peak of about 6W. This is because we are dealing with audio frequencies where it only hits this peak now and again. However for a beginner and for the benefit of simplicity and running our kit well within spec these approximate calculations will suffice, if you want to know more try researching RMS on the internet.
So we can create our circuit and not break the Audio Amplifier, but what about the speaker?
Buying the Speaker
So if you want the max volume you can from you speaker you just need to buy almost any that is rated 8Ohms and 3W (larger values are of course OK). Job Done. However you may want specific speakers because of space limitations, here for example is one I purchased. Really tiny but great for small spaces;
It was 8Ohm and as you can see from the back is rated for 0.5W. Immediately we can see a problem, it can only handle 0.5W, so even if using a 3.3V Vcc we will quickly destroy this speaker. I will address this issue after the next part but for now let’s presume we have a 8Ohm, 3W speaker and we want maximum volume.
Driving the PAM8403
The maximum input voltage to this chip is 0.3V but the output from your circuit is likely to be much higher, for example 5V with Arduino, 3.3V with other systems. So we need to ensure that the maximum voltage you expect to output is scaled down to 0.3V (or less). For this we use a “potential divider”. If you’re not familiar with these then take a few mins to look them up as it’s a very basic concept in electronics and used widely. Here’s the circuit you’d need;
Your signal comes into R1 (this is the Vin), which as mentioned is likely to be 3.3V or 5V (for Arduino). The two resistors divide the voltage down depending on the ratio R1 and R2 and the new output voltage is at Vout. The tricky bit is selecting the correct resistors to give the correct voltage at Vout. But never fear, it’s not too hard finding out what to use, follow these steps. We’ll do an example for 3.3V systems (Vin=3.3) first.
- Select R1 so that it does not allow too much current to flow from your source to ground, if you select a really small value then you may damage your source (i.e. Arduino or ESP32). I’d recommend 10KΩ for R1. Stick with that and you’ll be fine
- Us the following equation to calculate the value of R2:R2 = (R1 x Vout)/ (Vin– Vout)R2 = (10000 x 0.3)/ (3.3– 0.3)R2 = 3000 / 3R2 = 1000Ω (or 1KΩ)
- Select this resistor or the nearest value that is below this result
In this case 1KΩ is a commonly available value so we’ll stick with this. Let’s do it that calculation again but for a Vin of 5V:
R2 = (R1 x Vout)/ (Vin– Vout)
R2 = (10000 x 0.3)/ (5 – 0.3)
R2 = 3000 / 4.7
R2 = 638Ω
Now, this isn’t a common value and in my parts bin the nearest I have are 560 or 680. As rule 3 above states, choose the lower of the nearest values, so 560Ω is the one. The reason for this is that a lower value here will give a Vout of less than what we ideally wanted but a bigger value will give a voltage that is bigger than what we wanted, which may damage the chip, so always go lower.
Adding Volume Control
So now we have our voltage in the correct range for the PAM8403 but how can we control the volume? We use a variable resistor or more commonly a potentiometer. These have 3 connections and act just like out potential divider above, they reduce the voltage but because they can be changed (with a rotary dial usually) they can alter the voltage out, anything from 0v to the maximum they are supplied with (Vin). Let’s look at the full circuit below with all these bits in place.
We can see the output from our potential divider goes to one side of the potentiometer (10K Log), this is the Vin to this device. The other side is connected to the ground and the voltage comes out in the middle (literally so on the physical device also). This is then finally sent to the input of the PAM8403 (in this case the left channel). The potentiometer needs to be Logarithmic (or Log for short). This is because our ears respond to volume (loudness) logarithmic-ally and if you use a linear type pf potentiometer it just won’t feel to be working correctly.
An example of this circuit in action can be found on this page about using DACs on the ESP32 and here on the Frogger build page
Advanced – I want to use a lower power speaker.
As mentioned above there may be cases when you need to use a lower wattage speaker, perhaps for space reasons. In this case we need to ensure that the output voltage never goes so high as to cause that amount of power to go through the speaker. Let’s use the small speaker pictured earlier that was 8Ω and 0.5W. If Power=Voltage² / Resistance then the max voltage would be given by this equation;
Voltage = √(Power x Resistance)
Let’s put some numbers in
V= √(0.5 x 8)
V= √(4)
V = 2V
So the max voltage at the output would 2V. All we need do is ensure that the voltage input to the audio amp does not go so high as to goes this voltage at the output. We just need to adjust the value of the R2 resistor in the potential divider circuit from previously. If we want to drop the PAM8403 max output voltage down from 3.3V to 2V ( 60% of that output voltage) then we can simply just set a maxmium of 60% of the 0.3 input voltage, which would be 0.18V. Here’s the new calculation;
R2 = (R1 x Vout)/ (Vin– Vout)
R2 = (10000 x 0.18)/ (3.3– 0.18)
R2 = 1800/ 3.12
R2 = 576Ω
And as noted before I have some 560Ω resistors and so that is a close match, as long as you choose the nearest value or below then all will be good. The above supposes that the PAM8403 amplifies to full rail voltage when presented with it’s max input voltage and amplifies linear-ally over the 0 to 0.3v input range.
That’s all for now, hope this has been helpful.
I use your circuit to play voice, but not always (almost never) esp32 plays file good.
If I get signals from microfono of android for example and send them to esp32 I heard only big noise.
Signal from android microfone is incompatible with esp32 dac?
When you say send signal from phone to ESP32 DAC, how are you doing that? How are you digitising the sound to store in your ESP32? Have you followed the other guides on getting sound onto the ESP32 before it plays it back, there are a few steps to undertake. Check out the article on playing WAV files (if you’ve not already done so) at https://www.xtronical.com/basics/audio/dacs-for-sound/playing-wav-files/
This drives the amplifier with an input voltage in the range between 0 and +0.3 V. The datasheet says it accepts input between -0.3 and +0.3 V. Will this also drive the output speaker in the upper half of its range? Does this apply a DC offset to the waveform? When starting the sine wave at index 0, will it click when the sound starts because it jumps directly from 0% to +50% and then circles around that DC offset? Where would I get a negative voltage when driving from an MCU?
HI, sorry late reply, I have problems getting emails from the site to tell me I’ve a new comment.
Yes, the range is 0 to 0.3V, as we don’t have a negative rail available from the DAC output. So yes, just upper half of range. The wave form is still valid, just the speaker will only travel from it’s natural rest point and then in one direction and back. You should not here a click as index 0 is the resting point of the speaker (in the middle of it’s travel). If you jump from 0 to 50% instantly then any speaker will click. But as the click is quick and then the tone starts if’s probably not noticeable. Ideally I should start it at the bottom of the wave.
Getting a negative voltage is possible with minimal additional circuitry if you use two dacs to drive the amp, but it takes some effort and being very careful when developing or you may damage your ESP32. Or some extra circuitry to create an offset mid point voltage to the amp that the DAC voltage will be above or below. Again, extra effort and something that I didn’t think was worthwhile at the time. Doesn’t mean I won’t ever do it though!
I’ve recently read somewhere that I could put a small capacitor between the amplifier inputs to adjust for a DC bias (which we have here). But I just can’t find that info anymore. Would that work instead of the more complex negative voltage solution?
Also, where did you get your 10k log pot from? I’ve searched in many places but could only find linear potentiometers or other values.
The idea with the caps is to only allow AC frequencies through and block the DC, this page did a mod, http://www.diybudgetaudio.com/PAM8403.htm , if that helps. Although I think they said the sound wasn’t much different (only speed read it though).
The pots are very common, typing “10k log potentiometer” into Amazon (UK) brought up these (amongst others) in the list.
https://www.amazon.co.uk/10K-Logarithmic-Potentiometer-Coloured-Knob/dp/B00YEX8KNS/ref=sr_1_3
Although the value of it is not critical as it’s just being used as a potential divider, 20K, 50K or 100K would work equally the same. Hope this helps. If you’re really struggling then 10K linear would work, just the volume increases may not sound even over the range.