Teensy 4.1 with I2s stereo microphone

Status
Not open for further replies.

FelixWZ

Member
Hello guys,

I have some issues with sampling the I2S microphone ( without the shield ) by T4.1.
The microphone that I'm using is:
pic.JPG


The pin is connected:
mic board -> T4.1
WCLK -> 20
SCLK -> 21
Data -> 8

I hade try to run the next code to sample and do fft on the signal, found the code in this forum. Not working for me. all the value i got from the code are static without changes

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputI2S i2s1; //xy=139,91
AudioAnalyzeFFT1024 fft1024; //xy=467,147

// Create Audio connections between the components
//
AudioConnection c2(i2s1, 0, fft1024, 0);
// GUItool: end automatically generated code



// The scale sets how much sound is needed in each frequency range to
// show all 8 bars. Higher numbers are more sensitive.
float scale = 60.0;

// An array to hold the 16 frequency bands
float level[16];

// This array holds the on-screen levels. When the signal drops quickly,
// these are used to lower the on-screen level 1 bar per update, which
// looks more pleasing to corresponds to human sound perception.
int shown[16];



void setup() {
delay(200);
Serial.println("Start Setup");
// Audio requires memory to work.
AudioMemory(12);
//i2s1.begin();
fft1024.windowFunction(AudioWindowHanning1024);
Serial.println("End Setup");
}


void loop() {
if (fft1024.available()) {
// read the 512 FFT frequencies into 16 levels
// music is heard in octaves, but the FFT data
// is linear, so for the higher octaves, read
// many FFT bins together.
level[0] = fft1024.read(0);
level[1] = fft1024.read(1);
level[2] = fft1024.read(2, 3);
level[3] = fft1024.read(4, 6);
level[4] = fft1024.read(7, 10);
level[5] = fft1024.read(11, 15);
level[6] = fft1024.read(16, 22);
level[7] = fft1024.read(23, 32);
level[8] = fft1024.read(33, 46);
level[9] = fft1024.read(47, 66);
level[10] = fft1024.read(67, 93);
level[11] = fft1024.read(94, 131);
level[12] = fft1024.read(132, 184);
level[13] = fft1024.read(185, 257);
level[14] = fft1024.read(258, 359);
level[15] = fft1024.read(360, 511);
// See this conversation to change this to more or less than 16 log-scaled bands?
// https://forum.pjrc.com/threads/3267...-for-FFT-bin-selection-for-any-given-of-bands

// if you have the volume pot soldered to your audio shield
// uncomment this line to make it adjust the full scale signal
//scale = 8.0 + analogRead(A1) / 5.0;


for (int i=0; i<16; i++) {
Serial.print(level);

// TODO: conversion from FFT data to display bars should be
// exponentially scaled. But how keep it a simple example?
int val = level * scale;
if (val > 8) val = 8;

if (val >= shown) {
shown = val;
} else {
if (shown > 0) shown = shown - 1;
val = shown;
}

//Serial.print(shown);
Serial.print(" ");
}
Serial.println("");
}
}



Can anyone guide me to the right solution?
In the first step, I want to sample this microphone and print every sample on the serial monitor.

Is there any guide for the Audio\I2S lib, I want to manage the Bclock freq and more. like sample 8 of the same mics?

Thanks
Felix
 
Looks like the "Shield2Go" part is really a ADAU7002 chip which converts PDM to I2S. It also has a 1.8V regulator and 1.8V to 3.3V level shifters.

Really looks like this should work. The wiring you described looks right. Can you show us photos of how it's actually connected to Teensy?
 
Hi Poul!, Thanks for Helping me!!
Her's the Pics
STGW.JPG
TW.JPG

I'm also generating the next code, also without success:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputI2S i2s1; //xy=184,226
AudioOutputUSB usb1; //xy=391,234
AudioConnection patchCord1(i2s1, 0, usb1, 0);
AudioConnection patchCord2(i2s1, 1, usb1, 1);
// GUItool: end automatically generated code

Can anyone suggest code examples that may work for me?
 
Not a great idea to have long wires with fast logic signals - if you have to run longer
cables, twist each logic signal with a ground wire return to reduce high-speed crosstalk perhaps?
 
I ordered one of these IM69D130 boards from Digikey. It'll probably arrive in 1 week.

Can anyone suggest code examples that may work for me?

My gut feeling is the code from msg #1 was probably working, but the signal level is too low to see with only 2 digits past the decimal point.

As a very quick & dirty test, try changing this

Code:
Serial.print(level[i]);

to this:

Code:
Serial.print(level[i], 6);

The code in msg #5 isn't a full program, so I'm not going to comment... other than to say we often see people forget AudioMemory() when crafting a program from scratch. Best to start from a known good example.

The audio library does have an example for a similar I2S mic, in File > Examples > Audio > HardwareTesting > Microphones > SPH0645. That mic had a very low level signal and issues with DC offset. If you look at that example, it has an AudioAmplifier object which increases the signal up to normal level (multiply by 8.5). It also prints 3 digits for the FFT numbers rather than only 2.

Looking at the IM69D130 datasheet, on page 5 the first spec in the table is -36 dBFS. That might mean you need to use a gain of 63 to get the signal up to normal level. 10 ^ (-36 / 20) = 0.01585, which is very close to 1/63.

So to answer your question about suggested code examples, if you see anything with the 6 digits, try that SPH0645 example to pre-process the data before it goes into the FFT. Several people had trouble with that SPH0645 mic and that example was created to help show a way to make it work well. Maybe this IM69D130 mic needs similar effort?
 
The IM69D130 has an acoustic overload point of 130dB (hence the 130 in the part number??). Thus for normal levels around 60--70dB you'd
expect it to be 60-70dB down from full-scale, suggesting an amplification factor of 100's or 1000's.

Thinking about it this isn't going to play well with the 16 bit audio library really - some sort of
scale-factor you could program into the I2S input object might be worth considering, even if its
only a left-shift count.
 
Yes, eventually we may need I2S input with scaling. Or maybe a floating point extension like Chip's mods to the library. But at this moment, so many other things are much higher priority, so it's unlikely to happen anytime soon. Even if everything were running normally right now, I would still want to wait until I get those parts next week and actually use them here.

There's just no substitute for actually using the part. The SPH0645 datasheet has similar specs, -26 dB FS and 120 dB SPL acoustic overload. But when I actually worked with the a SPH0645 breakout board from Adafruit and wrote that example, a gain of 8.5 gave pretty usable results. I didn't do a lot of extensive testing, just talking, playing music from a nearby speaker and a few hand claps near the mic. The examples are only meant as a starting point for projects.
 
Hi guys, Thank you very much for the support!!

1) I had cut the length of the cables to 4-5cm.
2)File > Examples > Audio > HardwareTesting > Microphones > SPH0645.-----> not working. BTW, Paul, I don't want to use FFT, I just copied the example code to try if it will work.

I just need to get the value of the sample from the mic and transmit the value to the 3rd parity PC by USB or other protocol, all that in RT.

I hade sample the WCLK and BCLK with oscilloscope: the BCLK 2.8MHz and the WCLK 44K. The Data always LOW... the IM69D130 don't answers...

So then I had sampled the ADAU7002 CLOCK and DATA port from the MIC side. No data transfers from mic to ADAU7002.

How can I control the BCLK rate and the WCLK timings, I think that the problem with the timings of the signals.
 
So then I had sampled the ADAU7002 CLOCK and DATA port from the MIC side. No data transfers from mic to ADAU7002.

How can I control the BCLK rate and the WCLK timings, I think that the problem with the timings of the signals.

If the ADAU is I2S compatible, the timing is not an issue.
a) did you close the jumper R15?
b) How did you sample it? It works with 1.8V levels.

2021-04-08 11_30_45-Window.png
 
Hi Frank,

a) did you close the jumper R15? ---> Yes the board coming with default R15= 0Ohm
Capture.JPG

b) How did you sample it? It works with 1.8V levels.

I had connected oscilloscope probes on the next pins:
Capture2.JPG
 
Found the problem, the ADAU board defective, I connect a new one, works perfectly!!!!!!

How can I print every sample on the serial monitor? do I have such an option?
 
How can I print every sample on the serial monitor? do I have such an option?

The "queue" objects are meant to let your program get access to the actual audio samples. See File > Examples > Audio > Recorder for sample code. Edit that code to delete the part which writes to a SD card and instead try printing with Serial.print(). Teensy 4.1 will send an incredible amount of text if you try printing every sample. Even with Teensyduino's optimizations to the serial monitor, it can still put quite a load on your PC to try displaying all that in a scrolling window. I recommend saving your work before you open the serial monitor...
 
Status
Not open for further replies.
Back
Top