GIGA Display Shield Microphone Guide

Learn how to use the GIGA Display Shield's Microphone

The GIGA Display Shield has an embedded MEMS microphone (MP34DT06JTR) that when combined with the visual element of the GIGA Display Screen can be used in a number of ways.

  • Stream microphone data (plot it / print it),
  • Display volume as a bar,
  • Detect a clap or other noises

Using the Arduino_Graphics,Arduino_GigaDisplay_GFX and lvgl we can also create animations and screen changes based on microphone data.

In this guide we will take a closer look at the PDM library, and provide some examples that can be used with this shield.

Hardware & Software Needed

Downloading the Library and Board Package

Make sure the latest GIGA Board Package is installed in the Arduino IDE. You can install it directly in the IDE by navigating to the board manager and searching for Arduino Mbed OS Giga Boards and install it.

The PDM library is included in the Board Package, as well as the video driver library, Arduino_H7_Video library. Some examples in this guide uses other libraries that are listed in each example.

PDM Library

Pulse Density Modulation (PDM) is a technique used to convert analog signals into a digital 1-bit stream.

The PDM library is library built-in to the GIGA Board Package and allows you to read and process PDM signals. In this case, it reads the signal from the

  • Source code is available here
  • Library documentation is available here

Microphone PDM Example

The GIGA R1 Board Package includes a sample sketch called PDM, and in this section it is explained in more detail.

First we need to define the number of output channels, output frequency, a variable for counting when reading from the buffer and creating the buffer which the readings will be put into. This is done with the following lines:

1// default number of output channels
2static const char channels = 1;
3
4// default PCM output frequency
5static const int frequency = 16000;
6
7// Buffer to read samples into, each sample is 16-bits
8short sampleBuffer[512];
9
10// Number of audio samples read
11volatile int samplesRead;

A callback function needs to be set, which is called when new PDM data is ready to be read. We do this in the

setup()
function using:

1PDM.onReceive(onPDMdata);

onPDMdata
is the callback function that we will have to create at the end of the sketch.

Now when we want to print or use the readings let's do it with a

for
loop since they are inside a buffer, which we need to step through. But let's first check so that there are readings to be printed with a simple
if
statement. These lines will step through the buffer until all the readings inside are printed and then start over:

1if (samplesRead) {
2 for (int i = 0; i < samplesRead; i++) {
3 Serial.println(sampleBuffer[i]);
4 }
5}

Its inside this

for
loop where we can get readings that will then change visual elements on the screen. This is where you would put any code that needs to react to the microphone readings.

And the last important part is the callback function that we used in the

setup()
function. This will take care of reading the values into the buffer and setting the value of the
samplesRead
variable which we used in the previous step.

1/**
2 * Callback function to process the data from the PDM microphone.
3 * NOTE: This callback is executed as part of an ISR.
4 * Therefore using `Serial` to print messages inside this function isn't supported.
5 * */
6void onPDMdata() {
7 // Query the number of available bytes
8 int bytesAvailable = PDM.available();
9
10 // Read into the sample buffer
11 PDM.read(sampleBuffer, bytesAvailable);
12
13 // 16-bit, 2 bytes per sample
14 samplesRead = bytesAvailable / 2;
15}

The full example is available in the PDM Example section just below.

Microphone Examples

In this section you will find a series of examples that uses the microphone.

PDM Example

This sketch can be found in File > Examples > PDM in the Arduino IDE. It reads the microphone data, stores it in a buffer and prints it to the Serial Monitor / Serial Plotter tool in the IDE.

1#include <PDM.h>
2
3// default number of output channels
4static const char channels = 1;
5
6// default PCM output frequency
7static const int frequency = 16000;
8
9// Buffer to read samples into, each sample is 16-bits
10short sampleBuffer[512];
11
12// Number of audio samples read
13volatile int samplesRead;
14
15void setup() {
16 Serial.begin(9600);
17 while (!Serial);
18
19 // Configure the data receive callback
20 PDM.onReceive(onPDMdata);
21
22 // Optionally set the gain
23 // Defaults to 20 on the BLE Sense and 24 on the Portenta Vision Shield
24 // PDM.setGain(30);
25
26 // Initialize PDM with:
27 // - one channel (mono mode)
28 // - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
29 // - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield
30 if (!PDM.begin(channels, frequency)) {
31 Serial.println("Failed to start PDM!");
32 while (1);
33 }
34}
35
36void loop() {
37 // Wait for samples to be read
38 if (samplesRead) {
39
40 // Print samples to the serial monitor or plotter
41 for (int i = 0; i < samplesRead; i++) {
42 if(channels == 2) {
43 Serial.print("L:");
44 Serial.print(sampleBuffer[i]);
45 Serial.print(" R:");
46 i++;
47 }
48 Serial.println(sampleBuffer[i]);
49 }
50
51 // Clear the read count
52 samplesRead = 0;
53 }
54}
55
56/**
57 * Callback function to process the data from the PDM microphone.
58 * NOTE: This callback is executed as part of an ISR.
59 * Therefore using `Serial` to print messages inside this function isn't supported.
60 * */
61void onPDMdata() {
62 // Query the number of available bytes
63 int bytesAvailable = PDM.available();
64
65 // Read into the sample buffer
66 PDM.read(sampleBuffer, bytesAvailable);
67
68 // 16-bit, 2 bytes per sample
69 samplesRead = bytesAvailable / 2;
70}

Open the Serial Monitor / Serial Plotter to see the data in real time.

Example sketch printing values in the serial monitor
Example sketch printing values in the serial monitor

Clap Detection Sketch (ArduinoGraphics)

This sketch uses the Arduino_Graphics library to change the color of the background when a loud noise is detected, such as a clap.

1#include "Arduino_H7_Video.h"
2#include "ArduinoGraphics.h"
3#include <PDM.h>
4
5Arduino_H7_Video Display(800, 480, GigaDisplayShield);
6
7// default number of output channels
8static const char channels = 1;
9
10// default PCM output frequency
11static const int frequency = 16000;
12
13// Buffer to read samples into, each sample is 16-bits
14short sampleBuffer[512];
15
16// Number of audio samples read
17volatile int samplesRead;
18
19void setup() {
20 Display.begin();
21 Display.beginDraw();
22 Display.background(255, 255, 255);
23 Display.clear();
24
25 PDM.onReceive(onPDMdata);
26
27 if (!PDM.begin(channels, frequency)) {
28 Serial.println("Failed to start PDM!");
29 while (1);
30 }
31 Display.endDraw();
32}
33
34int count = 1;
35
36void loop(){
37 int micValue;
38
39 if (samplesRead) {
40 // Print samples to the serial monitor or plotter
41 for (int i = 0; i < samplesRead; i++) {
42 micValue = sampleBuffer[i];
43 if(micValue > 10000){
44 clap_switch();
45 }
46 }
47 // Clear the read count
48 samplesRead = 0;
49 }
50}
51
52void clap_switch(){
53 Display.beginDraw();
54 switch(count){
55 case 1:
56 Display.clear();
57 Display.background(0, 0, 204);
58 break;
59
60 case 2:
61 Display.clear();
62 Display.background(255, 128, 0);
63 break;
64
65 case 3:
66 Display.clear();
67 Display.background(255, 255, 0);
68 break;
69 }
70 if(count == 3)
71 {
72 count = 0;
73 }
74 count++;
75 Display.endDraw();
76 delay(1000);
77}
78
79void onPDMdata() {
80 // Query the number of available bytes
81 int bytesAvailable = PDM.available();
82
83 // Read into the sample buffer
84 PDM.read(sampleBuffer, bytesAvailable);
85
86 // 16-bit, 2 bytes per sample
87 samplesRead = bytesAvailable / 2;
88}

After uploading a sketch, snap your fingers or clap your hands to produce a noise that meets the threshold. You should see the background color of the screen change.

Volume Indication Sketch (LVGL)

This sketch requires the lvgl library, please make sure that is installed before you upload the sketch. The sketch will show a bar on the screen that is animated when noise is made, functionally making it display the volume of the microphones readings. You will find the full sketch just below.

For more information about using LVGL with the GIGA Display Shield, take a look at our documentation here.

1#include <PDM.h>
2#include "Arduino_H7_Video.h"
3#include "lvgl.h"
4
5Arduino_H7_Video Display(800, 480, GigaDisplayShield);
6
7static void set_slider_val(void * bar, int32_t val) {
8 lv_bar_set_value((lv_obj_t *)bar, val, LV_ANIM_ON);
9}
10
11// default number of output channels
12static const char channels = 1;
13
14// default PCM output frequency
15static const int frequency = 16000;
16
17// Buffer to read samples into, each sample is 16-bits
18short sampleBuffer[512];
19
20// Number of audio samples read
21volatile int samplesRead;
22
23lv_obj_t * obj;
24lv_anim_t a;
25int micValue;
26
27void setup() {
28 Display.begin();
29
30 PDM.onReceive(onPDMdata);
31
32 if (!PDM.begin(channels, frequency)) {
33 Serial.println("Failed to start PDM!");
34 while (1);
35 }
36
37 // Create the bar
38 obj = lv_bar_create(lv_scr_act());
39 lv_obj_set_size(obj, 600, 50);
40 lv_obj_center(obj);
41 lv_bar_set_value(obj, 500, LV_ANIM_OFF);
42
43 // Create the animation for the bar
44 lv_anim_init(&a);
45 lv_anim_set_exec_cb(&a, set_slider_val);
46 lv_anim_set_time(&a, 300);
47 lv_anim_set_playback_time(&a, 300);
48 lv_anim_set_var(&a, obj);
49}
50
51void loop() {
52
53 // Wait for samples to be read
54 if (samplesRead) {
55
56 // Print samples to the serial monitor or plotter
57 for (int i = 0; i < samplesRead; i++) {
58 Serial.println(sampleBuffer[i]);
59 micValue = sampleBuffer[i];
60 micValue = micValue / 100;
61 if (micValue > 500)
62 {
63 micValue = 500;
64 }
65 lv_anim_set_values(&a, 0, micValue);
66 lv_anim_start(&a);
67 }
68
69 // Clear the read count
70 samplesRead = 0;
71 delay(10);
72 }
73 lv_timer_handler();
74}
75
76/**
77 * Callback function to process the data from the PDM microphone.
78 * NOTE: This callback is executed as part of an ISR.
79 * Therefore using `Serial` to print messages inside this function isn't supported.
80 * */
81void onPDMdata() {
82 // Query the number of available bytes
83 int bytesAvailable = PDM.available();
84
85 // Read into the sample buffer
86 PDM.read(sampleBuffer, bytesAvailable);
87
88 // 16-bit, 2 bytes per sample
89 samplesRead = bytesAvailable / 2;
90}

Next Step

Now that you know how to use the on-board microphone, feel free to explore the shield's other features, like the IMU with our Orientation tutorial. Or if you rather dive deeper into LVGL, take a look at our LVGL guide.

For the complete documentation for this shield, check out the GIGA Display Shield documentation page.

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.