Ever notice that the ESP32-S3 doesn’t have a digital-to-analog converter? [Chris] did and asserts that he doesn’t care because he can just use the PDM system to get the same result. PDM — pulse density modulation — is similar to PWM and, like PWM, requires a filter that could range from a simple RC network to an active filter. You can see the result in the video below.
There are several ways [Chris] could produce the output he wanted. PWM was one choice, and some example code uses a timer to do PDM. However, that is not very efficient. The other alternative is to use the I2S output. However, this does require a few workarounds.
In particular, the I2S output is always stereo and incorporates a clock output that isn’t needed for this application. [Chris] simply output the same value on both channels and routed the clock to some pins that are normally used for startup options. That means they can’t easily be used for your own inputs, but it’s OK to use them for unimportant outputs.
We always enjoy seeing solutions like this because it can give you ideas for use in your own projects. Of course, this won’t apply to every project where you need a DAC, but it still might give you some ideas.
We have looked at PDM before. You could, too, build your own DAC hardware.
PDM on the ESP8266.
https://www.hackster.io/janost/audio-hacking-on-the-esp8266-fa9464
PDM is really amazing and not enough people exploit it. In essence it’s like a one-dimensional line drawing algorithm. For example, let’s say we have a 16-bit fractional value we want to turn into a PDM bitstream. We just need to add the fractional value to a sum and if there’s a carry, we set the bit:
short gTotal;
void Pdm(short aFrac)
{
long total=gTotal+aFrac;
digitalWrite(kPin, (total>>16)&1); // nasty magic numbers!
gTotal=total&0xffff;
}
I implemented a PDM (called SmoothPWM) for the very ancient HandyBoard robot in the late 1990s. The PWM API specified 100 levels, but the firmware truncated it to 8 PWM levels and a friend of mine wanted to have finer motor control for a robot. It only took a few 68HC11 assembler instructions to generate 4 PDM outputs with an 8-bit resolution. There’s still a few references to it:
https://www.cs.uml.edu/~fredm/handyboard.com/oldhb/software/contrib.html
Oops, I should really have used uint16_t instead of short and uint32_t for long.
If you want 16 bit resolution at only 1kHz, that’s already 65.536.000 interrupts per second, where you have to execute the code you posted. I don’t ze that happening.
If you’d do this on an FPGA, generating a PWM signal or PDM signal would have about the same complexity.
In many cases, if you don’t have dedicated hardware to generate the signal, you’re probably better off using PWM instead.
One big advantage of PDM is that the pulse frequency is much higher, which means it’s easier to build a simple filter to get a reasonable reconstruction of the original signal.
No its not. Its 32x oversampling.
Here is 16 bit at 44.1 or even 96KHz:
https://www.hackster.io/janost/audio-hacking-on-the-esp8266-fa9464
which is basically a first order deltasigma modulator
Yes.
ESP32S3 I2S peripheral has hardware implementation of PCM-to-PDM conversion, which this example uses.
PDM modulation can also be implemented in software, but it tends to be a bit demanding on CPU due to the noise shaping algorithm required. For microcontrollers without hardware PDM, dithered PWM or external DAC is usually a more fitting choice.
There is a Arduino API compatible GitHub-Repository from Early Hill Power which uses this principle since several years:
https://github.com/earlephilhower/ESP8266Audio/tree/master
From the description:
“The software I2S delta-sigma 32x oversampling DAC was my own creation, and sounds quite good if I do say so myself.”
If you implement PWM digitally and you reverse the bits either on the datum or the counter, you get something similar to PDM.
IMHO every PWM unit should implement this fake PDM, as it has preferable properties for applications other than power electronics.
Just as an example:16bit PWM is common, but not really usable for most DAC applications. With PDM or fake PDM, it gets way easier to filter.
Having that said. With DMA magic, you can implement something like this with your SPI peripheral…. Just prepare some bytes and let the 40MHz SPI unit output this as a continuous stream…
73
Another episode of “a DAC and a low-pass filter are kind of the same thing for a given fidelity.”
we had 1bit PDM cd players in the 90s and they were kinda awful sounding.
prety much all audio adc and dacs are now deltasigma, which is basically pdm
Old-timers like me, always enjoy seeing young people reinventing the wheel!
In ’61, Apollo’s AGC used this system to measure analog data from LEM, Saturn and capsule sensors.
OK, this is interesting, so how were PDM techniques used to perform what appears to be the opposite operation: an ADC?
https://hackaday.com/wp-content/uploads/2016/06/modulator.png