DAC’s on ESP32

Full video supporting this article is available below;

So, you’ve got your shiny new ESP32 and it’s amazing, does everything you want and more. But have you explored the DAC‘s yet? Digital to Analogue Converters are useful circuits for converting the internal clean digital world of the microprocessor into the fuzzy messy analogue worlds we live in. If you are familiar with ADC‘s (Analogue to Digital Converters), which most MCU’s have, then you will know that they allow us to convert a varying voltage to a numeric value. Handy for when you want to sample sound or temperature or pressure or … well many different things. DAC‘s do the reverse, they will take a digital value and convert it to an output voltage on a specified pin. Typically in the range 0v to Vcc (whatever Vcc may be, but sometimes you can specifiy or set an upper voltage point).

So for example if the Vcc was 3.3V our digital value could be anything between 0 and 255 (8bits). Setting it to 0 would result in 0V at the output pin, a value of 127 would be approx 1.65V at the output pin and 255 would be 3.3V. In this way we could control the brightness of a light or speed of a motor by altering the voltage supplied to it using a digital number 0 for lowest value, 255 for largest and then any value in-between.

But you may say, “I can already do that using PWM”, well, yes, PWM simulates a DAC but is not suitable for all applications. DAC’s in particular come into their own when it comes to sound.

DAC’s and Sound.
The advantages of storing sound as a digital representation of itself were easily spotted by the early music and electronics engineers. For example being able to easily make perfect copies each and every time rather than having to “look after” a very special master copy of the music (which in itself was often copied to junior master copies) was obviously beneficial. It also did away with expensive high quality duplicating equipment. You could now send perfect copies over the telephone line with no loss of quality. Try sending your latest album to the other side of the world over the phone line for duplication using an analogue copy! Impossible, so master copies had to be shipped to duplication plants physically.

Once your sound has been stored digitally (converted using an ADC) if you want to listen to it again with your analogue ears then we need to be able to convert it back from the digital data into a analogue signal again and hence the DAC’s.

Resolution and accuracy
The higher the resolution then the more accurate your digital stored sound will be when replayed. Note that there are other factors to sound accuracy – such as sample rate – which we will cover in later articles on producing sound. For now we will just look at resolution. In the CD specification it was 16 bit resolution, so the original sound (when converted to a voltage using a microphone) was stored as a 16 bit number – a number between 0 and 65535 (65536 values). The higher the number of bits to store the sound the finer and more accurate sound representation you will get. However the human ear has limitations and it’s not just a matter of the more the number of bits the better the sound as there comes a point when our ears cannot tell the difference.

In the ESP32 the resolution is 256, it has a 8 bit DAC (values from 0 to 255). This may seem poor but in fact it does allow us to have a good  representation of sound albeit not of audiophile quality. With our 3.3 volts processor this should mean a 0 sent to the DAC would give 0V on the DAC output pin and 255 would give 3.3V on the DAC output pin. However in real life the circuitry gives just slightly different values for various technical reasons. Generally starting a little over 0V and ending at around 3.24V for value of 255.

Testing your DAC
Hook up a voltmeter to GPIO pin 25 of the ESP32. This is the output of DAC1. The ESP32 has two DAC’s whose outputs come out on GPIO25 and GPIO26.  Enter the code below and upload to your ESP32. If you’ve not set up your Arduino to talk to ESP32 modules then have a look at this article.

You should see voltages of approx (and remember this is the analogue world now so they are approx!)

0.20V
0.60V
1.00V
1.36V
1.72V
2.12V
2.52V
2.88V
3.20V

Earlier we said that the voltage should be 0V for a value of 0 and 3.3V for a value of 255. Well, that’s in an ideal “what you would expect” world. In fact we get values slightly off from these due to the circuitry. For 0 we are getting around 200mV and for 255 around 3.20V. With any DAC you should check the range you are getting for the values you put in. There may even be some variance between devices due to manufacturing tolerances.

Producing Sound
To make some sound we need a speaker, we could connect a Piezo directly to the ESP32’s DAC but that wouldn’t produce good volume or quality so we add a simple audio amp module based on the PAM8403, full schematic below (click to enlarge);

Full explanation of this circuit is available in the video linked to above. So build this circuit and if you have a scope you can also inspect the wave-forms produced from the code below.

Producing a Sine Wave
Let’s do something a little more interesting, let’s draw a nice smart sign wave on a oscilloscope. If you have a scope you can try this code, if you don’t try adding a small piezo sounder to the DAC output and you should hear a tone.

This should produce a nice sine wave on your scope or a simple tone on your piezo sounder. Do not connect up a normal speaker to the DAC output, you will blow that part of the circuitry and possible the entire MCU, you need additional circuitry to manage the power of other devices but piezo speakers draw very little current and are fine. Note: the volume from the piezo may be very low, you may have to listen very carefully! (Piezo’s don’t work fantastically with smooth sine waves) Here’s the sine wave from my scope;

Looks super smooth doesn’t it? Well yes, it’s not bad but you’ve got to remember that this analogue signal was generated from a digital value in the range of 0-255 and that it moves up in discreet voltage “steps”. So our range as found out above was 0.2 to 3.2V. This is a range of 3V. To found out how much the voltage changes for each digital value (0-255) we divide this by 256, this gives 0.012V  or around 120mV per step. If we zoom in on a part of the wave we can clearly see this stepping

A basic 1 edge saw-tooth
The code below will produce a simple 1 edged saw-tooth wave-form

Saw-tooth 2.

Saw-tooth 3
To really show how we can manipulate the waveform have a look at this example which produces an almost mountain landscape for a wave-form

That’s all for now, in the next article in the DAC/sound series we look at capturing/storing and replaying some digital sound/speach!

Next Article : Playing Wav files/Digital Speech and sound