Using I2S microphone and Output at the same time with Teensy 4.1.

I am trying to use a trendy 4.1 to take the input of two microphones and send the combined signals to a speaker. I thought that I2S would be the best protocol for both the inputs and output because of the teensy audio library's I2SQuad function but when I try and use my I2S microphone (Adafruit I2S MEMS Microphone Breakout - SPH0645LM4H) with my I2S amp (Adafruit I2S 3W Class D Amplifier Breakout - MAX98357A) only the microphone works, until I disconnect it's clock pins and then the amp begins to work, even though I am using I2S1 for the microphone and I2S2 for the amp so the clocks should be independent from one another. How can I fix this, should I use different microphones/amps?

Thank you for any response in advance.
 
Please post a short code example demonstrating the issue, and a picture or diagram so we can see your exact wiring. We’re much more likely to be able to spot what’s wrong with that available.

From your description, there’s no real need to use both I2S busses, but it should work.
 
Please post a short code example demonstrating the issue, and a picture or diagram so we can see your exact wiring. We’re much more likely to be able to spot what’s wrong with that available.

From your description, there’s no real need to use both I2S busses, but it should work.
This is my code:

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

// GUItool: begin automatically generated code
AudioInputI2S            i2s1;           //xy=186.1999969482422,188
AudioSynthWaveform       waveform1;      //xy=255.1999969482422,310
AudioFilterStateVariable filter1;        //xy=321.1999969482422,190
AudioMixer4              mixer1;         //xy=461.1999969482422,251
AudioAmplifier           amp1;           //xy=601.1999969482422,257
AudioAnalyzeFFT1024      fft1024_1;      //xy=707.1999969482422,182
AudioOutputI2S2          i2s2_1;         //xy=753.2000122070312,258.20001220703125
AudioConnection          patchCord1(i2s1, 0, filter1, 0);
AudioConnection          patchCord2(i2s1, 1, filter1, 1);
AudioConnection          patchCord3(waveform1, 0, mixer1, 1);
AudioConnection          patchCord4(filter1, 2, mixer1, 0);
AudioConnection          patchCord5(mixer1, amp1);
AudioConnection          patchCord6(mixer1, fft1024_1);
AudioConnection          patchCord7(amp1, 0, i2s2_1, 0);
AudioConnection          patchCord8(amp1, 0, i2s2_1, 1);
// GUItool: end automatically generated code









const int SDCard = BUILTIN_SDCARD;

const float maxVol = 0.3;


void setup() {
  AudioMemory(50);
  filter1.frequency(30); // filter out DC & extremely low frequencies
  mixer1.gain(0, 8.5);   // amplify sign to useful range
  mixer1.gain(1, 1);   

  waveform1.begin(1, 440, WAVEFORM_SINE);

  Serial.begin(38400);
  while (!Serial) {
    ; // wait for serial port to connect.
  }
  Serial.println("Serial connection established.");

  if(!SD.begin(SDCard)){
    Serial.println("SD Card Failed to Initalise!");
    while (1) {
      // No SD card, so don't do anything more - stay stuck here
    }
  }
  Serial.println("SD Card Initalised!");

  amp1.gain(maxVol);

  /* Play the WAV file
  if (!playSdWav1.play("output.wav")) {
    Serial.println("Failed to play WAV file!");
    return;
  }
  Serial.println("Playing WAV file...");
  delay(100); //Delay to stop the next if statemnt from running before playing starts
  */
}

void loop() {
  if (fft1024_1.available()) {
    // each time new FFT data is available
    // print 20 bins to the Arduino Serial Monitor
    Serial.print("FFT: ");
    for (int i = 0; i < 20; i++) {
      float n = fft1024_1.read(i);
      if (n >= 0.001) {
        Serial.print(n, 3);
        Serial.print(" ");
      } else {
        Serial.print("  --  "); // don't print "0.000"
      }
    }
    Serial.println();
  }
}

And I have attached a diagram of my wiring.
 

Attachments

  • Teensy 4.1 ANC Wiring.png
    Teensy 4.1 ANC Wiring.png
    285.4 KB · Views: 31
This looks wrong:
C++:
AudioConnection patchCord2(i2s1, 1, filter1, 1);
That connects a microphone to the cutoff frequency control input of the filter, which is unlikely to be what you intended. (Your diagram doesn’t actually show a second microphone, though your original post says it’s there.)

To eliminate hardware issues, do you hear your 440Hz reference tone on the speaker with all physical connections made but the software ones to the microphone commented out, thus:
C++:
// AudioConnection          patchCord1(i2s1, 0, filter1, 0);
// AudioConnection          patchCord2(i2s1, 1, filter1, 1);
 
This looks wrong:
C++:
AudioConnection patchCord2(i2s1, 1, filter1, 1);
That connects a microphone to the cutoff frequency control input of the filter, which is unlikely to be what you intended. (Your diagram doesn’t actually show a second microphone, though your original post says it’s there.)

To eliminate hardware issues, do you hear your 440Hz reference tone on the speaker with all physical connections made but the software ones to the microphone commented out, thus:
C++:
// AudioConnection          patchCord1(i2s1, 0, filter1, 0);
// AudioConnection          patchCord2(i2s1, 1, filter1, 1);
Thanks for the response, you are right I did not mean to connect the microphone to the cutoff frequency control input of the filter. When I comment out the connection between the i2s input and the mixer as suggested I don't hear anything through my speaker however when I also comment out the initialisation of the i2s input I do hear the reference tone through my speaker, so I believe the hardware works. I also tested the microphone, when the i2s output is commented out the microphone works fine. As for why I haven't wired up two microphone it's because I currently can't even get one to work with the i2s output. I have attached the altered code with the commented out sections to show how I tested the speaker.

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

// GUItool: begin automatically generated code
//AudioInputI2S            i2s1;           //xy=154.1999969482422,237
AudioSynthWaveform       waveform1;      //xy=223.1999969482422,359
//AudioFilterStateVariable filter1;        //xy=289.1999969482422,239
AudioMixer4              mixer1;         //xy=429.1999969482422,300
AudioAmplifier           amp1;           //xy=569.1999969482422,306
AudioAnalyzeFFT1024      fft1024_1;      //xy=675.1999969482422,231
AudioOutputI2S2          i2s2_1;         //xy=721.1999969482422,307
//AudioConnection          patchCord1(i2s1, 0, filter1, 0);
AudioConnection          patchCord2(waveform1, 0, mixer1, 1);
//AudioConnection          patchCord3(filter1, 2, mixer1, 0);
AudioConnection          patchCord4(mixer1, amp1);
AudioConnection          patchCord5(mixer1, fft1024_1);
AudioConnection          patchCord8(amp1, 0, i2s2_1, 0);
AudioConnection          patchCord9(amp1, 0, i2s2_1, 1);
// GUItool: end automatically generated code




const int SDCard = BUILTIN_SDCARD;

const float maxVol = 0.3;


void setup() {
  AudioMemory(50);
  //filter1.frequency(30); // filter out DC & extremely low frequencies
  mixer1.gain(0, 8.5);   // amplify sign to useful range
  mixer1.gain(1, 1);  

  waveform1.begin(1, 440, WAVEFORM_SINE);

  Serial.begin(38400);
  while (!Serial) {
    ; // wait for serial port to connect.
  }
  Serial.println("Serial connection established.");

  if(!SD.begin(SDCard)){
    Serial.println("SD Card Failed to Initalise!");
    while (1) {
      // No SD card, so don't do anything more - stay stuck here
    }
  }
  Serial.println("SD Card Initalised!");

  amp1.gain(maxVol);

  /* Play the WAV file
  if (!playSdWav1.play("output.wav")) {
    Serial.println("Failed to play WAV file!");
    return;
  }
  Serial.println("Playing WAV file...");
  delay(100); //Delay to stop the next if statemnt from running before playing starts
  */
}

void loop() {
  if (fft1024_1.available()) {
    // each time new FFT data is available
    // print 20 bins to the Arduino Serial Monitor
    Serial.print("FFT: ");
    for (int i = 0; i < 20; i++) {
      float n = fft1024_1.read(i);
      if (n >= 0.001) {
        Serial.print(n, 3);
        Serial.print(" ");
      } else {
        Serial.print("  --  "); // don't print "0.000"
      }
    }
    Serial.println();
  }
}
 
Two quick things ... gotta go AFK for a bit ...
  • supplying the speaker amp from the Teensy 3.3V probably isn't great, it might overwhelm the regulator. Try the 5V (check, but I think it'll take it ... but be sure NOT to let 5V get back to a Teensy I/O pin, that'll kill it!)
  • I can't use exactly your connections, but I could do a quick test with AudioInputI2S2 as the input and AudioOutputI2S as the output. Nothing connected to the input, but the output was working fine. So you could perhaps do a quick try with the hardware and software swapped around
 
Two quick things ... gotta go AFK for a bit ...
  • supplying the speaker amp from the Teensy 3.3V probably isn't great, it might overwhelm the regulator. Try the 5V (check, but I think it'll take it ... but be sure NOT to let 5V get back to a Teensy I/O pin, that'll kill it!)
  • I can't use exactly your connections, but I could do a quick test with AudioInputI2S2 as the input and AudioOutputI2S as the output. Nothing connected to the input, but the output was working fine. So you could perhaps do a quick try with the hardware and software swapped around
This worked perfectly, thank you so much for your help.
 
Back
Top