|
| 1 | +--- |
| 2 | +title: 'Controlling the On-Board RGB LED with Microphone' |
| 3 | +difficulty: intermediate |
| 4 | +compatible-products: [nano-33-ble-sense-rev2] |
| 5 | +description: 'Learn how to create a soundmeter using the built-in microphone on the Nano 33 BLE Sense Rev2.' |
| 6 | +tags: |
| 7 | + - Microphone |
| 8 | + - Sound |
| 9 | + - Sensor |
| 10 | +author: 'Fabricio Troya' |
| 11 | +libraries: |
| 12 | + - name: Arduino PDM |
| 13 | + url: https://www.arduino.cc/en/Reference/PDM |
| 14 | +hardware: |
| 15 | + - hardware/03.nano/boards/nano-33-ble-sense-rev2 |
| 16 | +software: |
| 17 | + - web-editor |
| 18 | + - ide-v1 |
| 19 | + - ide-v2 |
| 20 | +featuredImage: 'chip' |
| 21 | +--- |
| 22 | + |
| 23 | +In this tutorial we will use an **Arduino Nano 33 BLE Sense Rev2** board to measure and display the sound values of your surroundings, made possible by the embedded **MP34DT06JTR** sensor. |
| 24 | + |
| 25 | +> **Warning:** A very small percentage of people may experience a seizure when exposed to flashing lights or patterns. Even people who have no history of seizures or epilepsy may have an undiagnosed condition that can cause these “photosensitive epileptic seizures” while watching lights blinking fast. **Immediately stop and consult a doctor if you experience any symptoms.** |
| 26 | +
|
| 27 | + |
| 28 | +## Goals |
| 29 | + |
| 30 | +The goals of this project are: |
| 31 | + |
| 32 | +- Learn how to output raw sensor data from the Arduino Nano 33 BLE Sense Rev2. |
| 33 | +- Use the PDM(Pulse-density modulation) library. |
| 34 | +- Print sound values in the Serial Monitor. |
| 35 | +- Create your own RGB sound meter. |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | +## Hardware & Software Needed |
| 40 | +* Arduino Nano 33 BLE Sense Rev2. |
| 41 | +* This project uses no external sensors or components. |
| 42 | +* In this tutorial we will use the [Arduino Web Editor](https://create.arduino.cc/editor) to program the board. |
| 43 | + |
| 44 | + |
| 45 | + |
| 46 | +## The MP34DT06JTR Sensor |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +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. |
| 51 | + |
| 52 | +The MP34DT06JTR 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: |
| 53 | + |
| 54 | +- Signal-to-noise ratio: 64dB |
| 55 | +- Sensitivity: -26dBFS ±3dB |
| 56 | +- Temperature range: -40 to 85°C |
| 57 | + |
| 58 | +If you want to read more about the MP34DT06JTR sensor you can take a look at the <a href="https://docs.arduino.cc/resources/datasheets/MP34DT06JTR.pdf" target="_blank">datasheet</a>. |
| 59 | + |
| 60 | + |
| 61 | + |
| 62 | +## Creating the Program |
| 63 | + |
| 64 | +**1. Setting up** |
| 65 | + |
| 66 | +Let's start by opening the [Arduino Web Editor](https://create.arduino.cc/editor), click on the **Libraries** tab, search for the **PDM FOR MBED** library, then in **Examples**, open the **PDMSerialPlotter** example. Once the sketch is open, rename it as **Sound_Meter**. |
| 67 | + |
| 68 | + |
| 69 | + |
| 70 | +**2. Connecting the board** |
| 71 | + |
| 72 | +Now, connect the Arduino Nano 33 BLE Sense Rev2 to the computer to check that the Web Editor recognizes it, if so, the board and port should appear as shown in the image. If they don't appear, follow the [instructions](https://create.arduino.cc/getting-started/plugin/welcome) to install the plugin that will allow the Editor to recognize your board. |
| 73 | + |
| 74 | + |
| 75 | + |
| 76 | + |
| 77 | +**3. Printing and displaying sound values** |
| 78 | + |
| 79 | +Now we will need to modify the code of the example, in order to print the sound values and turn on a different LED based how noisy is the sound. |
| 80 | + |
| 81 | +Before the `setup()` there are two types of variables initialized. One is a `short` variable and the other is a `volatile int` variable. We use the `short` type variable to store 16-bit data-types as the `sampleBuffer[256]`. The other, `volatile`, is a keyword known as a variable qualifier. It is usually used before the datatype of a variable, in order to modify the way in which the compiler and subsequent program treat the variable. In this case, it directs the compiler to load the variable `samplesRead` from RAM and not from a storage register. |
| 82 | + |
| 83 | +```arduino |
| 84 | +#include <PDM.h> |
| 85 | +
|
| 86 | +// buffer to read samples into, each sample is 16-bits |
| 87 | +short sampleBuffer[256]; |
| 88 | +
|
| 89 | +// number of samples read |
| 90 | +volatile int samplesRead; |
| 91 | +``` |
| 92 | + |
| 93 | +In the `setup()`, we use the `PDM.conReceive()` function to configure the data receive callback. Lastly, the `PDM.begin()` sets the sensor to read data from just one channel and a sample rate of 16 kHz, this statement is inside an `if()` that will print a message, as a string, in case the sensor has not been properly initialized. |
| 94 | + |
| 95 | +```arduino |
| 96 | +void setup() { |
| 97 | + Serial.begin(9600); |
| 98 | + while (!Serial); |
| 99 | +
|
| 100 | + // configure the data receive callback |
| 101 | + PDM.onReceive(onPDMdata); |
| 102 | +
|
| 103 | + // optionally set the gain, defaults to 20 |
| 104 | + // PDM.setGain(30); |
| 105 | +
|
| 106 | + // initialize PDM with: |
| 107 | + // - one channel (mono mode) |
| 108 | + // - a 16 kHz sample rate |
| 109 | + if (!PDM.begin(1, 16000)) { |
| 110 | + Serial.println("Failed to start PDM!"); |
| 111 | + while (1); |
| 112 | + } |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +Then, in the `loop()`, let's modify the example code by adding the following portion of code inside the `for()` loop, after the `Serial.println()` function. |
| 117 | + |
| 118 | +```arduino |
| 119 | +// check if the sound value is higher than 500 |
| 120 | + if (sampleBuffer[i]>=500){ |
| 121 | + digitalWrite(LEDR,LOW); |
| 122 | + digitalWrite(LEDG,HIGH); |
| 123 | + digitalWrite(LEDB,HIGH); |
| 124 | + } |
| 125 | + // check if the sound value is higher than 250 and lower than 500 |
| 126 | + if (sampleBuffer[i]>=250 && sampleBuffer[i] < 500){ |
| 127 | + digitalWrite(LEDB,LOW); |
| 128 | + digitalWrite(LEDR,HIGH); |
| 129 | + digitalWrite(LEDG,HIGH); |
| 130 | + } |
| 131 | + //check if the sound value is higher than 0 and lower than 250 |
| 132 | + if (sampleBuffer[i]>=0 && sampleBuffer[i] < 250){ |
| 133 | + digitalWrite(LEDG,LOW); |
| 134 | + digitalWrite(LEDR,HIGH); |
| 135 | + digitalWrite(LEDB,HIGH); |
| 136 | + } |
| 137 | +``` |
| 138 | + |
| 139 | +With this portion of the code, we will turn on the RGB LED based on the amount of sound that the microphones is receiving. |
| 140 | + |
| 141 | +**4. Complete code** |
| 142 | + |
| 143 | +If you choose to skip the code building section, the complete code can be found below: |
| 144 | + |
| 145 | +```arduino |
| 146 | +/* |
| 147 | + This example reads audio data from the on-board PDM microphones, and prints |
| 148 | + out the samples to the Serial console. The Serial Plotter built into the |
| 149 | + Arduino IDE can be used to plot the audio data (Tools -> Serial Plotter) |
| 150 | +
|
| 151 | + Circuit: |
| 152 | + - Arduino Nano 33 BLE Sense Rev2 board |
| 153 | +
|
| 154 | + This example code is in the public domain. |
| 155 | +*/ |
| 156 | +
|
| 157 | +#include <PDM.h> |
| 158 | +
|
| 159 | +// buffer to read samples into, each sample is 16-bits |
| 160 | +short sampleBuffer[256]; |
| 161 | +
|
| 162 | +// number of samples read |
| 163 | +volatile int samplesRead; |
| 164 | +
|
| 165 | +void setup() { |
| 166 | + Serial.begin(9600); |
| 167 | + while (!Serial); |
| 168 | +
|
| 169 | + // configure the data receive callback |
| 170 | + PDM.onReceive(onPDMdata); |
| 171 | +
|
| 172 | + // optionally set the gain, defaults to 20 |
| 173 | + // PDM.setGain(30); |
| 174 | +
|
| 175 | + // initialize PDM with: |
| 176 | + // - one channel (mono mode) |
| 177 | + // - a 16 kHz sample rate |
| 178 | + if (!PDM.begin(1, 16000)) { |
| 179 | + Serial.println("Failed to start PDM!"); |
| 180 | + while (1); |
| 181 | + } |
| 182 | +} |
| 183 | +
|
| 184 | +void loop() { |
| 185 | + // wait for samples to be read |
| 186 | + if (samplesRead) { |
| 187 | +
|
| 188 | + // print samples to the serial monitor or plotter |
| 189 | + for (int i = 0; i < samplesRead; i++) { |
| 190 | + Serial.println(sampleBuffer[i]); |
| 191 | + // check if the sound value is higher than 500 |
| 192 | + if (sampleBuffer[i]>=500){ |
| 193 | + digitalWrite(LEDR,LOW); |
| 194 | + digitalWrite(LEDG,HIGH); |
| 195 | + digitalWrite(LEDB,HIGH); |
| 196 | + } |
| 197 | + // check if the sound value is higher than 250 and lower than 500 |
| 198 | + if (sampleBuffer[i]>=250 && sampleBuffer[i] < 500){ |
| 199 | + digitalWrite(LEDB,LOW); |
| 200 | + digitalWrite(LEDR,HIGH); |
| 201 | + digitalWrite(LEDG,HIGH); |
| 202 | + } |
| 203 | + //check if the sound value is higher than 0 and lower than 250 |
| 204 | + if (sampleBuffer[i]>=0 && sampleBuffer[i] < 250){ |
| 205 | + digitalWrite(LEDG,LOW); |
| 206 | + digitalWrite(LEDR,HIGH); |
| 207 | + digitalWrite(LEDB,HIGH); |
| 208 | + } |
| 209 | + } |
| 210 | +
|
| 211 | + // clear the read count |
| 212 | + samplesRead = 0; |
| 213 | + } |
| 214 | +} |
| 215 | +
|
| 216 | +void onPDMdata() { |
| 217 | + // query the number of bytes available |
| 218 | + int bytesAvailable = PDM.available(); |
| 219 | +
|
| 220 | + // read into the sample buffer |
| 221 | + PDM.read(sampleBuffer, bytesAvailable); |
| 222 | +
|
| 223 | + // 16-bit, 2 bytes per sample |
| 224 | + samplesRead = bytesAvailable / 2; |
| 225 | +} |
| 226 | +``` |
| 227 | + |
| 228 | + |
| 229 | + |
| 230 | +## Testing It Out |
| 231 | + |
| 232 | +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. |
| 233 | + |
| 234 | + |
| 235 | + |
| 236 | +If you want to test it, the only thing you need to do is to place the board next to a speaker and play some music to see how the colors of the RGB LED change based on the music. |
| 237 | + |
| 238 | + |
| 239 | + |
| 240 | +**Warning:** Remember that depending of the music, lights might blink too fast. **Immediately stop playing and consult a doctor if you experience any symptoms of “photosensitive epileptic seizures”.** |
| 241 | + |
| 242 | + |
| 243 | +### Troubleshoot |
| 244 | + |
| 245 | +Sometimes errors occur, if the project is not working as intended there are some common issues we can troubleshoot: |
| 246 | +- Missing a bracket or a semicolon. |
| 247 | +- If your Arduino board is not recognized, check that the Create plugin is running properly on your computer. |
| 248 | +- Accidental interruption of cable connection. |
| 249 | +- The sound of the music is too low or the board is too far from the speaker. |
| 250 | + |
| 251 | + |
| 252 | +## Conclusion |
| 253 | + |
| 254 | +In this simple tutorial we learned how to read sound values from the **MP34DT06JTR** sensor using the [PDM library](https://github.com/arduino/ArduinoCore-nRF528x-mbedos/tree/master/libraries/PDM), and how to use the sensor embedded in the Arduino Nano 33 BLE Sense Rev2 board in order to print out sound values from the environment and visualize them through the RGB LED. |
| 255 | + |
0 commit comments