micro_pdm.ino

Arduino Nicla Vision · Archivo : micro_pdm.ino · Lenguaje : Arduino · Uso : Mesurer le niveau sonore avec le micro PDM

El micrófono PDM MEMS de la placa sirve de sonómetro: muestreado a 16 kHz por la librería PDM, el script calcula la amplitud pico a pico diez veces por segundo. Base de un contador de palmas, disparador por sonido o detector de presencia acústica.

Hardware

Una Arduino Nicla Vision (STM32H7 M7+M4, 23×23 mm) con cámara GC2145, IMU LSM6DSOX, micrófono PDM, ToF (VL53Lx), módulo ESP32 Wi-Fi/BLE y LED RGB (LEDR/G/B). La placa sola; el MP34DT06JTR va soldado. Prueba: aplaudir frente a la ventana del micro.

Cableado

Sin cableado: el micro PDM es interno (CLK + DATA en el bus dedicado del core).

Funcionamiento

PDM.begin(1, 16000) configura un canal a 16 kHz; el callback llena un búfer corto y el bucle extrae min/max fuera de interrupción (noInterrupts durante la copia). El ganancia 20 vale para voz.

Ejecución

Programación desde Arduino IDE (core ArduinoCore-mbed) por USB-C; librerías Camera, PDM, LSM6DSOX, WiFiNINA y ArduinoBLE.

Variantes

Calcular RMS en vez de pico para un dB más fiel, detectar una palmada por frente de amplitud, o enviar muestras por BLE para un espectro en el teléfono.

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);
  }
}

← Volver a la ficha