Skip to content

Commit ada6bf7

Browse files
authored
Merge pull request #12 from pennam/breakout_pdm
Breakout PDM
2 parents 792c092 + ecfb394 commit ada6bf7

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
This example reads audio data from the connected PDM microphone, and prints
3+
out the RMS value of the samples to the Serial console. The Serial Plotter
4+
built into the Arduino IDE can be used to plot the audio data (Tools ->
5+
Serial Plotter)
6+
7+
Circuit:
8+
- Portenta Breakout
9+
10+
This example code is in the public domain.
11+
*/
12+
13+
#include <Arduino_PortentaBreakoutCarrier.h>
14+
15+
// default number of output channels
16+
static const char channels = 1;
17+
18+
// default PCM output frequency
19+
static const int frequency = 16000;
20+
21+
// Buffer to read samples into, each sample is 16-bits.
22+
// Size in bytes must be a power of 2, grater or equal than PDM buffer size.
23+
short sampleBuffer[2048];
24+
25+
// Number of audio samples read
26+
volatile int samplesRead;
27+
28+
void setup() {
29+
Serial.begin(9600);
30+
while (!Serial);
31+
32+
// Configure the data receive callback
33+
Breakout.PDM.onReceive(onPDMdata);
34+
35+
// Configure BufferSize to 4096 bytes
36+
Breakout.PDM.setBufferSize(4096);
37+
38+
// Optionally set the gain, default value is 24
39+
Breakout.PDM.setGain(24);
40+
41+
// Initialize PDM with:
42+
// - one channel (mono mode)
43+
// - a 16 kHz sample rate
44+
if (!Breakout.PDM.begin(channels, frequency)) {
45+
Serial.println("Failed to start PDM!");
46+
while (1);
47+
}
48+
}
49+
50+
void loop() {
51+
// Wait for samples to be read
52+
if (samplesRead == 2048) {
53+
54+
// Compute RMS value
55+
double rms = RMS(sampleBuffer, samplesRead);
56+
57+
Serial.println(rms);
58+
59+
// Clear the read count
60+
samplesRead = 0;
61+
}
62+
}
63+
64+
/**
65+
* Callback function to process the data from the PDM microphone.
66+
* NOTE: This callback is executed as part of an ISR.
67+
* Therefore using `Serial` to print messages inside this function isn't supported.
68+
* */
69+
void onPDMdata() {
70+
// Query the number of available bytes
71+
int bytesAvailable = Breakout.PDM.available();
72+
73+
if(samplesRead < 2048) {
74+
// Read into the sample buffer
75+
Breakout.PDM.read(sampleBuffer, bytesAvailable);
76+
77+
// 16-bit, 2 bytes per sample
78+
samplesRead = bytesAvailable / 2;
79+
}
80+
}
81+
82+
/**
83+
* Compute RMS value of the input samples block
84+
*/
85+
double RMS(short Samples[], int Length) {
86+
double sum = 0;
87+
int i;
88+
for(i = 0; i < Length; i++) {
89+
sum += Samples[i] * Samples[i];
90+
}
91+
return sqrt(sum / Length);
92+
}

src/Arduino_PortentaBreakoutCarrier.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3131
#include <mbed.h>
3232
#include <Wire.h>
3333
#include <SPI.h>
34+
#include <PDM.h>
3435
#include "utility/Analog/Analog.h"
3536

3637
#define LAST_ARDUINO_PIN_NUMBER LEDB + 1
@@ -247,14 +248,16 @@ class BreakoutCarrierClass {
247248
UART UART2;
248249
UART UART3;
249250
MbedSPI SPI_0;
251+
PDMClass PDM;
250252
BreakoutCarrierClass() : I2C_0(PH_8,PH_7),
251253
I2C_1(PB_7,PB_6),
252254
I2C_2(PH_12,PH_11),
253255
UART0(PA_0, PI_9, NC/*PI_10*/, NC/*PI_13*/),
254256
UART1(PA_9, PA_10, NC/*PI_14*/, NC/*PI_15*/),
255257
UART2(PG_14, PG_9, NC, NC),
256258
UART3(PJ_8, PJ_9, NC, NC),
257-
SPI_0(PC_2, PC_3, PI_1)
259+
SPI_0(PC_2, PC_3, PI_1),
260+
PDM(PB_2, PE_2, NC)
258261
{
259262
}
260263
};

0 commit comments

Comments
 (0)