Главная chevron_right Уроки chevron_right Встроенные библиотеки chevron_right Библиотека PDM

Библиотека PDM

Библиотека PDM позволяет работать с PDM-микрофонами, встроенными на платах Arduino Nano RP2040 Connect и Nano 33 BLE Sense.

Обзор

Библиотека PDM предназначена для работы с PDM-микрофонами (Pulse-density modulation), в том числе со встроенным микрофоном MP34DT05 на плате Arduino Nano 33 BLE Sense.

Чтобы подключить библиотеку в скетч:

#include <PDM.h>

Библиотека берёт на себя всю работу с аудиопотоком, который также становится доступен через библиотеку ArduinoSound.

Как это работает

PDM (Pulse-Density Modulation) — метод представления аналогового сигнала в виде последовательности импульсов. Микрофоны на его основе компактны, потребляют мало энергии и отлично подходят для встраивания прямо в плату. Библиотека принимает поток данных от микрофона, накапливает его в буфере и уведомляет скетч через callback-функцию, когда данные готовы к чтению.

---

Функции

begin()

Описание

Инициализирует PDM-интерфейс и запускает приём данных с микрофона.

Синтаксис

PDM.begin(channels, sampleRate)

Параметры

  • channels — количество каналов: 1 для моно, 2 для стерео
  • sampleRate — частота дискретизации в Гц

Возвращает

1 при успехе, 0 при ошибке

Пример

  if (!PDM.begin(1, 16000)) {
    Serial.println("Failed to start PDM!");
    while (1);
  }

Практическое замечание. Вызывайте begin() только после того, как задали setBufferSize() и зарегистрировали callback через onReceive(). Если begin() вернул 0, проверьте, правильно ли выбрана плата в Arduino IDE — библиотека PDM поддерживается только на совместимых платах (Nano 33 BLE Sense, Nano RP2040 Connect и аналогичных).

---

end()

Описание

Останавливает PDM-интерфейс и освобождает занятые ресурсы.

Синтаксис

PDM.end()

Параметры

Отсутствуют

Возвращает

Ничего

Пример

  if (!PDM.begin(1, 16000)) {
    Serial.println("Failed to start PDM!");
    while (1);
  }


  // 

  PDM.end();

---

available()

Описание

Возвращает количество байт, доступных для чтения из PDM-буфера. Это данные, которые уже поступили от микрофона и сохранены в буфере приёма.

Синтаксис

PDM.available()

Параметры

Отсутствуют

Возвращает

Количество байт, готовых к чтению

Пример

// буфер для чтения сэмплов, каждый сэмпл 16-битный
short sampleBuffer[256];

// количество считанных сэмплов
volatile int samplesRead;

// 

  // запрос количества доступных байт
  int bytesAvailable = PDM.available();

  // чтение в буфер сэмплов
  PDM.read(sampleBuffer, bytesAvailable);

Типичная ошибка. Не вызывайте available() в основном цикле без callback — данные могут появляться нерегулярно. Лучший подход: проверять available() внутри функции, зарегистрированной через onReceive().

---

read()

Описание

Читает данные из PDM-буфера в указанный массив.

Синтаксис

PDM.read(buffer, size)

Параметры

  • buffer — массив для хранения принятых PDM-данных
  • size — количество байт для чтения

Возвращает

Фактическое количество прочитанных байт

Пример

// буфер для чтения сэмплов, каждый сэмпл 16-битный
short sampleBuffer[256];

// количество считанных сэмплов
volatile int samplesRead;

// 

  // запрос количества доступных байт
  int bytesAvailable = PDM.available();

  // чтение в буфер сэмплов
  Int bytesRead = PDM.read(sampleBuffer, bytesAvailable);

  // 16-bit, 2 байта на сэмпл
  samplesRead = bytesRead / 2;

Практическое замечание. Данные поступают в виде 16-битных сэмплов (int16_t). Если вы объявляете буфер как массив short или int16_t, передавайте в size значение sizeof(buffer), а не количество элементов — иначе прочитаете вдвое меньше данных, чем ожидаете.

---

onReceive()

Описание

Регистрирует callback-функцию, которая вызывается автоматически, когда новая порция PDM-данных готова к чтению.

Синтаксис

PDM.onReceive(callback)

Параметры

callback — функция без параметров и возвращаемого значения, вызываемая при поступлении новых данных

Возвращает

Ничего

Пример

// буфер для чтения сэмплов, каждый сэмпл 16-битный
short sampleBuffer[256];

// количество считанных сэмплов
volatile int samplesRead;

// 

  // настройка callback-функции приёма данных
  PDM.onReceive(onPDMdata);

  // инициализация PDM:
  // - один канал (моно режим)
  // - частота дискретизации 16 kHz
  if (!PDM.begin(1, 16000)) {
    Serial.println("Failed to start PDM!");
    while (1);
  }


  // 

void onPDMdata() {
  // запрос количества доступных байт
  int bytesAvailable = PDM.available();

  // чтение в буфер сэмплов
  Int bytesRead = PDM.read(sampleBuffer, bytesAvailable);

  // 16-bit, 2 байта на сэмпл
  samplesRead = bytesRead / 2;
}

Как проверить результат. Добавьте в callback-функцию вывод в Serial.print() — если данные поступают, вы увидите ненулевые значения available(). Отсутствие вызовов callback обычно означает, что begin() не был выполнен успешно.

---

setGain()

Описание

Устанавливает коэффициент усиления (gain) PDM-интерфейса. Влияет на громкость и чувствительность микрофона.

Синтаксис

PDM.setGain(gain)

Параметры

gain — значение усиления от 0 до 255; если не задано, используется значение по умолчанию — 20

Возвращает

Ничего

Пример

  // при необходимости задайте усиление, по умолчанию 20
  PDM.setGain(30);

  // инициализация PDM:
  // - один канал (моно режим)
  // - частота дискретизации 16 kHz
  if (!PDM.begin(1, 16000)) {
    Serial.println("Failed to start PDM!");
    while (1);
  }

Практическое замечание. Слишком высокий gain приводит к клиппингу (искажению) сигнала: сэмплы будут «упираться» в максимальные значения int16_t. Начните с 20–40 и увеличивайте постепенно, наблюдая за формой сигнала.

---

setBufferSize()

Описание

Задаёт размер буфера (в байтах), используемого PDM-интерфейсом. Должна вызываться до PDM.begin(). Если не вызывать, используется буфер по умолчанию — 512 байт, что достаточно для хранения 256 16-битных сэмплов.

Синтаксис

PDM.setBufferSize(size)

Параметры

size — размер буфера в байтах

Возвращает

Ничего

Пример

  PDM.setBufferSize(1024);

  // инициализация PDM:
  // - один канал (моно режим)
  // - частота дискретизации 16 kHz
  if (!PDM.begin(1, 16000)) {
    Serial.println("Failed to start PDM!");
    while (1);
  }

Практическое замечание. Увеличение буфера снижает частоту вызовов callback и уменьшает нагрузку на процессор, но увеличивает задержку обработки. Для задач реального времени (например, определения уровня звука) буфер по умолчанию обычно оптимален. Для записи и FFT-анализа имеет смысл увеличить его до 1024 или 2048 байт.