Xiao Seeed nRF52840 Sense - problem reading microphone data

Hi all,

I am having difficulties reading microphone data using built-in microphone at Xiao Seeed nRF52840 Sense. I have configured the overlay file as suggested here. Then used one of the examples - https://gist.github.com/hlord2000/52949ffc1650bb91f2170a4ac160ebae. The project file includes the following switches:

CONFIG_GPIO=y
CONFIG_FPU=y
CONFIG_PWM=y

# Enable audio subsystem
CONFIG_AUDIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED=y
CONFIG_AUDIO_DMIC=y

# Enable Logging and RTT Backend
CONFIG_LOG=y

The code is compiled ok

west build --build-dir /Users/jaroslavpsenicka/Projects/nrf/blinky/build /Users/jaroslavpsenicka/Projects/nrf/blinky --pristine --board xiao_ble/nrf52840/sense --sysbuild -- -DCONF_FILE="prj.conf" -DDTC_OVERLAY_FILE=boards/seeed_xiao_nrf52840.overlay

... 

-- Zephyr version: 4.1.99 (/opt/nordic/ncs/v3.1.1/zephyr), build: ncs-v3.1.1
[181/181] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       66084 B       788 KB      8.19%
             RAM:       45824 B       256 KB     17.48%
        IDT_LIST:          0 GB        32 KB      0.00%
Generating files from /Users/jaroslavpsenicka/Projects/nrf/blinky/build/blinky/zephyr/zephyr.elf for board: xiao_ble
Converted to uf2, output size: 132608, start address: 0x27000
Wrote 132608 bytes to zephyr.uf2
[10/10] Generating ../merged.hex

and flashed using my Raspberry Pico-based OCD 

openocd -f interface/cmsis-dap.cfg -f target/nrf52.cfg -c "program build/merged.hex verify" -c "reset run"

When executed, the microphone does not react to sound and produces output like so:

[00:51:40.001,464] <inf> dmic_sample: RMS: 0.015731
[00:51:40.101,470] <inf> dmic_sample: RMS: 0.015731
[00:51:40.201,477] <inf> dmic_sample: RMS: 0.015731
[00:51:40.301,483] <inf> dmic_sample: RMS: 0.015731

The code runs OK and I can attach the debugger and control the execution, however, the data seems to be stale - after a short period right after the restart:

[00:00:01.330,841] <inf> dmic_sample: RMS: 0.029410
[00:00:01.430,847] <inf> dmic_sample: RMS: 0.023021
[00:00:01.530,853] <inf> dmic_sample: RMS: 0.019408
[00:00:01.630,828] <inf> dmic_sample: RMS: 0.017508
[00:00:01.730,865] <inf> dmic_sample: RMS: 0.016566
[00:00:01.830,841] <inf> dmic_sample: RMS: 0.016117
[00:00:01.930,847] <inf> dmic_sample: RMS: 0.015907
[00:00:02.030,853] <inf> dmic_sample: RMS: 0.015811
[00:00:02.130,828] <inf> dmic_sample: RMS: 0.015767
[00:00:02.230,865] <inf> dmic_sample: RMS: 0.015746
[00:00:02.330,780] <inf> dmic_sample: RMS: 0.015738
[00:00:02.430,786] <inf> dmic_sample: RMS: 0.015733
[00:00:02.530,822] <inf> dmic_sample: RMS: 0.015731
[00:00:02.630,859] <inf> dmic_sample: RMS: 0.015731
[00:00:02.730,834] <inf> dmic_sample: RMS: 0.015731

I briefly experiemented with the regulator feature - assuming the microphone is not properly powered - is uses pin P1.10 to power the mic, as can be seen here: https://files.seeedstudio.com/wiki/XIAO-BLE/Seeed-Studio-XIAO-nRF52840-Sense-v1.1.pdf. However, adding an alias and explicitly enablig the regulator did not make any difference.

    aliases {
        mic-reg = &{/msm261d3526hicpm-c-en};
    };

and the code

	const struct device *const dmic_dev = DEVICE_DT_GET(DT_NODELABEL(dmic_dev));
	static const struct device *mic_reg = DEVICE_DT_GET(DT_ALIAS(mic_reg));

	int ret;

	LOG_INF("DMIC sample");

	if (!device_is_ready(dmic_dev)) {
		LOG_ERR("%s is not ready", dmic_dev->name);
		return -ENODEV;
	}

    regulator_enable(mic_reg);
	k_sleep(K_MSEC(50));   /* REQUIRED for this mic */

So I wonder whether some of you nRF gurus have tried using the built-in microphone with this board.
Could be a hardware problem? My next attempt is probably an external microphone, which might be a little bit over my head, to be honest.

Thank you in advance,

Jaroslav

Parents
  • Hi,

    Thanks for the detailed description and logs.

    The fact that you see changing RMS values only briefly after reset and then a constant value suggests that the PDM capture starts correctly but then stops delivering new samples. On the XIAO BLE Sense this could be related to the Devicetree configuration for the on-board microphone.

    You mentioned that you configured the overlay as suggested in the Seeed wiki. To help us verify that everything matches the expected setup for this board, could you please share the overlay file? Once we can review the overlay, we can check that the microphone power regulator and the PDM/DMIC node are configured as intended and not being overridden.

    Best Regards,
    Syed Maysum

  • Hi Syed,

    thank you for your answer. Attaching the overlay file:

    / {
    
        msm261d3526hicpm-c-en {
            regulator-boot-on;
        };
    
        aliases {
            mic-reg = &{/msm261d3526hicpm-c-en};
        };
    };
    
    dmic_dev: &pdm0 {
        status = "okay";
    };
        

    I also tried using right channel instead of the left one and printing out raw data captured by the microphone.

    The setup:

    #define READ_TIMEOUT     SYS_FOREVER_MS 
    #define PCM_WIDTH        16
    #define CHANNELS         1
    #define SAMPLE_RATE      16000
    #define BLOCK_MS         5
    #define BLOCK_COUNT      4
    
    #define SAMPLES_PER_BLOCK (SAMPLE_RATE * BLOCK_MS / 1000)
    #define BLOCK_SIZE_BYTES  (SAMPLES_PER_BLOCK * CHANNELS * sizeof(int16_t))
    
    K_MEM_SLAB_DEFINE_STATIC(mem_slab, BLOCK_SIZE_BYTES, BLOCK_COUNT, 4);
    
    ...
    
    	struct pcm_stream_cfg stream = {
    		.pcm_width = PCM_WIDTH,
    		.pcm_rate   = SAMPLE_RATE,
    		.block_size = BLOCK_SIZE_BYTES,
    		.mem_slab  = &mem_slab,
    	};
    	struct dmic_cfg cfg = {
    		.io = {
    			/* These fields can be used to limit the PDM clock
    			 * configurations that the driver is allowed to use
    			 * to those supported by the microphone.
    			 */
    			.min_pdm_clk_freq = 1000000,
    			.max_pdm_clk_freq = 3500000,
    			.min_pdm_clk_dc   = 40,
    			.max_pdm_clk_dc   = 60,
    		},
    		.streams = &stream,
    		.channel = {
    			.req_num_streams = 1,
    			.req_num_chan = 1,
    			.req_chan_map_lo = dmic_build_channel_map(0, 0, PDM_CHAN_RIGHT),
    			.req_chan_map_hi = 0,
    		},
    	};
    

    And use:

    	while (true){
    		for (int i = 0; i < block_count; ++i) {
    			void *buffer;
    			uint32_t size;
    			int ret;
    
    			ret = dmic_read(dmic_dev, 0, &buffer, &size, READ_TIMEOUT);
    			if (ret < 0) {
    				LOG_ERR("%d - read failed: %d", i, ret);
    				return ret;
    			}
    
    			int16_t *s = buffer;
    			LOG_INF("RAW: %d %d %d %d %d %d %d %d %d %d", s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);

    Gives me the following output:

    [00:04:30.396,545] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 0 7 7 7
    [00:04:30.397,308] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.401,550] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 0 0 7 7
    [00:04:30.402,160] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.406,555] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 0 0 7 7
    [00:04:30.407,165] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.411,560] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 0 0 7 7
    [00:04:30.411,956] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.416,564] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 7 7 7 7
    [00:04:30.416,931] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.421,569] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 7 7 7 7
    [00:04:30.421,936] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.426,574] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 7 7 7 7
    [00:04:30.426,940] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.431,549] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 0 7 7 7
    [00:04:30.432,312] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.436,553] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 0 0 7 7
    [00:04:30.437,133] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.441,558] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 0 0 7 7
    [00:04:30.442,169] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.446,563] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 0 0 7 7
    [00:04:30.446,929] <inf> dmic_sample: RMS: 0.069493
    [00:04:30.451,568] <inf> dmic_sample: RAW: 16208 8192 160 0 9216 244 7 7 7 7
    

    Unfortunately, this version does not reflect the sound either. The microphone sort of works, but keeps returning the same data... does not even look like a noise or something... weird.

    Thank you for your help,

    Jaroslav

  • Hi Syed,

    my aologies, the board I am using is actually not the "sense" version, and the microphone is not assembled. I need to go get the proper board, I am sure the code will start magically working after that. 

    i am so sorry, this is so embarrasing :-D

    Jaroslav

  • Hi Jaroslav,

    That’s fine. I hope it starts to work otherwise, please feel free to reach out to us again. Thanks.

    Best Regards,
    Syed Maysum

Reply Children
No Data
Related