Teensy 3.2 + Audio Board + MEMS Mic - Lots of noise but only when recording

Status
Not open for further replies.
Hi all,

I'm using a Teensy 3.2 with Teensy 3 Audio Shield coupled with a SparkFun ADMP401 breakout board MEMS microphone (https://www.sparkfun.com/products/9868). I don't require playback from the SD card on the Teensy, but I do desire to record data to the SD card for processing later on PC, as well as have the ability to listen to sounds being detected by the microphone (both when recording and not recording) via the on-board 3.5mm headphone jack.

I've started at the Examples->Audio->Recorder sketch and adapted it to work as desired. It is functionally working as desired, whenever I plug headphones into the 3.5mm jack, it allows me to hear what the microphone is measuring (both when recording or not (idle mode)). Saving to the SD card is also working, and I can import the .RAW file into MATLAB for processing. The audio quality is FANTASTIC through the headphone output when in idle mode, i.e. when not storing data to the SD card. However, as soon as I begin recording, a large amount of 'noise' is induced into the microphone input signal that can be heard through the 3.5mm output, as well as seen in the data stored to the SD card. I use quotations for noise because it's as if I can here the electric signals from storing to the SD card. When the processor is storing the data to a buffer I head a constant buzz, then, periodically, I hear a higher freqeuncy buzz (of duration approx 0.5 sec) in which (I think) the processor is pushing data to the SD card. Stop recording to SD card and the noise stops completely.

The noise I'm getting only when receiving is highly undesirable, and I can't seem to figure out where it's coming from to stop it. I will mention that powering the microphone via a separate power supply and ground seems to help the issue somewhat, but does not stop it completely. I've attached my code, as well as an image showing my setup-configuration as well as the data recorded to the SD card showing the noise explicitly, no other sounds were being recorded. Any ideas?

HTML:
// Record sound as raw data to a SD card, and play it back.
//
// Requires the audio shield:
//   http://www.pjrc.com/store/teensy3_audio.html
//
// Three pushbuttons need to be connected:
//   Record Button: pin 0 to GND
//   Stop Button:   pin 1 to GND
//
// This example code is in the public domain.

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

// Define input & output
AudioInputI2S            i2s2;           //xy=105,63
AudioOutputI2S           i2s1;           //xy=470,120

// Audio recording to SD card
AudioAnalyzePeak         peak1;          //xy=278,108
AudioRecordQueue         queue1;         //xy=281,63
AudioConnection          patchCord1(i2s2, 0, queue1, 0);
AudioConnection          patchCord2(i2s2, 0, peak1, 0);

// 3.5mm headphone output (feed-through)
AudioConnection          patchCord3(i2s2, 0, i2s1, 0);
AudioConnection          patchCord4(i2s2, 0, i2s1, 1);

AudioControlSGTL5000     sgtl5000_1;     //xy=265,212


// Bounce objects to easily and reliably read the buttons
Bounce buttonRecord = Bounce(0, 4); // 8 = 8 ms debounce time
Bounce buttonStop =   Bounce(1, 4);


// Decide which input on the audio shield to be used
//const int myInput = AUDIO_INPUT_LINEIN;
const int myInput = AUDIO_INPUT_MIC;


// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

// Remember which mode we're doing
int mode = 0;  // 0=stopped, 1=recording

// The file where data is recorded
File frec;

void setup() {
  
  // Configure the pushbutton pins - pull-up resistor configuration
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);

  // Audio connections require memory, and the record queue
  // uses this memory to buffer incoming audio.
  AudioMemory(120);

  // Enable the audio shield, select input, and enable output
  sgtl5000_1.enable();
  sgtl5000_1.inputSelect(myInput);

  // Microphone gain selection
  sgtl5000_1.micGain(0.1);

  // Turn off ADC high pass filter to reduce noise level
  sgtl5000_1.adcHighPassFilterDisable();

  // Initialize the SD card
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here if no SD card, but print a message
    while (1) {
      delay(500);
    }
  }
}


void loop() {
  // First, read the buttons
  buttonRecord.update();
  buttonStop.update();
  
  // Respond to button presses
  if (buttonRecord.fallingEdge()) {
    if (mode == 0) startRecording();
  }
  if (buttonStop.fallingEdge()) {
    if (mode == 1) stopRecording();
  }

  // If we're recording, carry on...
  if (mode == 1) {
    continueRecording();
  }

  // Volume control via pot on audio board
  float vol = analogRead(15);
  vol = vol / 1024;
  sgtl5000_1.volume(vol);
  
}


void startRecording() {
  if (SD.exists("RECORD.RAW")) {
    // The SD library writes new data to the end of the
    // file, so to start a new recording, the old file
    // must be deleted before new data is written.
    SD.remove("RECORD.RAW");
  }
  frec = SD.open("RECORD.RAW", FILE_WRITE);
  if (frec) {
    queue1.begin();
    mode = 1;
  }
}

void continueRecording() {
  if (queue1.available() >= 2) {
    byte buffer[512];
    // Fetch 2 blocks from the audio library and copy
    // into a 512 byte buffer.  The Arduino SD library
    // is most efficient when full 512 byte sector size
    // writes are used.
    memcpy(buffer, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    memcpy(buffer+256, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    // write all 512 bytes to the SD card
    elapsedMicros usec = 0;
    frec.write(buffer, 512);
    // Uncomment these lines to see how long SD writes
    // are taking.  A pair of audio blocks arrives every
    // 5802 microseconds, so hopefully most of the writes
    // take well under 5802 us.  Some will take more, as
    // the SD library also must write to the FAT tables
    // and the SD card controller manages media erase and
    // wear leveling.  The queue1 object can buffer
    // approximately 301700 us of audio, to allow time
    // for occasional high SD card latency, as long as
    // the average write time is under 5802 us.
    //Serial.print("SD write, us=");
    //Serial.println(usec);
  }
}

void stopRecording() {
  queue1.end();
  if (mode == 1) {
    while (queue1.available() > 0) {
      frec.write((byte*)queue1.readBuffer(), 256);
      queue1.freeBuffer();
    }
    frec.close();
  }
  mode = 0;
}

25999wm.jpg


2vd5kjd.jpg
 
Last edited:
From the audio design tool:
micGain(dB);
When using the microphone input, set the amplifier gain. The input number is in decibels, from 0 to 63.

From control_sgtl5000.h:
bool micGain(unsigned int dB);

Why you using float?:
sgtl5000_1.micGain(0.1);
 
From the audio design tool:
micGain(dB);
When using the microphone input, set the amplifier gain. The input number is in decibels, from 0 to 63.

From control_sgtl5000.h:
bool micGain(unsigned int dB);

Why you using float?:
sgtl5000_1.micGain(0.1);

The microphone breakout board has an amplification factor of ~66 at it's analog output. The greater the gain set in software, the greater the amplitude of the noise I described became. It didn't give an error so I didn't look further than the fact the gain could be selected between 0 to 63. I set it something low to see if it would change the SNR, which it did not. Both the amplitude of the noise and signal are affected the same by changing the gain in software.

I should mention I previously had the gain set at all integer values (1, 3, 5, 20, 30,...) and the presence of the noise I described was always there. In fact, with a gain of 20 or so, the noise was so prevalent the signal saturated with any sound applied to the microphone. You are correct though, even though it does not throw an error, I should probably set it to an int as described. Thanks!
 
I have the same, or very similar, MEMS microphone and I found that it was very sensitive even with 0dB gain. So much so, that it picks up the constant fan noise from my PC. Are there any sources of noise close by that your mic could be picking up?

Pete
 
I have the same, or very similar, MEMS microphone and I found that it was very sensitive even with 0dB gain. So much so, that it picks up the constant fan noise from my PC. Are there any sources of noise close by that your mic could be picking up?

Pete

Yes, I understand what you are saying but this is not the cause - placing the microphone next to my laptop I can certainly pick up the noise produced by the fan on the microphone and I could see that fan noise on the output whether writing to the SD card or not. This microphone is absolutely fantastic when paired with this audio board (besided the issue I described of course). I can literally hear myself breathing with the microphone 3-4 feet away from my airway - it is very sensitive and exactly what I require for my project. I recorded the data of the plot with no background noise or other stimulus applied to the microphone, all that is being seen is the noise being induced into the mic input.

The issue I describe is very clearly some sort of interference or 'cross talk' that is happening on either the Teensy or the Audio Shield - some sort of noise is being injected into the mic signal the moment I begin recording. It is very prominent the moment I begin recording to the SD card, and will continue exactly the same, very periodic sounding, until the moment I depress the stop button and writing the SD card halts.

If you take a look at the signal I plotted (this is what is being stored to the SD card), it sounds like a buzz....then a slight "tick" (you can see those marks in the plot)...back to buzz... and this happens 7 times before a longer "electronic" signal is heard and it repeats: buzz, 7 ticks, then longer noisy sound again. Soon as I stop recoring to the SD card the signal becomes clean without any buzz, ticks, or other electronic noisy sounds..

119tmpv.jpg
 
Last edited:
Try moving a little bit to the right the teensy and audio board and then use a shorter path for VCC and GND to the mic board. Right now you using more than 20cm of cable if you take into account the path for VCC an GND in the breadboard..
Anyway keep in mind that any mic it's a just as good as the amplifier you use.
The breakout has almost no filtering at all, so place at least a 1uF capacitor close to the VCC and GND breakout cables.
This mic board from Sparkfun has no ferrites for EMI, and its using low value capacitor sizes.
You cannot use a 0.1uf to filtering all board power supply and then use 1.0uF to filter the resistor divider of the positive input of the op amp. If you gonna use that capacitors in the board the placement should be just the opposite:
https://www.sparkfun.com/datasheets/BreakoutBoards/ADMP401-Breakout-v13.pdf

No wonder you getting a lot of high frequency noise.
 
Try moving a little bit to the right the teensy and audio board and then use a shorter path for VCC and GND to the mic board. Right now you using more than 20cm of cable if you take into account the path for VCC an GND in the breadboard..
Anyway keep in mind that any mic it's a just as good as the amplifier you use.
The breakout has almost no filtering at all, so place at least a 1uF capacitor close to the VCC and GND breakout cables.
This mic board from Sparkfun has no ferrites for EMI, and its using low value capacitor sizes.
You cannot use a 0.1uf to filtering all board power supply and then use 1.0uF to filter the resistor divider of the positive input of the op amp. If you gonna use that capacitors in the board the placement should be just the opposite:
https://www.sparkfun.com/datasheets/BreakoutBoards/ADMP401-Breakout-v13.pdf

No wonder you getting a lot of high frequency noise.

Thank you Stendall, I too had a feeling that the microphone circuit may be the culprit so I did a test: I removed the microphone completely and connected the "MIC" input on the Audio Shield directly to ground. I placed my headphones into the 3.5mm output and listened, I got exactly the same noise (only when recording) as when the microphone was connected.

I have a feeling the MIC input line trace on the Audio Shield PCB is simply too close to the digital data lines for the SD card, since the noise only appears when the SD card is being used to record. I've gone over my solder connections under the microscope to ensure there was no bridging between my connections.

I've attached the magnitude spectrum showing what frequencies the noise occurs at:

2eknhpk.jpg
 
What is the mains power frequency in your house?.
60 hz. ?

I think you could have a power supply issue.
The first line looks like 180hz. Second harmonic of 60hz
 
What is the mains power frequency in your house?.
60 hz. ?

I think you could have a power supply issue.
The first line looks like 180hz. Second harmonic of 60hz

Correct, 60 Hz power supply from a wall outlet, but remember I get this noise even when running on battery. It would make sense we don't see the first harmonic (60 Hz) as the bandwidth of the microphone connected is 100 Hz to 15 kHz. But then again, I got the exact same noise, and no 60 Hz peak even without the microphone connected.

My other thought was maybe the 180 Hz peak is the event when the writing of data to the SD card takes place and the mic input line is picking up that digitial signal. I sample at 44100 Hz, but since we can't push data to the SD card at such a high rate, we use a number of buffers, and write to the SD card at a much lower rate (maybe 180 Hz?).
 
Last edited:
Are you sure you get exactly this noise (180hz peak) when you use batteries?
Maybe you having more than one noise source. The noise from wall outlet and environmental noise.
Did you put the 1uF capacitor the closest possible to the mic board leads?

If the sketch writes to the SD every 2 audio block, that's ~44100/256 = ~172 writes/second.
Very close to the 180hz too. Dammit!

Try to write to the SD every 1 or 3 audio blocks and check the noise peak again.

I'm thinking that maybe the specific SD card you are using draws a little bit more current than usual when writes.
That together with a bad filtering on the mic board could make a difference.
 
Last edited:
Are you sure you get exactly this noise (180hz peak) when you use batteries?
Maybe you having more than one noise source. The noise from wall outlet and environmental noise.
Did you put the 1uF capacitor the closest possible to the mic board leads?

If the sketch writes to the SD every 2 audio block, that's ~44100/256 = ~172 writes/second.
Very close to the 180hz too. Dammit!

Try to write to the SD every 1 or 3 audio blocks and check the noise peak again.

I'm thinking that maybe the specific SD card you are using draws a little bit more current than usual when writes.
That together with a bad filtering on the mic board could make a difference.

Hi Stendall,

I checked the noise peak of the same recording I showed previously to examine the frequency peak more exactly, it's precisely at 172.4 Hz. The next highest peak you see occurs at precisely 344.5 Hz (~double that of 172.4), both of which were recorded only when powered by the battery while on my lab bench.

29y3ujp.jpg


I did as you said, changed the audio block size and I could immediately hear a change in the noise I was hearing (when recording) through my headphones, not better or worse, just the noises occuring at different rates as compared to prior.

Dammit is right! I hear perfectly great sound being passed through the microphone when not recording, soon as I hit the button to record the terrible noise comes on. I still feel it's the microphone input trace too close to the digital communication lines on the PCB for the SD card causing the issue. It doesn't help the microphone was not designed to "match" the audio shield or Teensy, and the fact it's a powered microphone (requires ~3.3v) vs. the crappy electret microphone they recommend (that used only the ground and audio signal) probably plays into the issue as well.

Tried the 1uF capacitor as well, and no help. Will try to look for another micro SD card to test, but mostly looking into re-designing the PCB for the audio shield to better isolate the audio input line from digital communication lines. Either that, or ditch the audio shield all together and just analog read the output of the mic with the Teensy directly and design my own headphone input, etc.. Also the microphone I can (and plan to) redesign a bit better too.
 
one noise source is the regular writing to SD disk, which draws for a short period significant power, modulating the power supplied to the mems internal FET, resulting in regular spikes.
Unfortunately, recording audio to onboard uSD with single power supply is extremely difficult and the PJRC audioboard is somewhat noisy in this respect.
 
one noise source is the regular writing to SD disk, which draws for a short period significant power, modulating the power supplied to the mems internal FET, resulting in regular spikes.
Unfortunately, recording audio to onboard uSD with single power supply is extremely difficult and the PJRC audioboard is somewhat noisy in this respect.


Thank you WMXZ, and I can agree with this statement. What would be the best solution do you think? Perhaps using an external SD card adapter with it's own, isolated, power source?
 
Thank you WMXZ, and I can agree with this statement. What would be the best solution do you think? Perhaps using an external SD card adapter with it's own, isolated, power source?

if the micbias is really the problem then increasing the existing 2.2uF on exit of SGTL5000-pin16 to say 47uF or more (by soldering a larger capacitor on top) should help. But others may have better ideas.
Not using the usd card on audio adapter would also avoid load changes on the 3.3V line.
 
Vq35dett01, you mentioned that you post-process the .RAW file in matlab. Can you explain the magnitude of this task and what kind of format you are able to output it as? Thank you.
 
Vq35dett01, you mentioned that you post-process the .RAW file in matlab. Can you explain the magnitude of this task and what kind of format you are able to output it as? Thank you.

Ctsi, post-processing tasks include generating and analyzing the spectrogram of the recording, as well as passing the data through a set of algorithms, the latter part I am not closely involved with. Data is (to be) used for pre-screening of individuals with possible Obstructive Sleep Apnea (OSA). Currently my research involves recording breathing sounds during wakefulness & sleep to 'determine' if one can be considered as suffering from OSA. You can see from this quality of the audio recorded is of the utmost importance.

We have a 'current setup' comprised of expensive ($10k+), large, and heavy commercial equipment: recording studio microphone, amplifer, 16-bit high-speed USB hub (ADC), etc. The goal is to design a relatively inexpensive, wearable device that meets, or at least comes close to the performance of the 'current setup'. Post-processing has been validated with the 'current setup', despite the noise I hear ONLY when recording to SD, the quality of the Teensy + Audio Board otherwise is not too far off..

As an overall update for the issue, I'm fairly certain it's caused by the voltage supply changes that occur when using the SD card to save data. Though my efforts to avoid this have all failed, I've tried:

i) Powering the Audio Board separately from the Teensy
ii) Using the on-board SD card reader on a Teensy 3.6
iii) Using an external SD card breakout board (separate power supply)
iv) Tried all combinations of capacitors and other such tricks on the power/ground lines, mic lines, etc.

All of which produce some form of noise when recording to SD.

Recording to Audacity through the Teensy's USB connection results in no noise, so next plan is to incorporate a Raspberry Pi to capture data..
 
Last edited:
Have you found streaming the audio signals through Audacity provides any sort of timestamping option? I haven't been able to find any by importing the .raw file into Audacity but I have not tried recording directly to Audacity yet. Timestamping my signals are very important to my project and I am yet to find a viable solution so if that is an aspect you are utilizing please let me know. Best of luck.
 
Audacity has good relative time stamping and easy measurement of arbitrary sample lengths.

Not absolute time, or time compared to an external standard.

You may find value it sending a fast, known audio signal into one channel, and your signal-of-interest into the other.
You'll see the two signals, one over the other, with resolution down to 44,100 Hz.

There are a couple of uses of this technique in this thread
https://forum.pjrc.com/threads/41706-Teensy-Microphone-Module
 
Last edited:
Hi

Did someone get a solution for this "writing to SD card noise" issue? I am quite exactly in the same situation and really don't know if I can go on working with a Teensy board (and especially what to use as a replacement :-( ).
 
It seems that there is no better solution in terms of quality/price on the market for the moment. Since the SD card access seems to stray into the analog audio section, approved techniques like separate power supplies for analog and digital, additional decoupling and/or shielding might do the trick.
 
Hi

I run into the same issues vq35dett01 described. Kinda disappointing now, cause the recoding was the key feature I wanted wo work with. It also doesn't work when using the line in input and write to sd card -> same noise here (make some kinda sense when its a pub design issue).

If someone finds a workaround someday, feel free to share :).

Cheers
 
Status
Not open for further replies.
Back
Top