micro_pdm.ino
Le micro MEMS PDM de la carte sert de sonomètre : échantillonné en 16 kHz par la bibliothèque PDM, le script calcule l’amplitude crête à crête dix fois par seconde. Base d’une applaudimètre, d’un déclencheur au claps ou d’un détecteur de présence sonore.
Matériel requis
Une Arduino Nicla Vision (STM32H7 double cœur M7+M4, 23×23 mm) avec caméra GC2145 2 MP, IMU LSM6DSOX, micro PDM, capteur ToF (famille VL53Lx), module sans fil ESP32 (Wi-Fi/BLE) et LED RGB (LEDR=23, LEDG=24, LEDB=25). La carte seule ; le MP34DT06JTR est soudé sur la carte. Un testeur : taper dans les mains devant la fenêtre micro.
Câblage
Aucun câblage : le micro PDM est interne (CLK + DATA sur le bus dédié du core).
Fonctionnement
PDM.begin(1, 16000) configure un canal 16 kHz ; le callback rempli le tampon court, la boucle en extrait min/max hors interruption (noInterrupts autour de la copie). Le gain 20 convient à la voix.
Exécution
Programmation via Arduino IDE (core ArduinoCore-mbed, target NICLA_VISION) sur le port USB-C ; bibliothèques Camera, PDM, Arduino_LSM6DSOX, WiFiNINA et ArduinoBLE fournies.
Variantes
Calculer le RMS plutôt que la crête pour un dB plus fidèle, détecter un claps par front d’amplitude, ou envoyer les échantillons en BLE pour un spectre sur téléphone.
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);
}
}