Record audio with Nano 33 BLE Sense through terminal

Hello everyone,

after years of only-reading my first post since I have a problem and can't figure out what the problem is.

What I want to do:

  1. Record sound data with onboard PDM microphone on Nano 33 BLE Sense
  2. Use PDM library for it
  3. Print the data to the serial
  4. Use TeraTerm to log it to a file
  5. Import the raw data to audacity to save it as a .wav file

What I don't understand:

  1. There is a big questionmark when using the PDM library. The documentation is the most brief I ever saw. :smiley: And there is only one example which works "somehow" but I am not able to fully understand it.

a) I read a lot about PDM and PCM the last days. So there is this code to initialize the mic:

  // initialize PDM with:
  // - one channel (mono mode)
  // - a 16 kHz sample rate
  if (!PDM.begin(1, 16000)) {
    Serial.println("Failed to start PDM!");
    while (1);

as far as I know the PDM sample rate is somewhere in the 1 to 4 MHz area. So is here meant the PCM-sample-rate? 16kHz is a common rate for PCM so this would make sense... but then it's very confusing that this is called "PDM.begin" but there comes out a PCM signal...

b) When using the example which is provided by the arduino IDE (File -> Examples -> PDM -> PDMSerialPlotter) there should then be 16000 16 bit samples per second (?). But I only see about 600... What am I not understanding here?

c) If log this output and want to import it to audacity as 16bit signed with 16kHz I don't get any usable sound. But this audacity thing is at the moment not that important... I think the problem is somewhere before.

Thank you for hints and suggestions

I guess the Serial.print takes too much time so you end up missing/dropping a lot of samples each time you call it. Try changing the code so you accumulate samples in a buffer (array) and then print the whole buffer in one single Serial.print when you are done collecting samples (whenyou have either reached a timeout or the size of the buffer).

My understanding is the PDM.h library produces PDM data samples, not PCM samples.

PDM to PCM conversion requires filtering, which is not part of the PDM library, or part of ArduinoSound library. Please folks, tell me if I'm wrong.

Edit: I'm wrong. Its handled internally by the nRF52840 PDM module to do the conversion. See here

The nrf_pdm driver is used internally in the Arduino PDM implementation.

When using the example which is provided by the arduino IDE (File → Examples → PDM → PDMSerialPlotter) there should then be 16000 16 bit samples per second (?). But I only see about 600… What am I not understanding here?

I am not sure what program you have is it called PDMSerialPlotter?

If so then yes the sample rate to 16KHz. But it does not do continuous sampling. What it does is to take 256 samples and place them in a buffer and then send them out to the serial port for display on the serial plotter. So you have a snatch of 256 samples, which at 16KHz represents 0.016th of a second of audio. It then goes back and takes another 256 samples. So all the time it has spent outputting the samples is lost along with the audio it represents. So by recording these small snatches of sound is not going to give you the full waveform.

Now this processor has a lot of free memory, you will see this example uses

42744 bytes (16%) of dynamic memory, leaving 219400 bytes for local variables.

So if you use a buffer of 21900 bytes that is enough for 21900 / 2 = 109500 samples giving you a sample time of 6.8 seconds. Although you might not be able to get a buffer that big and have to cut it down…

Note the baud rate has nothing to do with the actual transfer rate on this processor, or any other that establishes a direct USB serial interface.