Teensy 4 PDM Audio Input

Status
Not open for further replies.

Sanworks

Member
Hi all,

I'm trying to interface a PDM microphone with T4, using the Audio System Design Tool.
I linked the PDM input with the 'queue' class. The resulting code compiles for T3.6, but for T4 it produces an error.

Here's the code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputPDM            pdm1;           //xy=109,145
AudioRecordQueue         queue1;         //xy=273,143
AudioConnection          patchCord1(pdm1, queue1);
// GUItool: end automatically generated code

void setup() {
  
}

void loop() {
  
}

And here's the error:

C:\...\Temp\arduino_build_881909\sketch\MicTest.ino.cpp.o: In function `AudioInputPDM::AudioInputPDM()':

C:\...\arduino-1.8.10\hardware\teensy\avr\libraries\Audio/input_pdm.h:37: undefined reference to `AudioInputPDM::begin()'

C:\...\AppData\Local\Temp\arduino_build_881909\sketch\MicTest.ino.cpp.o: In function `AudioStream::AudioStream(unsigned char, audio_block_struct**)':

C:\...\arduino-1.8.10\hardware\teensy\avr\cores\teensy4/AudioStream.h:130: undefined reference to `vtable for AudioInputPDM'

collect2.exe: error: ld returned 1 exit status

I'm using Arduino 1.8.10 and Teensyduino 1.48.
Is PDM support not yet available on T4? Or do I have something misconfigured?

Thanks!
 
Any luck?

Hi all,

I'm trying to interface a PDM microphone with T4, using the Audio System Design Tool.
I linked the PDM input with the 'queue' class. The resulting code compiles for T3.6, but for T4 it produces an error.

Here's the code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputPDM            pdm1;           //xy=109,145
AudioRecordQueue         queue1;         //xy=273,143
AudioConnection          patchCord1(pdm1, queue1);
// GUItool: end automatically generated code

void setup() {
  
}

void loop() {
  
}

And here's the error:

C:\...\Temp\arduino_build_881909\sketch\MicTest.ino.cpp.o: In function `AudioInputPDM::AudioInputPDM()':

C:\...\arduino-1.8.10\hardware\teensy\avr\libraries\Audio/input_pdm.h:37: undefined reference to `AudioInputPDM::begin()'

C:\...\AppData\Local\Temp\arduino_build_881909\sketch\MicTest.ino.cpp.o: In function `AudioStream::AudioStream(unsigned char, audio_block_struct**)':

C:\...\arduino-1.8.10\hardware\teensy\avr\cores\teensy4/AudioStream.h:130: undefined reference to `vtable for AudioInputPDM'

collect2.exe: error: ld returned 1 exit status

I'm using Arduino 1.8.10 and Teensyduino 1.48.
Is PDM support not yet available on T4? Or do I have something misconfigured?

Thanks!



My apologies for reviving this topic. Did you have any luck with Teensy 4.0 and the PDM library support?


I am currently working on a project that involves a PDM preamplifier and I am a bit lost due to the lack of info regarding the connections and library usage.

Cheers

dzalf
 
I've been looking at PDM recently. No the audio library doesn't support T4 for PDM yet (if you look in the sources
its clearly ifdef'd out for T4. It would need the low level code for configuring the I2S hardware to output a 2.8MHz
clock ported to the T4 processor, and for DMA'ing in the data.

I think this is best left to someone with the relevant knowledge to get round to, though I might have a go myself
if I can find my way round the 3 thousand page datasheet without brain meltdown!
 
I have a pull-request for adding T4 support to AudioInputPDM: https://github.com/PaulStoffregen/Audio/pull/387

You only need to patch one file for testing, input_pdm.cpp

In the end the existing code for I2S was fairly easy to tailor to PDM by inspecting the differences for KINETISK version
and adding the necessary cache-flush call.

The processor overhead for PDM is much less objectionable on the T4, even at 150MHz, and it may work even at 24MHz
(although I think running an FFT at the same time overloaded it).
 
BTW it strikes me that on the T4 you could move PDM to the secondary I2S pins to avoid conflicting with the audio shield,
but I'm not sure how to reconfigure all the registers for this. Paul??
 
I'd like to ask everyone who wants me to work on this a question.

Which PDM microphone or chip are you using?


(hint: I'm more motivated by seeing photos...)
 
Thats a great question - whatever the Adafruit PDM module uses - they don't seem to say, although theres a
good bet its the MP34DT01-M as that's referenced in a few places alongside that module, and it has the same
left/right select control.

I first checked it was functioning with a T3.2 then had a bash at using the T4 - and of course trying a few
other approaches to decimation along the way (more on that at a later date perhaps).
 
AdaF NRF Sense unit uses : PDM Microphone sound sensor: MP34DT01-M - PDM sound sensor.
sensors_Feather_Sense_pinouts_PDM_mic.png

And their adafruit-clue - uses the same Mic.

They link to Arduino lib arduino.cc/en/Reference/PDM that mentions "such as the on board MP34DT05 on the Arduino Nano 33 BLE Sense : and this page says :
Code:
The MP34DT05-A sensor on the Arduino Nano 33 BLE Sense can be accessed through the PDM library and the Arduino Sound library, which uses the PDM library in the background

AdaF has general notes on other breakouts - where they don't name the part - like they are standard 3.3V taking a clock and returning a PWM value like bit stream: adafruit-pdm-microphone-breakout?view=all
 
And another observation I have - I'm not sure the PDM code has to be incompatible with I2S output on the same I2S unit, as the
clocking is the same. I might have a look at making this work, so that it works more like I2S input, calling AudioOutputI2S::config_i2s()
and then tweaking a few things.

And having spent a few hours looking at the manual I might also have a stab and making PDM work on I2S2 unit on T4 too. Found
it very confusing that the BCLK/LRCLK are driven differently on I2S1 and I2S2...
 
Thought I'd pop my RF spectrum analyzer on a PDM signal from one of these microphones to see what sort of
noise shaping they have - 3 plots zooming in on the audio band, with full-scales of 5MHz, 2MHz and 20kHz
pdm_spectrum3.png
pdm_spectrum2.png
pdm_spectrum1.png
[ The peak in the last plot is me whistling at the mic ]

Interestingly the two peaks at half-Nyquist spread into a wide band if there's significant sound levels at the mic -
the two peaks when its quiet suggest limit-cycles of some sort I think, which is what you'd expect from a sigma-delta
modulator I guess.

Anyway it shows pretty good shaping of the quantization noise out of the audio band.

In fact its pretty quiet up to around 50--70kHz, suggesting a more relaxed cutoff for a decimation filter might
be OK (if you don't mind bat calls aliasing down to the audible range).
 
I'll admit, I've sometimes wondered if the 512 tap FIR filter was really a good idea. I wrote the code more as a challenge to see if Teensy could implement such an extreme filter rather than a careful plan. The impulse response came from a free web-based filter tool, which may not be truly correct (the tool probably was never well tested for such long filters).
 
I'll admit, I've sometimes wondered if the 512 tap FIR filter was really a good idea. I wrote the code more as a challenge to see if Teensy could implement such an extreme filter rather than a careful plan. The impulse response came from a free web-based filter tool, which may not be truly correct (the tool probably was never well tested for such long filters).

Well I've experimented with CIC cascades and multi-state decimation and don't seem to get any speed advantage, though
some space advantage. CIC cascading can be optimized by table lookup it turns out, to about the same throughput as
the existing 512 tap filter.

BTW strongly recommend Pyrhon's scipy.signal package for digital filtering tinkering.
 
Dear Community,
i get the same compiling error as the thread starter in first post.
is there already a solution? If i read correctly the work is still going on? - is it?
i am using a different chip ( not MP34DT01-M or MP34DT05-A) but the base problem is the pdm library with the T4.x, - right?
I would be happy to receive the latest information.

Many greetings.
 
i get the same compiling error as the thread starter in first post.
is there already a solution?

Yes, there is a solution. All you need to do is use a recent beta version, because PDM support for Teensy 4.x was added after 1.53 was released.

Get it here:
https://forum.pjrc.com/threads/66357-Teensyduino-1-54-Beta-7


If i read correctly the work is still going on? - is it?

No, not really. The PDM input code we have now isn't expected to change much.

But if you or anyone else wants to fiddle with the filter response, you could create a text file with your desired 512 tap impulse response and run the perl script (found in the code comments) to generate a different filter table. If someone happens to create a filter response that works better than the one we have now, I'd be happy to replace the existing table. But then again, what is considered "better" may not be so clear & easy to hear. The filter we have now seems to work pretty well. The memory consumed isn't a big issue on Teensy 4.


but the base problem is the pdm library with the T4.x, - right?

The base problem is simply using a version of the software from before this code was adapted to work on Teensy 4.x.

Admittedly, the normal ~3 month software release schedule has fallen far behind (currently about 9 months) during the pandemic & PJRC's labor shortage due to social distancing. In normal times, we would have released 1.55 by now. But the reality today is we still have 1.53 from last summer as the latest non-beta release.

So to use PDM with Teensy 4.x, until 1.54 releases, you need to use a beta version to get PDM support.



i am using a different chip ( not MP34DT01-M or MP34DT05-A)

Can you tell us the part number? Is it IM69D130?
 
Yes, there is a solution. All you need to do is use a recent beta version, because PDM support for Teensy 4.x was added after 1.53 was released.

Get it here:
https://forum.pjrc.com/threads/66357-Teensyduino-1-54-Beta-7




No, not really. The PDM input code we have now isn't expected to change much.

But if you or anyone else wants to fiddle with the filter response, you could create a text file with your desired 512 tap impulse response and run the perl script (found in the code comments) to generate a different filter table. If someone happens to create a filter response that works better than the one we have now, I'd be happy to replace the existing table. But then again, what is considered "better" may not be so clear & easy to hear. The filter we have now seems to work pretty well. The memory consumed isn't a big issue on Teensy 4.




The base problem is simply using a version of the software from before this code was adapted to work on Teensy 4.x.

Admittedly, the normal ~3 month software release schedule has fallen far behind (currently about 9 months) during the pandemic & PJRC's labor shortage due to social distancing. In normal times, we would have released 1.55 by now. But the reality today is we still have 1.53 from last summer as the latest non-beta release.

So to use PDM with Teensy 4.x, until 1.54 releases, you need to use a beta version to get PDM support.





Can you tell us the part number? Is it IM69D130?



Many thanks,
with the 1.5.4#7 compiled well.
should i connect T4 to Pin9 and Pin13 like the T3?
 
Compiled but seems not working

Many thanks,
with the 1.5.4#7 compiled well.
should i connect T4 to Pin9 and Pin13 like the T3?

Did you figure out which pins to connect with?

I am using the following code to test the PDM microphone on Teensy 4.0. I tried two different connections: CLK-pin9,DAT-pin13/CLK-pin9,DAT-pin8. The code compiled fine but the sensor does not seems to work, it gives flat line when viewing on serial plotter. I also tested the same microphone, same code on a teensy 3.6 and it works perfectly. Anyone has made it work?

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically genverated code
AudioInputPDM            pdm1;           //xy=232,306
AudioAnalyzePeak         peak1;          //xy=567,257
AudioAnalyzeRMS          rms1;           //xy=588,334
AudioConnection          patchCord1(pdm1, peak1);
AudioConnection          patchCord2(pdm1, rms1);
// GUItool: end automatically generated code


void setup() {
  AudioMemory(4);
//  analogReference(INTERNAL);
  Serial.begin(9600);
}

void loop() {
  Serial.print(rms1.read()); Serial.print(" ");
  Serial.println(peak1.read());
  delay(5);
}
 
For T4.x its clk=21, data=8, as documented in the version of the audio design tool in the beta version.
(gui/index.html relative to the Audio library root).
 
Thank you so much!! It works now. I have another question: is that possible to connect two PDM microphones on the T4?
 
is that possible to connect two PDM microphones on the T4?

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).
 
Status
Not open for further replies.
Back
Top