Different sampling frequencies for Arduino Nano 33 Ble Sense

Hi,
The new edge impulse firmware of Arduino Nano 33 Ble Sense has the option of changing sampling frequencies during data collection to 4000Hz and 8000Hz in addition to 16000Hz.

I’m curious regarding how the sampling frequencies are changed since the pdm library allows only 16,000Hz and 41667Hz (https://github.com/arduino/ArduinoCore-nRF528x-mbedos/blob/master/libraries/PDM/src/PDM.cpp). Can someone please explain how edge impulse changes sampling frequencies?

Thank you!

Hi @dhruvilodhavia,

Here is where we calculate sampling rates for frequencies that are not 16000Hz in the Arduino Nano 33 BLE Sense firmware: https://github.com/edgeimpulse/firmware-arduino-nano-33-ble-sense/blob/master/src/sensors/ei_microphone.cpp#L475-L477

A note from our embedded team: “Since Arduino lib only support 2 frequencies, we hook into the nordic driver directly to get all wanted frequencies.”

1 Like

Hello! Does this mean that when deploying, are the available frequencies transferred to the board also when building Arduino library? Or only when building the firmware?

I have noticed in my project that while the firmware -version works well, the Arduino-library does not. The problem is that my model assumes 8000 hz input, and the Arduino-code works only if I change the EI_CLASSIFIER_FREQUENCY definition to 16000 (and the model loses its performance).

Replied by email but also adding the solution here for anyone interested.
The Arduino sketch needs to be modified in 2 places:

  1. Add following code after variables declaration:
extern "C" {
    #include <hal/nrf_pdm.h>
}

/* Private functions ------------------------------------------------------- */

/**
 * @brief PDM clock frequency calculation based on 32MHz clock and
 * decimation filter ratio 80
 * @details For more info on clock generation:
 * https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf5340%2Fpdm.html
 * @param sampleRate in Hz
 * @return uint32_t clk value
 */
static uint32_t pdm_clock_calculate(uint64_t sampleRate)
{
    const uint64_t PDM_RATIO = 80ULL;
    const uint64_t CLK_32MHZ = 32000000ULL;
    uint64_t clk_control = 4096ULL * (((sampleRate * PDM_RATIO) * 1048576ULL) / (CLK_32MHZ + ((sampleRate * PDM_RATIO) / 2ULL)));

    return (uint32_t)clk_control;
}
  1. Modify the microphone_inference_start function with:
    PDM.setBufferSize(4096);

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

        return false;
    }

    /* Calculate sample rate from sample interval */
    uint32_t audio_sampling_frequency = (uint32_t)(1000.f / EI_CLASSIFIER_INTERVAL_MS);

    if(audio_sampling_frequency != 16000) {
        nrf_pdm_clock_set((nrf_pdm_freq_t)pdm_clock_calculate(audio_sampling_frequency));
    }

    // set the gain, defaults to 20
    PDM.setGain(127);

Aurelien

2 Likes