MKR, I2S, CLK stopping, using I2S.h

The CLK out of the MKR1010 (pin 2) using the I2S.h library just stops at random.
Causing the microphone (SPH0645) to go into the sleep mode.
Some times at 10 seconds, sometimes 45 minutes.

I've got a scope probe on CLK (pin 2) and I see the CLK waveform going to flat.
The WatchDogTimer triggers and the interrupt kicks everything back on.

I've tried I2S.end() when detected and then restarting I2S.begin(I2S_PHILIPS_MODE, 20000, 32).
But that has no effect.

Anyone seen this and have a solution?

The mic is mono, I2S is set for stereo in your case, could this be the reason?

Thanks for the reply. Is that I2S_RIGHT_JUSTIFIED_MODE or I2S_LEFT_JUSTIFIED_MODE parameters?

Depends on how you wired your mic, could you show how you connected it?

GND connected GND
3.3V connected VCC
LRCLK / WS pin 3 (MKR1010)
BCLK pin 2 (MKR1010)
Data /SD A6 (MKR1010)
SEL Not connected

I’m not really familiar with this microphone, the pair i have are round ones and one is set for left and the other for right channel. Some arduino tutorial mentions that you can leave Sel disconnected like you have, maybe it just transmits on both channels in this configuration. as far as connection it seems fine, maybe try lowering sampling frequency to 16000? if this stil doesn’t work perhaps if you could try another board?

Thanks for trying.
I've lowered the sampling and I currently have 10 units out in the field exhibiting this behavior.
The watchdog timer does reset and that gets everything working, but it bothers me relying on the Watchdog timer, its sloppy.
I feel the answer is in the I2S.h. but that calls out many other .h files as well.
So, it's slow going.

One more question, are you reading I2S directly in the loop with I2S.read()? I used example in I2S library and managed succesfully break it by adding delay in the loop. There are wrappers in ArduinoLibrary that use I2S class but they all have update method that reads I2S into array independently, maybe the timing is crucial if you use raw I2S.

Yes, I am. I've tried adding a delay, but it still randomly breaks. You broke working code by adding a delay?

for (int i=0; i<samples; i++) {
sample2=0;
sample2=I2S.read();
if(sample2==0 || sample2==-1) {
i--;
}
else {
sample2>>=14;
sample[i]=sample2;
}
}
}

Yes, using this sketch https://www.arduino.cc/en/Tutorial/LibraryExamples/I2SInputSerialPlotter

if I add delay(500) in the loop it breaks completely, if I use millis() and print in the plotter every 500 millisecond but the I2S.read() is not delayed it works, but sometimes it stops too, just like you described. If I use AmplitudeAnalyzer from ArduinoSound library, which has own independent routine for reading I2S it doesnt stop even randomly. This is why I was suprised it happend to you but I never used raw I2S before.

GREAT! I'll check out AmplitudeAnalizer from ArduinoSound library

I'm sooooo happy you said, "but sometimes it stops too, just like you described". It's not me!

Yeah, that ran all night.
I'm suspecting the SPH0645 returns data differently than that library is expecting.
I've read the SPH0645 is not I2S compliant in timing.
Note to self: Next IOT project don't use SPH0645.
Thanks for the help.

1 Like

I've been digging more in ArduinoSound library regading I2S because I wanted to separate left and right channel amplitude from stereo mics, so I got to know inner working a bit more. What exactly does your mic do?

The output of ArduinoSound library does not seem to correlate to the volume of yelling I am presenting to the SPH0645. Also the output seems to be filtered maybe smoothed. It does not hang up, I ran it all night long and more. To use the SPH0645 you have to >>14 the data out stream. I suspect somewhere down deep in the code the answer is, I see the library does use I2S.h.

Whoa, they are so expensive. I bought a pair of INMP441 (https://invensense.tdk.com/wp-content/uploads/2015/02/INMP441.pdf), it has slightly narrower frequency reponse than yours, but is very sensitive. I run it with 44100 and 32bit sampling and using modified AmplitudeAnalyzer class that extracts right and left data separately https://twitter.com/Killzone_Kid/status/1414967020597166083?s=20