Reading microphone data on Nano RP2040 Connect

Learn how to read data from the MP34DT05 microphone, and how to use the data to turn ON or OFF the built-in RGB.

Introduction

The Nano RP2040 connect comes with the MP34DT05 microphone, which can be used to record audio. In this tutorial, we will setup a basic application that simply turns ON or OFF the built in RGB LED whenever a loud noise is recorded (for example snapping our fingers).

Note: if you need help setting up your environment to use your Arduino Nano RP2040 board, please refer to this installation guide.

Goals

The goals of this project are:

  • Learn about PDM.
  • Read microphone data.
  • Print out the data in the Serial Monitor / Serial Plotter.
  • Create trigger value(s).
  • Activate an RGB based on a loud noise.

Hardware & Software needed

The MP34DT05 microphone

The MP34DT05 microphone.
The MP34DT05 microphone.

Microphones are components that convert physical sound into digital data. Microphones are commonly used in mobile terminals, speech recognition systems or even gaming and virtual reality input devices.

The MP34DT05 sensor is a ultra-compact microphone that use PDM (Pulse-Density Modulation) to represent an analog signal with a binary signal. The sensor's range of different values are the following:

  • Signal-to-noise ratio: 64dB
  • Sensitivity: -26dBFS ±3dB
  • Temperature range: -40 to 85°C

If you want to read more about the MP34DT05 sensor you can take a look at the datasheet.

Circuit

This tutorial requires no additional circuit. You will only need to connect the board to a computer through a Micro USB cable.

The circuit.
The circuit.

Programming the board

We will now get to the programming part of this tutorial.

  1. First, let's make sure we have the drivers installed. If we are using the Web Editor, we do not need to install anything. If we are using an offline editor, we need to install it manually. This can be done by navigating to Tools > Board > Board Manager.... Here we need to look for the Arduino Mbed OS Nano Boards and install it.

  2. We can now take a look at some of the core functions of this sketch:

  • static const char channels = 1;
    - sets the number of output channels.
  • static const int frequency = 16000;
    - sets the sampling frequency to 20 KHz.
  • short sampleBuffer[512]
    - buffer to read samples into, each sample is 16-bits.
  • while (!Serial)
    - prevents program from running until Serial Monitor is opened.
  • PDM.begin(channels, frequency)
    - initializes the PDM library.
  • Serial.print(sampleBuffer[i])
    - prints sample to the Serial Monitor / Plotter.

The sketch can be found in the snippet below. Upload the sketch to the board.

1#include <WiFiNINA.h>2#include <PDM.h>3
4bool LED_SWITCH = false;5
6// default number of output channels7static const char channels = 1;8
9// default PCM output frequency10static const int frequency = 16000;11
12// Buffer to read samples into, each sample is 16-bits13short sampleBuffer[512];14
15// Number of audio samples read16volatile int samplesRead;17
18void setup() {19  Serial.begin(9600);20  pinMode(LEDB, OUTPUT);21  while (!Serial);22  // Configure the data receive callback23  PDM.onReceive(onPDMdata);24
25  // Optionally set the gain26  // Defaults to 20 on the BLE Sense and -10 on the Portenta Vision Shield27  // PDM.setGain(30);28
29  // Initialize PDM with:30  // - one channel (mono mode)31  // - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense32  // - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield33  if (!PDM.begin(channels, frequency)) {34    Serial.println("Failed to start PDM!");35    while (1);36  }37}38
39void loop() {40  // Wait for samples to be read41  if (samplesRead) {42
43    // Print samples to the serial monitor or plotter44    for (int i = 0; i < samplesRead; i++) {45      if (channels == 2) {46        Serial.print("L:");47        Serial.print(sampleBuffer[i]);48        Serial.print(" R:");49        i++;50      }51      Serial.println(sampleBuffer[i]);52
53      if (sampleBuffer[i] > 10000 || sampleBuffer[i] <= -10000) {54        LED_SWITCH = !LED_SWITCH;55        if (LED_SWITCH) {56          Serial.println();57          digitalWrite(LEDB, HIGH);58          Serial.println("ON!");59          Serial.println();60          delay(1000);61        }62        else {63          Serial.println();64          digitalWrite(LEDB, LOW);65          Serial.println("OFF!");66          Serial.println();67          delay(1000);68        }69      }70    }71
72    // Clear the read count73    samplesRead = 0;74  }75}76
77/**78   Callback function to process the data from the PDM microphone.79   NOTE: This callback is executed as part of an ISR.80   Therefore using `Serial` to print messages inside this function isn't supported.81 * */82void onPDMdata() {83  // Query the number of available bytes84  int bytesAvailable = PDM.available();85
86  // Read into the sample buffer87  PDM.read(sampleBuffer, bytesAvailable);88
89  // 16-bit, 2 bytes per sample90  samplesRead = bytesAvailable / 2;91}92

Testing it out

After successfully uploading the code to the board, we will need to open the Serial Monitor to initialize the program. Once we open it, we can see that data is being printed rapidly. These are the audio samples that are record from the microphone. We can also open the Serial Plotter to instead view the data as a graph.

Serial Monitor with microphone data.
Serial Monitor with microphone data.

We can also open the Serial Plotter to instead view the data as a graph.

Serial Plotter with microphone data.
Serial Plotter with microphone data.

Now in the sketch, we have written a conditional that is activated whenever the sample value is either over

10000
or under
-10000
. This can be produced, by for example snapping our fingers, coughing loudly or if you prefer, yelling (we prefer the finger snapping method).

Whenever this condition is met, the following things happen:

  • The boolean
    LED_SWITCH
    changes.
  • Depending on the state of
    LED_SWITCH
    , the blue pixel turns ON or OFF.
  • The text
    "ON"
    or
    "OFF"
    is printed in the monitor.
  • The program freezes for one second, then resumes (this is just to allow some time to see the status of the LED).

In the Serial Monitor we should see the following when the conditional is met, where the blue pixel will turn ON / OFF depending on the state of

LED_SWITCH
.

The blue RGB pixel either turns ON/OFF when the condition is met.
The blue RGB pixel either turns ON/OFF when the condition is met.

Conclusion

In this tutorial we have learned how to retrieve data from the microphone onboard the Nano RP2040 Connect board. The sketch we used is an elaboration of the PDM example that can be found through File > Examples > PDM > PDMSerialPlotter.

Contribute to Arduino

Join the community and suggest improvements to this article via GitHub. Make sure to read out contribution policy before making your pull request.

Missing something?

Check out our store and get what you need to follow this tutorial.