Recording PDM data of XIAO nRF52840 Sense to SD card

I recorded PDM data to an SD card for practice. I hope this will be helpful for those who are interested. To record PDM data to SD card, several measures were necessary.

  1. Flush after each block recording to prevent file corruption.
  2. Prepare a sampleBuffer of 1000mS to match the 400mS write and flush time.
  3. Use a FIFO for 1000mS to prevent data loss due to SD’s long write time of 1500mS that sometimes occurs.
  4. speed up SD’s SPI clock as much as possible
  5. minimize the gain to prevent data overflow because the microphone is highly sensitive.

The SD contains PCM data with 16-bit 16 kHz sampling; I used Audacity’https://www.audacityteam.org/’ to convert it to WAV format. Unfortunately, the sound quality is far from HiFi.
Note: If the microphone input is even slightly too loud, the data will overflow and noise will be recorded.

Here are the sketches and sample WAV files used in the experiment.
POST_nRF52_XIAO_PDM_SD.zip (384.7 KB)

3 Likes

Hello! I was able to create a similar program to yours, and I had a few questions that you may be able to answer.

Have you recorded the current draw at all for your program?
Why do higher amplitude recordings cause skips/clipping in the audio? How can this be combatted? (An issue in my code)

Thanks!

Current consumption when 3.8V is applied to the battery pad. The average current is 15 mA and the peak is 60 mA.
If the recording clips even with minimal gain, how about reducing the sound input by plugging the microphone hole or moving the microphone away from the sound source?

Thanks for the graph! I have tried moving the device further away from the source, and while this does work, I want to ensure my device can log as much data as possible.

Audio analysis is fairly new to me, and I was wondering what causes the clipping? Additionally, for further clarification, does PDM.setGain(0); set the gain to -20dB? Is that the lowest setting?

Thank you in advance!

does PDM.setGain(0); set the gain to -20dB? Is that the lowest setting?

setGain(0); sets the gain to -20dB.

If you import the waveform into Audacity and check the waveform, you can see how it clips and inverts.

Thank you for your help!

There were some problems with the sketch attached to post 1, which have been corrected. In addition, it is now recorded in WAVE format. The changes are as follows

  1. setGain() is executed after the begin() since the gain is set to the default value in the begin()
  2. Change data writing to little-endian format
  3. Review PDM buffer size and FIFO size
  4. Use SD with the fastest write speed possible
  5. Record in WAVE format.

For example, you can import the waveforms into the application “Audacity” to edit, check, and play back. After editing, the waveform can be exported in wave format.

The timing of reading PDM data and writing to SD was checked with a digital scope.

  1. PDM data is pushed from the PDM buffer to the FIFO every 16mS for 200uS
  2. In most cases, the data is popped every 16mS and written to SD over 6mS
  3. In rare cases, it takes over 500mS to write to the SD

So I needed FIFO which will not overflow, If FIFO overflow, the red LED will blink 5 times, so please increase FIFO size.

POST_nRF52_XIAO_PDM_WAVE_SD.zip (2.4 KB)

HI there,
Could I use the expansion Flash chip if installed on the Grove Expansion board? as FIFO or fast storage for this?
The board Flash speed is fast so what is a big size of a wav file? Then at a more convenient time move to SD card (external flash no fear to overwrite on-board flash and corrupt?)
Curious
GL :slight_smile: PJ
:v:

XIAO’s onboard flash P25Q16H is 2MB, so it can record about 2 hours. I think the flash seems to have a shorter write time than SD, but sometimes it takes a long time to write and I think a FIFO is needed.
I plan to experiment with external 16MB flash in the future.

edit
I was mistaken. At 16000 samples/sec, a 2MB flash only has the capacity for 2 minutes.

2 Likes

I am planning a project to record voice data to a small on-board Flash or transmit it in real-time via BLE. To do this I experimented with limiting the bandwidth of the signal to 2 kHz, or reducing the sample frequency.

The PDM library does not support sample frequencies below fs=16kHz, so I used a FIFO to achieve 1/4 down-sampling. To prevent fold-back noise due to sampling, it was necessary to attenuate components above fs/2=2kHz, so a low-pass filter with a cutoff frequency of fc=1.5kHz was provided.

The filter was designed using the online tool “TFilter” and implemented as a 32nd order FIR filter with fc=1.5kHz and a stopband of -40dB. The filter excution time was 9.4uS.
The resulting spectrum were compared. The fs=16kHz spectrum output from the PDM contains components up to 8kHz, while the spectrum down-sampled to fs=4kHz shows that the bandwidth is limited to 2kHz. The sound quality of the two can be compared in the attached wave file. Even a bandwidth of 2 kHz would be sufficient for a voice signal.

The PDM outputs 256 data samples collectively every 16mS. It takes 2.5mS to pass through the low-pass filter and push into the FIFO. The FIFO is popped 4 times and recorded to SD only once, resulting in 1/4 down-sampling.
In most cases it takes only 650uS to pop and write, and 256 data pushed every 16mS will pop all in 16mS. In very rare cases, writing to SD takes so long that not all data can be popped every 16mS. It is necessary to ensure that the FIFO has enough capacity not to overflow.

The following libraries and tools are being used. Thanks.

RingBuffer by Jean-Lue - Locoduino 1.0.5
FIR filter by Leeman Geophysical LLC 0.1.1
FIR filter designed with http://t-filter.engineerjs.com/
\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.8\libraries\PDM\src
\Arduino15\packages\Seeeduino\hardware\mbed\2.9.2\libraries\PDM\examples\PDMSavedOnSDcard\PDMSavedOnSDcard.ino

The sketches and sample wave files used in the experiments can be found here.
POST_nRF52_XIAO_PDM_4k_WAV.zip (1.4 MB)

you can also try using IIS … pronounced I 2 S

Hi there,
This is VERY interesting and sparks the question to me what about setting up a DMA transfer for the fifo?
is that any advantage?, how much time impact? does the pushing and popping to fifo would it impact in timing.?
Nice deep dive here.
Awesome stuff my guy :+1:
GL :slight_smile: PJ
:v:

In my application I need to record the data to SD or Flash for later analysis . I suspect that the occasional recording across sector or bank is taking more than the normal write time. To absorb the difference from the 16mS timing output by PDM, I need to use FIFO. Since the execution time for the FIFO push or pop is 1uS at most, I never thought of using DMA. Of course, as an amateur programmer, I could never build a FIFO using DMA!

Hi there,
I would agree after listening too (lol, digresing to say I used to record BIG Band in Pittsburgh back in the day, your sample Donna Lee(live) they did a lot of The Count Basie Orchestra stuff I still have some 10" R2R of it ) looking at it from one master device recording and transferring all the data, you would need an intermediary controller. We used DMA for Highspeed sampling with Labview Software in a DAQ environment and had an FPGA to handle the actual reading and writing the memory location independent, only pushing a beginning memory address and the pushing/reading and popping/writing was under the control of the FPGA.
the main code would only need to be sure buffer space was available. In the case of PDM data almost need some kind of cycle stealing DMA to never miss a byte. sounds like killing a fly with a shotgun.
in this case it’s a bandwidth more leaning task requirement maybe. Gave me a head rush though thanks… :grin:
perhaps a dual ended external flash or something would/could be used? good stuff.

GL :slight_smile: PJ
:v:

My guy was Tim Rodgers and his make believe ballroom Orchestra & swing band…btw love that era sound, so clean and pure :+1:

:heart_eyes:

2 Likes

The sample is “Donna Lee” Orchestra U.S.A. live in Carnegie Hall, 1963.

1 Like

:smile: recorded several great gigs at Heinz Hall in the Burgh, Pittsburgh.
One was for the USA ski team Gala, 4.5 hrs some of the greatest talents i have ever witnessed, later we rolled up to the greatest the second spot, the Stanley Theater. Those days the benefits where the “shazizle” :star_struck:

GL :slight_smile: PJ :+1:

1 Like