Skip to content

Breakout PDM #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions examples/PDMRootMeanSquare/PDMRootMeanSquare.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
This example reads audio data from the connected PDM microphone, and prints
out the RMS value of the samples to the Serial console. The Serial Plotter
built into the Arduino IDE can be used to plot the audio data (Tools ->
Serial Plotter)

Circuit:
- Portenta Breakout

This example code is in the public domain.
*/

#include <Arduino_PortentaBreakoutCarrier.h>

// default number of output channels
static const char channels = 1;

// default PCM output frequency
static const int frequency = 16000;

// Buffer to read samples into, each sample is 16-bits.
// Size in bytes must be a power of 2, grater or equal than PDM buffer size.
short sampleBuffer[2048];

// Number of audio samples read
volatile int samplesRead;

void setup() {
Serial.begin(9600);
while (!Serial);

// Configure the data receive callback
Breakout.PDM.onReceive(onPDMdata);

// Configure BufferSize to 4096 bytes
Breakout.PDM.setBufferSize(4096);

// Optionally set the gain, default value is 24
Breakout.PDM.setGain(24);

// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate
if (!Breakout.PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1);
}
}

void loop() {
// Wait for samples to be read
if (samplesRead == 2048) {

// Compute RMS value
double rms = RMS(sampleBuffer, samplesRead);

Serial.println(rms);

// Clear the read count
samplesRead = 0;
}
}

/**
* Callback function to process the data from the PDM microphone.
* NOTE: This callback is executed as part of an ISR.
* Therefore using `Serial` to print messages inside this function isn't supported.
* */
void onPDMdata() {
// Query the number of available bytes
int bytesAvailable = Breakout.PDM.available();

if(samplesRead < 2048) {
// Read into the sample buffer
Breakout.PDM.read(sampleBuffer, bytesAvailable);

// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
}

/**
* Compute RMS value of the input samples block
*/
double RMS(short Samples[], int Length) {
double sum = 0;
int i;
for(i = 0; i < Length; i++) {
sum += Samples[i] * Samples[i];
}
return sqrt(sum / Length);
}
5 changes: 4 additions & 1 deletion src/Arduino_PortentaBreakoutCarrier.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <mbed.h>
#include <Wire.h>
#include <SPI.h>
#include <PDM.h>
#include "utility/Analog/Analog.h"

#define LAST_ARDUINO_PIN_NUMBER LEDB + 1
Expand Down Expand Up @@ -247,14 +248,16 @@ class BreakoutCarrierClass {
UART UART2;
UART UART3;
MbedSPI SPI_0;
PDMClass PDM;
BreakoutCarrierClass() : I2C_0(PH_8,PH_7),
I2C_1(PB_7,PB_6),
I2C_2(PH_12,PH_11),
UART0(PA_0, PI_9, NC/*PI_10*/, NC/*PI_13*/),
UART1(PA_9, PA_10, NC/*PI_14*/, NC/*PI_15*/),
UART2(PG_14, PG_9, NC, NC),
UART3(PJ_8, PJ_9, NC, NC),
SPI_0(PC_2, PC_3, PI_1)
SPI_0(PC_2, PC_3, PI_1),
PDM(PB_2, PE_2, NC)
{
}
};
Expand Down