Reading Audio Samples With the Onboard Microphone

Learn how to create a soundmeter using the built-in microphone with the Nicla Vision.

Nicla Vision - microphone
Nicla Vision - microphone

Overview

In this tutorial you will use the Arduino Nicla Vision board to get the microphone (MP34DT06JTR) readings and change the LED brightness.

Goals

  • Get the microphone data.
  • Use the PDM(Pulse-density modulation) library.
  • Print the microphone values in the Serial Monitor.
  • Change RGB blinking speed with the last microphone reading. (Arduino IDE)
  • Show the values on a spectrum analyzer (only with openMV)

Required Hardware and Software

  • Nicla Vision
  • Latest mbed Core version
  • Latest openMV IDE version

Set Up

To check that you correctly set up the board please visit our Getting Started Guide for both OpenMV and Arduino instructions.

Instructions

OpenMV

Open the script by going to Examples > Arduino > NanoRP2040 > Audio > Audio_fft.py.

Using the same sketch as the NanoRP2040, because both boards access the microphone in the same way

Make sure the board is connected, if the board is connected to OpenMV you should see a green play button in the bottom left corner of the window. If you do not see this icon, try pressing the connect button in the bottom left corner. If there still is some issue to connect the board take another look at the getting started guide.

When the script is running, you will see an spectrum analyzer in the top right panel that reflects the audio readings input. Try making some noise and see how it reacts.

OpenMV IDE - Spectrum analyzer
OpenMV IDE - Spectrum analyzer

Arduino

Setting Up the Sketch

We will edit the example from the mbed Core, go to Examples > PDM > PDMSerialPlotter and save it into your sketchbook.

You can run the sketch to see the result, it will show the data that the microphone is getting on the Serial Plotter.

Controlling the Blinking LED

Now that you can get the microphone data, let's control the built-in RGB LED and change the speed of its blinking depending on the values by changing the blinking time to the last reading of the microphone, the blink will be slow if the sound is loud, and fast if it is quiet.

You can access the example sketch at Examples > PDM > PDMSerialPlotter and then edit as shown in this tutorial. Or find the full edited sketch in our Arduino_Pro_Tutorials library.

Complete Sketch

1/*
2 This example reads audio data from the on-board PDM microphones, and prints
3 out the samples to the Serial console. The Serial Plotter built into the
4 Arduino IDE can be used to plot the audio data (Tools -> Serial Plotter)
5 Circuit:
6 - Arduino Nicla Vision, or
7 - Arduino Nano 33 BLE board, or
8 - Arduino Nano RP2040 Connect, or
9 - Arduino Portenta H7 board plus Portenta Vision Shield
10 This example code is in the public domain.
11 */
12
13
14 #include <PDM.h>
15
16 // default number of output channels
17 static const char channels = 1;
18
19 // default PCM output frequency
20 static const int frequency = 16000;
21
22 // Buffer to read samples into, each sample is 16-bits
23 short sampleBuffer[512];
24
25 // Number of audio samples read
26 volatile int samplesRead;
27
28 // Blinking
29 bool state = false;
30 int timeStart = 0;
31
32 void setup() {
33 Serial.begin(9600);
34 pinMode(LEDB, OUTPUT);
35
36 while (!Serial);
37
38 // Configure the data receive callback
39 PDM.onReceive(onPDMdata);
40
41 // Optionally set the gain
42 // Defaults to 20 on the BLE Sense and 24 on the Portenta Vision Shield
43 // PDM.setGain(30);
44
45 // Initialize PDM with:
46 // - one channel (mono mode)
47 // - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
48 // - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield
49 if (!PDM.begin(channels, frequency)) {
50 Serial.println("Failed to start PDM!");
51 while (1);
52 }
53
54
55 }
56
57 void loop() {
58 // Wait for samples to be read
59 if (samplesRead) {
60
61 // Print samples to the serial monitor or plotter
62 for (int i = 0; i < samplesRead; i++) {
63 if (channels == 2) {
64 Serial.print("L:");
65 Serial.print(sampleBuffer[i]);
66 Serial.print(" R:");
67 i++;
68 }
69 Serial.println(sampleBuffer[i]);
70 }
71
72 // Clear the read count
73 samplesRead = 0;
74
75 if (millis() - timeStart > sampleBuffer[2]) {
76 digitalWrite(LEDB, state);
77 state = !state;
78 }
79 }
80 }
81
82 /**
83 Callback function to process the data from the PDM microphone.
84 NOTE: This callback is executed as part of an ISR.
85 Therefore using `Serial` to print messages inside this function isn't supported.
86 * */
87 void onPDMdata() {
88 // Query the number of available bytes
89 int bytesAvailable = PDM.available();
90
91 // Read into the sample buffer
92 PDM.read(sampleBuffer, bytesAvailable);
93
94 // 16-bit, 2 bytes per sample
95 samplesRead = bytesAvailable / 2;
96 }

Testing It Out

After you have successfully verified and uploaded the sketch to the board, open the Serial Monitor from the menu on the left. You will now see the new values printed.

If you want to test it, the only thing you need to do is to speak or play some sounds close to the board and see how the blinking of the RGB LED changes based on the input.

Troubleshoot

  • In case the Serial Monitor freezes, unplug and then plug the board into your computer again, now try to upload the sketch
  • If the sketch is not working, try to double tap the reset button and upload the sketch once again.

Conclusion

You have learned how to use the Arduino IDE and OpenMV to get data from the microphone and then use it to change the RGB LED on the board. This can for example be used as an alarm system to wake the board up and take a screenshot with the Camera.

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.

Suggest Changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. You can read more on how to contribute in the contribution policy.