Variable PDM Microphone Sample Rates on nRF52840 Sense

Hey everyone!

I’ve been using the PDM microphone on the XIAO nRF52840 sense to record audio data. It samples data at a rate of 16 kHz meaning it can process frequencies up to around 8 kHz (has two readings on each wave). My firmware fills an integer buffer of length 32,767 with PCM data, then writes it out to an SD card.

My audio recording application only needs to capture frequencies from 0 kHz up to 2 kHz - 4 kHz. Is it possible to reduce the 16 kHz sample frequency to 4 kHz - 8 kHz to increase time between SD writes to conserve battery life? In my testing, I can change PDM_SAMPLE_RATE to be different from 16000, but it doesn’t record any audio data.

if (!PDM.begin(1, PDM_SAMPLE_RATE)) {     // mono 16000 samples/sec
    Serial.println("Failed to start PDM!");
  }

PDM Library

Thanks in advance!

Hi cam,

See PDM.cpp starting at line 86. Only 16000 and 41667 sample rates are supported.
For example, if you want to sample at 8 kHz, set the sample rate to 16 kHz and record the data to the SD card every two times, you will have sampled at 8 kHz.

I measured the average current per minute.
It was 17 mA at 16 kHz, 14 mA at 8 kHz, and 10 mA with the on-chip DCDC converter enabled.

To enable DCDC, add the following line to setup()

NRF_POWER->DCDCEN = 1; // enable on chip DCDC converter

Do you mean to disregard every other reading?

Please see line 70 of the attached file.
POST_nRF52_XIAO_PDM_SD_8kHz.zip (1.4 KB)

Do you mean to disregard every other reading?

What do you mean by “every other reading”?

Hello! I’m a bit confused with exactly the below line does. Are you able to elaborate?

fifo.lockedPop(temp);

Can the same effect be created using a decimation factor of 2 or down sampling? My sketch reads the PCM value into a buffer and saves them to the SD card. Essentially each row of the SD text file is a separate PCM reading. I then modify the header files to convert it to a WAV file.

I had mentioned something about disregarding every other reading, but this was incorrect of me to say due to my lack of understanding.

Thanks in advance!

I’m a bit confused with exactly the below line does

Documentation can be found at this link.
GitHub - Locoduino/RingBuffer: A RingBuffer library for Arduino

Can the same effect be created using a decimation factor of 2 or down sampling?

I think it would have the same effect, but I don’t see how you are going to implement it specifically; would it cut the number of writes to SD in half?

I haven’t yet created an implementation with decimation or down sampling, but I did use the ring buffer library similar to your implementation. It’s giving me an issue now, such that the audio is both pitched and sped up, still at a 16khz sample rate. The good news is that the audio is much clearer and doesn’t have as much graininess. I’m hoping I can fix the sample rate soon.

For easy downsampling, you can use the application linked below.

Record the PDM data sampled at 16 kHz, thinned down to every other one, as a TXT file with no header on an SD card. Import it into the application, specifying 8 kHz. After importing, you can check the sound, edit the waveform, and export it as an 8kHz WAV file with a header.

https://www.audacityteam.org/

I see, thank you! Also, do you know if its possible to increase the buffer size? Maybe to 65535?

According to the PDM library, setBufferSize(int bufferSize), so I think 32767 is the maximum.