Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: PDM Microphone guidance/examples? Is PDM+I2S Possible?

  1. #1
    Junior Member
    Join Date
    Aug 2019
    Posts
    13

    PDM Microphone guidance/examples? Is PDM+I2S Possible?

    Hello again guys

    As I mentioned on a previous post, I am working on a project involving a PDM microphone pre-amplifier and a I2S UDA1334 decoder.

    For now, I would like to test the PDM processing part using an Adafruit PDM Microphone.

    My main issue right now is the lack of resources and examples of the usage of the library. I am using a Teensy 3.6 board.

    I cannot figure out how to get the signal from the microphone. There is no clear indication if it can only be used with the Audio adaptor board or if it possible to use a standalone Teensy.

    Here is what I've done so far:

    1. Using the audio design tool GUI I created the following sketch:


    Click image for larger version. 

Name:	GUIWiring_PDM-I2S.png 
Views:	9 
Size:	113.3 KB 
ID:	19551

    However, upon inspection of the wiring I believe that using PDM and I2S at the same time is NOT possible because they use the same pins (9 and 13 for PDM CLK/I2S BCLK and PDM DATA, respectively )

    When loading the following code the Teensy 3.6 does NOT register any keys pressed and it seems to be stuck in the filtering process. Perhaps this is due to my lack of understanding of how to use the PDM libary. Any hints?

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Bounce.h>
    
    #define MUTE_SOUND HIGH
    #define UNMUTE_SOUND LOW
    
    // GUItool: begin automatically generated code
    AudioInputPDM            pdm1;           //xy=242,248
    AudioOutputI2S           i2s1;           //xy=559,257
    AudioConnection          patchCord1(pdm1, 0, i2s1, 0);
    AudioConnection          patchCord2(pdm1, 0, i2s1, 1);
    // GUItool: end automatically generated code
    
    
    // Bounce objects to read six pushbuttons (pins 0-5)
    // I am only using two buttons as a test --> These will be used for increasing and decreasing a pointer
    Bounce button0 = Bounce(30, 10);
    Bounce button1 = Bounce(31, 10);  // 5 ms debounce time
    Bounce muteButton = Bounce(32, 10);  // 5 ms debounce time
    
    const int muteLED = 14;
    const int mutePin = 25;
    
    bool mutedFlag = false;
    
    
    void setup() {
    
     
      Serial.begin(115200);
      
      Serial.println("********* Initialising Audio I2S Moudule: UDA1334 ******************");
      Serial.println(" Asisgning pins...");
      // Configure the pushbutton pins for pullups.
      // Each button should connect from the pin to GND.
    
      pinMode(30, INPUT_PULLUP);
      pinMode(31, INPUT_PULLUP);
      pinMode(32, INPUT_PULLUP);
    
      pinMode(mutePin, OUTPUT);
      pinMode(muteLED, OUTPUT);
      
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      Serial.println(" Asisgning Audio Memory...");
      AudioMemory(50);
    
      digitalWrite(mutePin, UNMUTE_SOUND);
    
      pdm1.begin();
    
    }
    void loop() {
      
      pdm1.update();
      
      button0.update();
      button1.update();
      muteButton.update();
    
      if (button0.fallingEdge()) {
    
        Serial.println(" Button 0 pressed...");
    
      }
    
      if (button1.fallingEdge()) {
    
        Serial.println(" Button 1 pressed...");
    
      }
    
      if (muteButton.fallingEdge()) {
    
        if (mutedFlag == false) {
    
          digitalWriteFast(mutePin, MUTE_SOUND);
          Serial.println(" Muted Sound!");
          mutedFlag = true;
        } else {
    
          digitalWriteFast(mutePin, UNMUTE_SOUND);
          Serial.println(" Unmuted Sound!");
          mutedFlag = false;
    
        }
      }
    
    }
    I have the feeling that this usage is NOT allowed.

    2. Then, I removed the I2S device trying to get something from the PDM microphone, however the library indicates that the AudioInputPDM object has no functions. Where can the data be read/accessed or viewed? What is Port Out 0 (according to the Audio Connections in the image attached below)?

    Click image for larger version. 

Name:	PDMObject.png 
Views:	4 
Size:	46.1 KB 
ID:	19556

    As you might see I am completely lost

    I would like to kindly ask you for further guidance on how to use this microphone as the information on PDM microphones+Teensy is scarce and there a re NO EXAMPLES available.

    Is it possible to test the PDM microphone using Teensy 3.6 as an Audio Device in my PC? Any other alternatives/resources?


    Thank you in advance

    Edit: added hyperlink to the microphone preamplifier (FAN3852) that I plan to use later on


    confined and confused dzalf

  2. #2
    Senior Member
    Join Date
    Feb 2017
    Posts
    403
    You should not be calling the PDM object's begin() an update() functions. That's handled by the audio library. Fix that and get rid of all your button handling code until you get the mic input to I2S output to work.

    What is the I2S output connected to? Teensey Audio Shield?

    What is 'mutePin' connected to?

  3. #3
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,499
    here is a sketch i used with https://www.adafruit.com/product/3492 hooked to T3.2, using 3v3, GND, DAT to pin 13, CLK to 9, SEL not connected.
    Code:
    #include <Audio.h>
    #define MICGAIN 100
    
    // GUItool: begin automatically generated code
    //AudioInputI2S i2s1;   // I2S mic
    AudioInputPDM i2s1;   // PDM
    AudioAnalyzePeak peak1;
    AudioAnalyzeRMS rms1;
    AudioConnection p1(i2s1, peak1);
    AudioConnection p2(i2s1, rms1);
    // GUItool: end automatically generated code
    
    
    void setup() {
      AudioMemory(4);
      Serial.begin(9600);
      while(!Serial);
      delay(5000);
      Serial.println("RMS peak");
    }
    
    void loop() {
      Serial.print(MICGAIN * rms1.read()); Serial.print(" ");
      Serial.println(MICGAIN * peak1.read());
      delay(5);
    }
    you can use IDE's SerialPlotter to view the data
    Last edited by manitou; 04-01-2020 at 01:53 PM.

  4. #4
    Junior Member
    Join Date
    Aug 2019
    Posts
    13
    Quote Originally Posted by gfvalvo View Post
    You should not be calling the PDM object's begin() an update() functions. That's handled by the audio library. Fix that and get rid of all your button handling code until you get the mic input to I2S output to work.

    What is the I2S output connected to? Teensey Audio Shield?

    What is 'mutePin' connected to?
    Dear gfvalvo

    Thank you for your kind response.

    I've removed the functions. Still nothing.

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    
    // GUItool: begin automatically generated code
    AudioInputPDM            pdm1;           //xy=182,235
    AudioOutputI2S           i2s1;           //xy=465,236
    AudioConnection          patchCord1(pdm1, 0, i2s1, 0);
    AudioConnection          patchCord2(pdm1, 0, i2s1, 1);
    // GUItool: end automatically generated code
    
    
    void setup() {
    
      AudioMemory(20); // Is this correct?
    
    
    }
    
    void loop() {
    
    
    }
    The I2S output is connected to a UDA1334 decoder. I am not using the Teensy audio shield since originally I planned to use the UDA1334. As I mentioned, I believe that I cannot get an audio input using this I2S device due to the common pins being used by the two devices (Microphone and I2S decoder).

    The mute pin was used in my previous circuit for testing the I2S device which works fine with the pinout I described there.

    Any other advice? Should I be using different pins for each device? What alternative pins are compatible with PDM devices and/or I2S on Teensy 3.6?


    As I understand, I should be getting audio signal out of my I2S without using any further instructions in my code. The library should be doing all the dirty work

    Thank you once again

    dzalf

  5. #5
    Senior Member
    Join Date
    Feb 2017
    Posts
    403
    I should work as-is with the BCLK supplied by the T3.6 (~2.8 MHz). The PDM object then filters the signal and provides the proper Audio Library sample stream to the following objects.

    If it were my project, I'd divide and conqueror. Get the mic input going first as in @manitou's sketch.

  6. #6
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,499
    Quote Originally Posted by dzalf View Post

    Any other advice? Should I be using different pins for each device? What alternative pins are compatible with PDM devices and/or I2S on Teensy 3.6?
    see post #3 to confirm PDM mic working.
    Last edited by manitou; 03-31-2020 at 10:33 PM.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,864
    Quote Originally Posted by dzalf View Post
    The I2S output is connected to a UDA1334 decoder.
    Have you tested your UDA1334, like with the synth-only examples like Synth > Guitar?

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,864
    Ah, looking at the code again (it's been quite a while since I wrote the PDM input code), it probably will not play nice with I2S output. To get the signal out, use Teensy 3.6's built in 12 bit DAC.

  9. #9
    Junior Member
    Join Date
    Aug 2019
    Posts
    13
    Quote Originally Posted by gfvalvo View Post
    I should work as-is with the BCLK supplied by the T3.6 (~2.8 MHz). The PDM object then filters the signal and provides the proper Audio Library sample stream to the following objects.

    If it were my project, I'd divide and conqueror. Get the mic input going first as in @manitou's sketch.
    Dear gfvalvo

    You are absolutely right and believe it or not this is exactly what I'm trying Perhaps it matter of the resolution (pun intended) from my divide and conquer approach.

    I tried to make some blocks work first but I've convinced myself that I really need to slow down and chop my project into smaller bits (:P ) for sure.

    This is only the tip of the iceberg(-ish) project I am working on at the moment (from which I cannot disclose further details due to IP related issues).

    I got it working now (I will share my results in my reply to manitou )

    Thank you very much for your help

    dzalf

  10. #10
    Junior Member
    Join Date
    Aug 2019
    Posts
    13
    Quote Originally Posted by manitou View Post
    see post #3 to confirm PDM mic working.
    Dear manitou

    You are da man!

    I got it working after using your guidance and Paul's advice (down here).

    For now, the solution is to forget about my I2S board and simply use the internal DACs from the T3.6.

    This is my code so far:


    Code:
    #include <Audio.h>
    #define MICGAIN 50
    
    // GUItool: begin automatically generated code
    AudioInputPDM            mic;            
    AudioOutputAnalogStereo  dacs1;         
    AudioConnection          patchCord1(mic, 0, dacs1, 1);
    AudioConnection          patchCord2(mic, 0, dacs1, 0);
    AudioAnalyzePeak peak1;
    AudioAnalyzeRMS rms1;
    AudioConnection p1(mic, peak1);
    AudioConnection p2(mic, rms1);
    // GUItool: end automatically generated code
    
    void setup() {
      AudioMemory(4);
      analogReference(INTERNAL);
      Serial.begin(9600);
    }
    
    void loop() {
      Serial.print(MICGAIN * rms1.read()); Serial.print(" ");
      Serial.println(MICGAIN * peak1.read());
      delay(5);
    }

    And the audio from the MIC is loud and clear (I still need to play around with some digital and analog filtering)

    Here an image of the "I love Teensy" waveform:

    Click image for larger version. 

Name:	IloveTeensyWaveform.png 
Views:	12 
Size:	36.5 KB 
ID:	19560


    Thank you VERY much for your help and be assured that I will come back very soon with more questions as these are my first steps with the Audio Design Tool

    Stay safe and keep in the loop!

    dzalf

  11. #11
    Junior Member
    Join Date
    Aug 2019
    Posts
    13
    Quote Originally Posted by PaulStoffregen View Post
    Have you tested your UDA1334, like with the synth-only examples like Synth > Guitar?
    Dear Paul

    Yes, I successfully tested the UDA1334 using the SamplePlayer example and the following pinout:

    Pin 9 (Teensy 3.6) to BCLK (UDA1334)
    Pin 22 (Teensy 3.6) to DIN (UDA1334)
    Pin 23 (Teensy 3.6) to WSEL (UDA1334)

    I also assigned a push button to mute the device and that's when I ran into issues, as I described here. The solution to that "white noise" was to filter the Mute Pin from the UDA1334 with a 10nF capacitor to GND (weird because I had no issues with Teensy 4.0)

    Following your advice from your second comment I used the DACs from T3.6 to test the Guitar synth and I can only say: Nice tune!

    I am now going to design my own amplification solution based on an unused LM4861M that I just found in my parts bin

    As I mentioned to manitou, I need to learn a lot from the forums and keep practicing with the Audio GUI as I am an absolute n00b using it

    Thank you for your kind help and more importantly for all the amazing effort and heart you've put on creating the Teensy ecosystem.

    Hats off to you!

    dzalf

  12. #12
    Junior Member
    Join Date
    Aug 2019
    Posts
    13
    Quote Originally Posted by PaulStoffregen View Post
    Ah, looking at the code again (it's been quite a while since I wrote the PDM input code), it probably will not play nice with I2S output. To get the signal out, use Teensy 3.6's built in 12 bit DAC.
    That's what I assumed.

    I've abandoned the idea (for now) of using the UDA1334 and I will be using the DACs from T3.6.

    This makes me wonder:

    Is it possible to extract a digital audio stream in case I want to use an external DAC? In case I want moar resolution...

    Cheers

    dzalf

  13. #13
    Senior Member
    Join Date
    Feb 2017
    Posts
    403
    Quote Originally Posted by dzalf View Post
    That's what I assumed.
    Is it possible to extract a digital audio stream in case I want to use an external DAC? In case I want moar resolution...
    A quick look at the code shows that the I2S RX hardware gets set up slightly differently by the AudioInputPDM class than by the AudioOutputI2S class (which configures both I2S TX and RX).

    It seems that it would be a fairly straight-forward task to create your own set of PDM-In / I2S-Out Audio Library classes using AudioInputPDM, AudioOutputI2S, and AudioInputI2S as guides. But, you'd have to dig into the details to know for sure.
    Last edited by gfvalvo; 04-01-2020 at 12:09 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •