Learn how to utilize ESP32's built-in Digital to Analog Converters (DACs) for outputting audio and arbitrary signals at high frequencies, along with a step-by-step guide on configuring the I2S peripheral for using DAC channels.
[0:00] Hey Everyone, we’re back with another video about the ESP32 and audio output.
[0:07] In previous videos, we’ve covered using the ESP32’s I2S peripherals
[0:12] along with the built-in Analogue to Digital Converters for reading audio data.
[0:17] We’ve also looked at using the I2S peripherals for directly outputting digital audio signals.
[0:23] In this video, we’re going to take a look at using the built-in Digital to Analogue Converters.
[0:28] We’ll use these to output analogue signals directly from the ESP32.
[0:34] So, there are a few things to note about the Digital to Analogue Converters on the ESP32.
[0:40] There are two channels available DAC-1 and DAC-2.
[0:45] Both these channels support 8-bit resolution so we can set them to a value between 0 and 255.
[0:52] The range of the output voltage is from 0v volts to Vdd.
[0:56] So, typically a range of 0 volts to 3.3 volts.
[1:01] And one big difference from what you may be used to is that the GPIO pins are fixed.
[1:06] Channel 1 will output on GPIO25 and channel 2 will output on GPIO26.
[1:13] Basic output using Arduino code is pretty straightforward.
[1:17] We just use the “dacWrite” function specifying pins 25 or 26
[1:23] along with the value that you would like to send.
[1:26] If you want to stick to the IDF functions this is also very straightforward.
[1:31] You just need to enable the DAC channel and then call “dac_output_voltage”.
[1:36] DAC channel 1 will output on pin 25 and DAC channel 2 will output on pin 26.
[1:43] Let’s have a look at this in action.
[1:46] I’ve hooked up my multimeter to one of my esp32 dev boards and I’m slowly stepping up the voltage
[1:53] on the output of the DAC channel.
[2:04] Here you can see a chart of the expected values versus the measured values.
[2:09] There’s a couple of things to note:
[2:12] We don’t get zero volts when the output is set to zero we get around four millivolts.
[2:17] There is a reasonably linear range up to about 1.5 volts where the error is fairly small.
[2:24] And then we increasingly get
[2:25] differing values from what we expect as we approach the maximum output voltage.
[2:30] If you’re doing anything that requires any accuracy it’s probably worth calibrating
[2:35] your own device to see what values you get.
[2:38] So, using direct output is pretty good if you just want to output a slowly changing value.
[2:43] But what If you want to play audio or generate high-frequency signals.
[2:47] For this, we can use the I2S peripheral to transfer data using DMA.
[2:52] This will let us queue up samples to be
[2:54] output letting the CPU get on with doing other processing.
[2:58] We need to configure the I2S peripheral to use the built-in Digital to Analog Converters.
[3:05] We need to tell it the sample rate we want to use and bits per sample.
[3:10] This is slightly strange as only the top eight bits will be used by the DACs.
[3:15] Initializing the I2S peripheral is the same as usual.
[3:19] We install the driver - there is one important note here: we can only use I2S0 with the built-in DACs.
[3:27] We also need to set the I2S peripheral into DAC mode and enable both the DAC channels.
[3:34] Sending data to the I2S peripheral is straightforward
[3:38] and follows the same pattern as we’ve used before.
[3:41] We create a task and within our task wait for the peripheral to request more data.
[3:47] We can then write more data to the peripheral for output.
[3:52] Now the output from the DAC’s won’t be powerful enough to drive a speaker directly
[3:57] so you’ll need an amplifier.
[3:58] I’m using a small breakout board with an audio amplifier but you can easily
[4:03] build a simple amplifier from discrete components.
[4:06] Let’s have a listen to see how well this works.
[4:38] There’s a bit of noise but that’s probably to be expected when building up a circuit
[4:42] on a breadboard - we’re not dealing with high-end audio here.
[4:47] What about outputting arbitrary signals and higher frequencies?
[4:51] I’ve tried a few experiments outputting a simple sawtooth
[4:54] waveform and this is the highest frequency I was able to achieve.
[4:59] This works out at a sample rate of around 2 MHz so you can output at fairly high frequencies.
[5:08] So, what have we learned?
[5:10] We can use the built-in Digital to Analog Converters
[5:13] to output analogue signals directly from the ESP32.
[5:18] We can output audio data and we can output arbitrary signals at reasonably high frequencies.
[5:26] The outputs are reasonably linear over a range of values
[5:30] but we are limited to 8-bit resolution so high-end audio is probably not an option.
[5:38] Apart from that, this is a pretty simple way to get analogue data out of the esp32.
[5:43] So thanks for watching all the source code is on GitHub - the link is in the description.
[5:49] If you found this video useful then please hit the subscribe button.
[5:52] There are more videos in the pipeline and I’m working on an interesting project
[5:56] which will hopefully use some of what we’ve learned in this video.
[6:00] So thanks again and I’ll see you in the next video!