Ultrasonic PDM Input on Teensy 4.0

alextouss

Member
Hello,

I'd like to connect three PDM microphones in ultrasonic mode ( SPH0641LU4H-1) to a Teensy 4.0 at ~4.8Mhz, and then run a 4-taps IIR filter on the raw PDM bits to get the signal in the range I need. I'm currently looking for the easiest/best way to do it.

I see three options from my point of view :
- Abuse the I2S hardware as in the audio library. Only problem is the only resource I could find was an answer from PaulStoffregen in this thread, and the source code makes it look like the I2S hardware is hard to use. I'm also unsure about whether it would support a 4.8Mhz clock.
With the software that exists today, no. It only supports one PDM input.

But if your idea of "possible" includes editing the low-level code in the library, then theoretically up to 5 PDM inputs should be possible. The existing code could be reused with some minor changes to work on I2S2, which is nearly identical hardware to I2S1. That would give a 2nd input.

The I2S1 hardware can actually use 5 data pins, where 3 can be either input or output. So with more work on the code, theoretically a 4 channel PDM input could be made, similar to how the 8 channel I2S input works.

I believe Teensy 4 is probably fast enough to run 5 instances of the PDM 512 tap low pass FIR filter and leave plenty of CPU time left over for audio processing. But that's an assumption which should be carefully checked (by anyone who might try to make these changes).
- Bit bang by using polling.
- Bit bang with interrupts and Timers.

Would anyone have any cues as to what road I should take ? I'm quite comfortable with C, embedded development and have an FPGA programming background but I don't know the MCU's datasheet by heart.

Thank you,
Alex
 
I would have thought the best approach was to create a modified version of the pdm input class (which supports 2.8235MHz), however this device isn't running at a power-of-two multiple of 44.1kHz...
 
I would have thought the best approach was to create a modified version of the pdm input class (which supports 2.8235MHz), however this device isn't running at a power-of-two multiple of 44.1kHz...
Yeah, I guess that my use case is too far from the existing pdm input class to make use of it :/. Anyone else have a cue on the bit-bang alternatives?
 
Don't go down the bitbang path. At nearly 3 MHz, you'll consume the CPU, especially if entering and exiting an interrupt at that rate. You will need as much CPU time as you can get for 3 filters!

Your best path is to use the I2S hardware. Look at AudioInputI2SHex in the audio library. It's meant to bring in 6 normal audio channels on 3 data pins. You would basically repurpose this 6 channel I2S code to bring in 3 PDM bitstreams, just like the exiting PDM code uses 1 normally stereo I2S input pin to bring in 1 PDM bitstream.

Do you have a plan for the filters? I see that datasheet gives a frequency response on page 7, but I didn't see any info about the filter algorithm they used to achieve that result.

If you manage to get this working, I hope you'll share the code or at least some info and performance results?
 
Last edited:
IIR filters can do with a few taps what FIRs need hundreds of taps to do. If you want to prototype some filter design, I really suggest to try PyFDA, which is easy to use yet very powerful. The only problem is that IIRs require floating point math to avoid quantization-induced instability, but that shouldn't be an issue with the Teensy's FPU, so I guess that the three filters will be super easy to do.

Here's what a typical audio band filter would look like with an IIR, with just four taps. -125db at 1Mhz should already be enough to filter sigma-delta noise.
Screenshot from 2024-10-09 10-31-55.png

That [PDM in -> array of floats] part of my work isn't sensitive so I can share the code and performance results.

I get the idea behind repurposing the six-channel I2S hardware as three PDM inputs. But wouldn't that only work at 2x1,4112 MHz? The SPH Ultrasonic microphone works at up to 4.8MHz, and I'd like to use it at that frequency.
Don't go down the bitbang path. At nearly 3 MHz, you'll consume the CPU, especially if entering and exiting an interrupt at that rate. You will need as much CPU time as you can get for 3 filters!
Wouldn't reading the registers and doing ~20 float operations at 4.8MHz work on a 600MHz MCU?

Thank you,
 
I get the idea behind repurposing the six-channel I2S hardware as three PDM inputs. But wouldn't that only work at 2x1,4112 MHz?

The I2S hardware is very configurable, and so is the PLL which generates the main audio clock. You'll need to read the reference manual and probably do some fiddling to get the bitrate you want. But the I2S hardware definitely can do 11.3 MBit/sec for TDM protocol, so I'm pretty sure you can achieve 4.8 Mbit/sec.
 
Perfect, that's what I needed to get started, thank you. I'm designing the hardware, and will let you know once I'm onto the firmware!
 
If you're purposely trying to learn how to do PDM inputs directly to the Teensy, then developing this whole new method sounds like fun! Go for it!

But, if your goal is simply to use PDM in any way that is easy, it would probably be easier to use an audio codec chip that is built to receive daya from PDM mics. With this approach, you'd use the existing I2S objects in the Teensy Audio Library to talk to the codec chip...and then the codec chip would then talk PDM to the mic. This is how PDM + I2S are supposed to be used. So, with this approach, there would be much less hacking of the software than if you pursue the idea of forcing the Teensy's I2S interface to directly read PDM.

To use an audio codec chip to read PDM, you first need to find one that's easy to use with Teensy. The easiest to use is the Teensy Audio Adapter that Paul makes. Sadly, I don't think that it reads from PDM mics. Dang.

There are other audio codecs out there, though. The Tympan does PDM, for example. (Note: I'm associated with Tympan). The Tympan is a Teensy 4.1 at its heart plus it includes an audio codec and a Bluetooth chip. You program it as if it is a Teensy 4.1 (because it is a Teeny 4.1). To get access to its audio features, you use the Tympan Library, which is an extension of the Teensy Audio library. With the Tympan hardware and software, I've used PDM mics at 96kHz and done some fun modulation and demodulation of complex ultrasound signals.


As a yet another idea, be aware that you don't have to use that one PDM mic that you found. Many (most?) MEMS mics do ultrasound, even if they don't advertise for it. You can even use MEMS analog mics for ultrasound, which might be even easier. Tympan has two analog mics built-in and we later found that they worked fine to sense ultrasound. Or, you can buy some analog MEMS mics from Adafruit. (Or, she even has a MEMS mic that directly talks I2S without needing an interface chip ...which would be nice and simple, though i don't know if its built-in I2S goes up to ultrasonic speeds)

Regardless, you have many ultrasonic options available to you, even though few products talk about it.

Chip
 
Last edited:
Back
Top