How to Use Microphones on the Arduino

Using an electret microphone, the Arduino can detect sounds and perform actions based on the input it receives. For example, the sound of hands clapping, a door closing, or someone’s voice can all be used to trigger an Arduino’s output.

In this article, I’m going to show you how to set up and program a couple different types of electret microphones. We’ll take a look at what the output of the microphones look like, then we’ll build a circuit that responds to a loud sound by lighting up an LED.

What is an Electret Microphone?

Electret microphones come packaged as a stand-alone unit like this one:

Electret Microphone Standalone.jpg

Or attached to a breakout board like this:

Electret Microphone Breakout.jpg

Breakout Board Microphones

The breakout board above is a Keyes KY-038 sound detector module. Breakout board microphones usually come with a pre-amplifier built in. The pre-amplifier amplifies the audio signal to a level the Arduino can work with. This board has an “analog output” and a “digital output”. The blue component in the image above is the threshold potentiometer. It sets the sensitivity of the microphone.

Stand Alone Microphones

Stand alone microphones are a little harder to set up, since they don’t have a pre amplifier. You will need to build and connect one yourself.

Electret Microphones

Electret microphones are polarized, so they have a positive pin and a ground pin:

Electret Microphone Pins.jpg

The pin that connects to the metal casing is the ground pin and the other pin is the positive pin.

How Electret Microphones Work

Audio signals are an alternating current, similar to the current in the electrical outlets in your home. However, while the AC current in your home is a sine wave with a static frequency and wavelength, audio waves are highly variable:

Sine Wave vs Audio Wave.png

A higher frequency audio signal creates a higher pitched sound. And a lower frequency audio signal creates a lower pitched sound:

High Pitch vs Low Pitch.png

The “volume”, or “loudness” of a sound is directly related to the amplitude of the peaks. A higher amplitude audio signal creates a higher volume sound. And a lower amplitude audio signal creates a lower volume sound.

Low Volume vs High Volume.png

Another factor called “DC offset” determines the voltage at the waveform’s center.

No DC Offset vs Positive DC Offset.png

The audio signal swings up and down around the “DC offset” voltage.

How to Connect an Electret Microphone to the Arduino

Now let’s see what the raw signal from the microphone looks like. The signal output from an electret microphone is very weak, so we need to connect the microphone to a pre-amplifier to amplify the output before it’s sent to the Arduino.

What is a Pre-Amplifier?

A pre-amplifier is a circuit that increases, or amplifies a weak audio signal into a stronger one. One way to make a pre-amplifier is with one or more “operational amplifiers”, or “op-amps” for short. Op-amps are general purpose voltage amplifiers:

Op Amp Schematic Symbol PHOTOSHOPPED.png

Op-amps take a low voltage input signal and output a high voltage signal. One important aspect of op-amps is the concept of “gain”. Gain is the level of amplification performed by the amplifier. It’s the ratio of the output voltage to the input voltage.

Gain Equation.png

A gain of 1 would result in no amplification of the input signal, and a gain of 10 would result in a ten-fold amplification of the input signal. Gains are usually set anywhere from 1 up to about 100X. There are lots of pre-amplifier chips on the market that you can use to amplify the electret microphone’s signal. Here are some of the most common ones: 

  • TLC272
  • LM393
  • LM358
  • OPA2344
  • OPA2345
  • LM386

In testing, I compared the popular LM386 amplifier to the LM358. The LM358 had a cleaner signal with less noise, so that’s what I’m going to use here.

How to Connect an Electret Microphone and Pre-Amp to the Arduino

Here’s a diagram of the LM358 pins:

LM358 Pin Diagram From Datasheet.png

You can build the pre-amplifier circuit following this schematic:

LM358 Pre-Amp SCHEMATIC.png

Or you can use this wiring diagram:

LM358 Wiring Diagram with Labels.png

The gain of this circuit can changed by replacing the 100K Ohm resistor with another value. When the value is 100K ohms, the gain is set at 100X, which is the highest gain the LM358 can produce. So that will make the microphone pretty sensitive. You can lower the gain by using a smaller resistor. For example, a 47K ohm resistor will set the gain at 47X. A 10K ohm resistor will set the gain at 10X.

How to Program an Electret Microphone on an Arduino

With the microphone and pre-amp connected to the Arduino, let’s take a look at the code that will detect the microphone’s output.

const int microphonePin = A0; void setup() { Serial.begin(9600);
} void loop() { int mn = 1024; int mx = 0; for (int i = 0; i < 10000; ++i) { int val = analogRead(microphonePin); mn = min(mn, val); mx = max(mx, val); } int delta = mx - mn; Serial.print("Min="); Serial.print(mn); Serial.print(" Max="); Serial.print(mx); Serial.print(" Delta="); Serial.println(delta);
}

First we declare a variable for the microphone’s input pin, and set it equal to analog pin 0. Then we initialize the serial monitor. To capture the fluctuating audio signal, we’ll take a series of analog reads from the microphone pin. Then we’ll calculate the minimum and maximum values measured in that series of analog reads.

Audio Min Max Diagram Min and Max.png

Next we’ll calculate the difference, or delta, between the minimum and maximum values. The value of the delta will give us an idea of the volume of sound detected by the microphone. A smaller delta corresponds to a smaller amplitude in the audio waveform, and thus a quieter sound:

Audio Min Max Diagram Small Delta.png

A larger delta corresponds to a larger amplitude waveform, and a louder sound:

Audio Min Max Diagram Delta.png

Explanation of the Code

In the loop section, we start by declaring a variable called mn, which will store the minimum value of the analog reads. It’s initially set equal to 1024. Then we declare a variable called mx, which will store the maximum analog read values. It’s initially set equal to zero.

Next we have a for statement. The condition of the for statement creates a loop that runs 10,000 times before exiting. Each time the loop iterates, an analog read is taken from the microphone pin, and stored in the local variable, val.

After each analog read, we calculate the minimum and maximum values measured within those 10,000 analog reads.

The min() Function

The min() function takes two parameters, and returns the one with the smallest value. In this case the parameters are variables, mn and val. For example, if mn = 1, and val = 5, the min() function will return 1, since it’s smaller than 5.

The max() Function

The max() function works the same way as the min() function, but returns the larger of the two parameters. So if mx is larger than val, it will return mx. If val is larger than mx, it will return val.

So how does the for loop return the min and max analog read values over a series of 10,000 reads? The first time through the loop, mn is set equal to 1024, and mx is set equal to zero. In the first iteration through the for loop, we take an analog read of the microphone pin, and store the reading in val. Let’s say it’s 620. The min() function compares 1024 to 620 and returns the smaller value, so 620 is now stored in the mn variable. Then the max() function compares 0 to 620, and returns the higher value. So 620 is now stored in the mx variable.

Now the for loop iterates a second time. Another analog read is taken from the microphone pin and stored in the val variable. Let’s say now it’s 340. The min() function now compares 620 to 340 and returns the smaller value. So this time 340 is stored in the mn variable. When the max() function is executed, it compares 620 to 340 and returns the higher value. This time 620 is still higher than 340, so the value stored in mx is still 620. This process repeats until the 10,000th iteration, at which point it exits the loop with the highest and lowest analog read values stored in mx and mn.

To get the delta, or difference between the highest and lowest reading, we simply subtract mx from mn. After that, we can print mn, mx, and delta to the serial monitor.

After you build the circuit and upload the code, open the serial monitor and you will see Min, Max, and Delta values being printed out:

Arduino Electret Microphone Serial Monitor Output.png

How to Setup Microphone Breakout Boards on the Arduino

Now let’s look at how to set up the breakout board style of microphone. These are quite a bit easier to set up since they have a pre-amplifier built in. I’ll be using the Keyes KY-038 microphone module:

Keyes KY-038 Microphone Module.jpg

The Keyes KY-038 uses an LM393 op-amp. The module has four pins. The A0 pin carries the amplified analog audio output. G is for ground, the “+” sign is Vcc, and the D0 pin is the digital output.

The digital output is LOW when the audio signal is lower than a certain threshold value, and HIGH when the audio signal is greater than a certain threshold value.

The threshold value can be changed by adjusting the screw on top of the blue potentiometer. Turning the screw clockwise decreases the threshold and makes the microphone more sensitive. Turning it counter-clockwise increases the threshold and makes the microphone less sensitive.

How to Use the Microphone Module’s Digital Output to Trigger an Event

To demonstrate how to use the microphone’s digital output, let’s build an example project that reads the digital signal from the microphone and turns on an LED when the sound level increases above a certain threshold value. Follow this diagram to connect the microphone module and LED to the Arduino:

LED Clapper Wiring Diagram.png

In the sketch below, we’re going to take a digital read from the microphone’s digital pin. If the reading is HIGH, we’ll digital write a HIGH value to the LED.

int ledPin = 10;
int microphonePin = 1;
int state = 0; void setup() { pinMode(ledPin, OUTPUT); pinMode(microphonePin, INPUT);
} void loop() { state = digitalRead(microphonePin); if (state == HIGH) { digitalWrite(ledPin, HIGH); delay(1000); } else { digitalWrite(ledPin, LOW); }
}

Explanation of the Code

At the top of the sketch, we declare variables for the microphonePin and ledPin. We also declare another variable called state, to store the HIGH and LOW values read from the microphone’s digital pin.

In the setup() section, we initialize the ledPin as an OUTPUT, and the microphonePin as an INPUT. In the loop() section, we first take a digital read from the microphonePin and store that reading in the state variable. Then we have an if else statement that says “if the microphone pin state is HIGH, then digital write the ledPin HIGH, and delay for one second”. Otherwise, digital write the ledPin LOW.

Once the microphone module and LED are connected to your Arduino, upload the code. When you make a loud sound, the LED should light up:

Arduino Microphone Module LED Clapper Circuit.jpg

Ok, now let’s look at how to trigger an LED with the microphone’s analog signal.

How to Use the Microphone Module’s Analog Output to Trigger an Event

For this example, connect the microphone module and LED the same way you did in the last example. In the sketch below, the Arduino will calculate the min, max, and delta values from a series of analog reads from the microphone. We’ll use the delta value to trigger a digital write to the LED pin:

const int microphonePin = A0;
int ledPin = 10; void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT);
} void loop() { int mn = 1024; int mx = 0; for (int i = 0; i < 100; ++i) { int val = analogRead(microphonePin); mn = min(mn, val); mx = max(mx, val); } int delta = mx - mn; Serial.println(delta); if (delta > 200) { digitalWrite(ledPin, HIGH); delay(1000); } else { digitalWrite(ledPin, LOW); }
}

Explanation of the Code

First we declare the microphonePin and ledPin variables. When adjusting the sensitivity, it helps to print the delta values to the serial monitor, so we’ll initialize that as well.

In the setup() section, we initialize the serial monitor and set the ledPin as an OUTPUT.

In the loop() section, we declare variables for mn and mx. Then we have a for loop that takes a bunch of reads, and calculates the min and max analog read values from the microphonePin. In the pre-amplifier sketch we saw earlier, we performed 10,000 iterations of the for loop. But 10,000 iterations creates a delay in how the LED responds. So you can decrease this to 100, which still works fine:

for (int i = 0; i < 100; ++i) {

Next we calculate the delta, just like before. Then we print delta to the serial monitor.

After that, we use an if statement to set the threshold to control when the LED lights up. For example, if delta is greater than 200, then we digital write the ledPin HIGH, and delay for one second. Otherwise, we digital write the ledPin LOW with an else statement. The number 200 sets the threshold that triggers the LED:

if (delta > 200) {

A lower threshold will make the LED turn on at a lower sound level. And a higher threshold will make the LED turn on at a higher sound level. Play around with different threshold values to get the microphone to respond to different types of sounds, and remember that the LED can be substituted with any other device that can be activated with a high or low signal!

Source