Skip to content

Commit

Permalink
Add PDM library for Arduino Nano RP2040 Connect (#213)
Browse files Browse the repository at this point in the history
* Add PDM library for Arduino Nano RP2040 Connect

* No PDM test in CI, only works on Arduino Nano RP2040
  • Loading branch information
earlephilhower authored Jun 16, 2021
1 parent 6afcf58 commit b02b9c4
Show file tree
Hide file tree
Showing 13 changed files with 1,100 additions and 0 deletions.
83 changes: 83 additions & 0 deletions libraries/PDM/examples/PDMSerialPlotter/PDMSerialPlotter.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
This example reads audio data from the on-board PDM microphones, and prints
out 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:
- Arduino Nano 33 BLE board, or
- Arduino Nano RP2040 Connect, or
- Arduino Portenta H7 board plus Portenta Vision Shield
This example code is in the public domain.
*/

#include <PDM.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
short sampleBuffer[512];

// Number of audio samples read
volatile int samplesRead;

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

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

// Optionally set the gain
// Defaults to 20 on the BLE Sense and -10 on the Portenta Vision Shield
// PDM.setGain(30);

// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1);
}
}

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

// Print samples to the serial monitor or plotter
for (int i = 0; i < samplesRead; i++) {
if(channels == 2) {
Serial.print("L:");
Serial.print(sampleBuffer[i]);
Serial.print(" R:");
i++;
}
Serial.println(sampleBuffer[i]);
}

// 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 = PDM.available();

// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);

// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
27 changes: 27 additions & 0 deletions libraries/PDM/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#######################################
# Syntax Coloring Map PDM
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

PDM KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2

available KEYWORD2
read KEYWORD2

onReceive KEYWORD2

setGain KEYWORD2
setBufferSize KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
9 changes: 9 additions & 0 deletions libraries/PDM/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=PDM
version=1.0
author=Arduino
maintainer=Arduino <[email protected]>
sentence=Enables the communication with devices that use the PDM Bus. Specific implementation for nRF52.
paragraph=
category=Communication
url=
architectures=rp2040
68 changes: 68 additions & 0 deletions libraries/PDM/src/PDM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright (c) 2019 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef _PDM_H_INCLUDED
#define _PDM_H_INCLUDED

#include <Arduino.h>
//#include <pinDefinitions.h>

#include "utility/PDMDoubleBuffer.h"

class PDMClass
{
public:
PDMClass(int dinPin, int clkPin, int pwrPin);
virtual ~PDMClass();

int begin(int channels, int sampleRate);
void end();

virtual int available();
virtual int read(void* buffer, size_t size);

void onReceive(void(*)(void));

//PORTENTA_H7 min -12 max 51
//NANO 33 BLE SENSe min 0 max 80
void setGain(int gain);
void setBufferSize(int bufferSize);
size_t getBufferSize();

// private:
void IrqHandler(bool halftranfer);

private:
int _dinPin;
int _clkPin;
int _pwrPin;

int _channels;
int _samplerate;

int _gain;
int _init;

PDMDoubleBuffer _doubleBuffer;

void (*_onReceive)(void);
};
#ifdef PIN_PDM_DIN
extern PDMClass PDM;
#endif
#endif
Loading

0 comments on commit b02b9c4

Please sign in to comment.