micro_pdm.ino

Arduino Nicla Vision · File : micro_pdm.ino · Language : Arduino · Use case : Mesurer le niveau sonore avec le micro PDM

The board MEMS PDM microphone becomes a sound level meter: sampled at 16 kHz by the PDM library, the script computes peak-to-peak amplitude ten times a second. The base of a clap counter, sound trigger or acoustic presence detector.

Hardware

An Arduino Nicla Vision (STM32H7 M7+M4, 23×23 mm) with GC2145 camera, LSM6DSOX IMU, PDM mic, ToF (VL53Lx), ESP32 Wi-Fi/BLE module and RGB LED (LEDR/G/B). The board alone; the MP34DT06JTR is soldered on board. Test by clapping in front of the mic window.

Wiring

No wiring: the PDM mic is internal (CLK + DATA on the core dedicated bus).

How it works

PDM.begin(1, 16000) sets one channel at 16 kHz; the callback fills a short buffer, the loop extracts min/max outside interrupts (noInterrupts around the copy). Gain 20 suits voice.

Running it

Programmed from the Arduino IDE (ArduinoCore-mbed, NICLA_VISION target) over USB-C; Camera, PDM, Arduino_LSM6DSOX, WiFiNINA and ArduinoBLE libraries provided.

Variants

Compute RMS instead of peak for a truer dB, detect a clap by amplitude edge, or stream samples over BLE for a phone spectrum.

micro_pdm.ino

// Microphone PDM MEMS MP34DT06JTR embarqué.
// Bibliothèque PDM du core (identique au Nano 33 BLE Sense).

#include <PDM.h>

#define ECHANTILLONS 256
short tampon[ECHANTILLONS];
volatile int nDispo = 0;

void surDonneesPDM() {
  nDispo = PDM.available();
  PDM.read(tampon, nDispo);        // copié depuis l'IT : critique
}

void setup() {
  Serial.begin(115200);
  PDM.onReceive(surDonneesPDM);
  PDM.setGain(20);                 // gain 0-30, 20 = voix à 1 m
  if (!PDM.begin(1, 16000)) {      // 1 canal, 16 kHz
    Serial.println("PDM indisponible");
    while (1) { ; }
  }
}

void loop() {
  static unsigned long t = 0;
  if (millis() - t > 100) {        // crête-à-crête 10 fois/s
    t = millis();
    long minV = 32767, maxV = -32768;
    noInterrupts();
    for (int i = 0; i < nDispo / 2; i++) {
      if (tampon[i] < minV) minV = tampon[i];
      if (tampon[i] > maxV) maxV = tampon[i];
    }
    interrupts();
    Serial.print("crete=-"); Serial.print(-minV);
    Serial.print(" +"); Serial.println(maxV);
  }
}

← Back to the board