View All Posts
Want to keep up to date with the latest posts and videos? Subscribe to the newsletter
HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi

In this video, I've made some fascinating explorations with the ESP32 S3 chips and TinyS3 boards from Unexpected Maker. Intriguingly, even without a DAC converter, S3 chips can produce an audio waveform. I've played around with a basic RC filter to reconstruct the analogue audio signal from a PDM signal. The result was quite impressive for a board without a native DAC! I also discussed the possibility of creating a simple amplifier using just a MOSFET as a switch. Finally, I gave a peek into some of my new boards from PCBWay and looked at how Delta Sigma modulation can be played with to recover original data. It's all quite a fun foray into the world of circuitry and audio signals!

Related Content

[0:00] So I’ve been playing recently with some ESP32 S3 chips and boards
[0:06] So this board is a TinyS3 from the Unexpected Maker
[0:09] It’s a well known fact that the S3 doesn’t have a DAC converter
[0:15] There’s lots of complaints online about how that’s really annoying
[0:19] and you can’t get audio out, how frustrating
[0:23] But it may surprise you to see if we switch over to the oscilloscope
[0:28] that we have what very much looks like an analogue signal
[0:31] And if we zoom out on this analogue signal
[0:34] you can see that it looks remarkably like an audio waveform
[0:38] So that’s pretty interesting
[0:40] If we turn on channel 1, which is connected directly to pin 21 on the board
[0:45] we can see how this works
[0:47] So we’re using a PDM signal
[0:50] So if I zoom in on that signal
[0:52] you can actually see how the density changes
[0:55] as the value of the analogue signal changes
[0:58] So to reconstruct the analogue signal
[0:59] all I’ve got is a simple RC filter
[1:02] So if we look back at the board
[1:04] you can see my RC filter here
[1:05] and I picked fairly arbitrary components for this
[1:09] I think this is just a 1k and 100nF
[1:13] But it’s reconstructing the analogue signal, no problem
[1:16] So let’s have a listen to it and see how it sounds
[1:19] So I have a very simple speaker here, USB powered speaker
[1:24] And this just connects via a headphone jack
[1:27] So let’s get that wired up
[1:30] and see if we can actually hear the audio signal
[1:34] So we’ll plug that in
[1:38] And we’ll take our reconstructed analogue signal from the RC filter
[1:43] We’ll just play that on the tip
[1:44] And of course we do need a ground signal
[1:48] Surprisingly it’s working without one, which is interesting
[1:52] Let’s connect ground up as well
[1:55] There we go, so we have ground properly wired up
[2:01] So that’s our reconstructed audio signal
[2:18] What’s really interesting
[2:19] is that we can actually take the signal directly from pin 21
[2:24] So the raw PDM signal
[2:26] if we feed that straight into our amplifier
[2:30] we still get perfectly good audio
[2:46] So what’s happening here is the bandwidth of the analogue amplifier
[2:50] in this speaker
[2:52] is low enough that it’s filtering out all of the PDM noise
[2:56] and reconstructing our signal
[2:58] Now what’s really interesting as well
[3:00] is we can actually just drive headphones
[3:03] directly from the PDM signal
[3:05] So I’ve got some headphones here
[3:09] So let’s plug these cheap headphones in
[3:15] So what should happen is
[3:18] the headphones also have a limited bandwidth
[3:21] so the small speakers in the headphones
[3:23] can’t amplify the noise from the PDM signal
[3:28] So they’ll just filter out the audio signal
[3:30] So I’ll put this close to the microphone
[3:33] And hopefully that’s near enough the microphone that you can hear it
[3:38] And it’s surprisingly good quality
[3:47] Now what’s quite interesting as well
[3:50] I keep saying what’s quite interesting
[3:51] but it is all very interesting
[3:53] is how simple you can make an amplifier
[3:56] So if you think about class D amplifiers
[4:00] they’re just simple switches
[4:01] and they use a similar idea to the PDM signal
[4:05] where the speaker is just switched very quickly
[4:11] and you get sound generated
[4:13] So let’s hook up the ground wire for this
[4:17] And all I’ve got here is a MOSFET acting as a switch
[4:21] and it’s just switching this speaker on and off very quickly
[4:25] So pretty simple, not much going on there
[4:28] Let’s plug in the PDM signal directly to the gate of the MOSFET
[4:35] So there we go
[4:40] It’s reproducing the audio
[4:43] It’s not fantastic quality
[4:45] but it’s not really surprising
[4:46] This MOSFET is not a logic level MOSFET
[4:50] I’m actually surprised it works at all
[4:53] So that’s pretty good
[4:54] So now it feels like an opportune moment to mention PCBWay
[4:58] So I’ve got some new boards for them
[5:00] The ESP32-TV board version 3
[5:04] So I’ve just been testing these
[5:08] I fixed the previous mistake
[5:09] so now battery charging does work
[5:12] I’ve also fixed the issue where the USB controller
[5:15] is conflicting with the ESP32
[5:18] So that now works really well
[5:19] getting really good speeds on the SD card
[5:21] So that’s great
[5:24] I’m going to do a bit more testing
[5:25] Solder on the display and make sure that works
[5:29] But that should give us some really interesting results
[5:32] So let’s have a look at what’s going on under the hood
[5:34] So here’s our original waveform
[5:36] So let’s play that
[5:37] And I’ve plotted the spectrogram just for reference
[5:46] so we can see what that should look like
[5:48] So we’ll close this waveform
[5:50] And what I’ve done is I’ve simulated
[5:52] a delta sigma modulation of that waveform
[5:56] So we can have a look at this
[5:57] So this data up here, the blue data
[5:59] is all of the samples and they’re just going from -1 to 1
[6:03] Then underneath we have the spectrogram
[6:05] So I’ve currently got it set to go from 0 to 500 kHz
[6:09] because the sample rate of this signal is around 1 MHz
[6:12] So let’s change the spectrogram settings
[6:14] to just do up to 8 kHz
[6:16] So we’ll change this to 8 kHz
[6:21] And now if you look here
[6:22] you can see that right at the bottom of our spectrum
[6:25] we have the original signal
[6:26] So all we need to do to recover our original data
[6:29] is to low pass filter it
[6:30] So let’s do that
[6:33] So we’ll go here
[6:34] and we’ll go low pass filter
[6:36] and we’ll filter it at 8 kHz
[6:39] So let’s apply that
[6:41] And there we go
[6:42] We have our original signal recovered
[6:44] So let’s play this
[6:46] [music]
[6:57] So that’s pretty good
[6:58] We’ve managed to recover our original signal
[7:00] from the Delta Sigma modulated data
[7:03] So what’s quite interesting
[7:04] if I undo that low pass filter
[7:06] So we go back to our Delta Sigma modulated data
[7:10] and then hit play
[7:11] we actually can hear the original data as well
[7:14] [music]
[7:18] So what’s happening here
[7:19] is the audio system on my Mac
[7:21] can only play up to around 20 kHz maximum
[7:24] So all of the higher frequencies
[7:25] are being filtered out automatically
[7:27] So that’s pretty interesting
[7:29] I think it’s a very cool piece of technology
[7:31] So how do we actually do this in code?
[7:34] The documentation on the Espressif website
[7:36] is surprisingly good
[7:37] They’ve even got an example circuit
[7:39] for doing a low pass filter
[7:40] to recover the original signal
[7:42] It’s certainly more sophisticated
[7:44] than my simple RC filter
[7:46] They’ve got some example code
[7:47] for generating a 100 Hz sine wave
[7:49] Looking at this code
[7:50] we can see that they are using a timer
[7:52] to output the samples
[7:54] Now this is perfectly reasonable
[7:55] but it does mean that our code
[7:56] will be constantly interrupted
[7:58] to output a sample
[7:59] I have implemented this for outputting audio
[8:02] and it does work without any issues
[8:04] But wouldn’t it be nice
[8:05] if we could use the I2S peripheral
[8:07] to do all the heavy lifting
[8:09] Now the I2S peripheral does support PDM output
[8:12] but there’s a slight wrinkle
[8:14] It always outputs the right and left channel
[8:16] and wants to have a pin allocated
[8:18] to the clock signal
[8:19] Now my workaround for this
[8:20] is to just output the same value
[8:22] for both the left and the right samples
[8:24] That way we can just take the output
[8:26] of the I2S peripheral
[8:27] and treat it as a mono signal
[8:29] The only other slight annoyance
[8:30] is the clock signal
[8:32] In my experiments
[8:33] I just set this to an unused pin
[8:34] GPIO45 or 46 are quite good candidates for this
[8:38] as on the S3
[8:39] they can’t really be used for anything else
[8:41] GPIO0 could also be a good option
[8:44] Now you may be asking
[8:45] What took me on this path in the first place?
[8:47] Why did I start playing around with PDM output?
[8:50] Well I’ve been getting my TV code working
[8:52] on the TinyWATCH from Unexpected Maker
[8:55] This has a really small buzzer
[8:56] and a very simple driver circuit
[8:58] But in theory it should work with PDM data
[9:02] And it does
[9:02] It’s just very very quiet

HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi
Want to keep up to date with the latest posts and videos? Subscribe to the newsletter
Blog Logo

Chris Greening

> Image


A collection of slightly mad projects, instructive/educational videos, and generally interesting stuff. Building projects around the Arduino and ESP32 platforms - we'll be exploring AI, Computer Vision, Audio, 3D Printing - it may get a bit eclectic...

View All Posts