1.. zephyr:code-sample:: x-nucleo-iks02a1-mic 2 :name: X-NUCLEO-IKS02A1 shield - MEMS microphone 3 :relevant-api: audio_dmic_interface 4 5 Acquire audio using the digital MEMS microphone on X-NUCLEO-IKS02A1 shield. 6 7Overview 8******** 9This sample enables the digital MEMS microphone on X-NUCLEO-IKS02A1 10shields 11 12This sample provides an example of how to acquire audio through 13the digital MEMS microphone on X-NUCLEO-IKS02A1 shield. 14The microphone generates a PDM stream which is acquired through I2S. 15The PDM stream is then converted to PCM using the OpenPDM2PCM library 16available in zephyrproject/modules/hal/st/audio/microphone. 17 18Requirements 19************ 20 21This sample communicates over I2C with the X-NUCLEO-IKS02A1 shield 22stacked on a board with an Arduino connector. 23 24.. note:: 25 26 Please note that, in order to make the shield working on top of this board, 27 it is needed to have SB24 and SB29 solder bridges properly closed. In this way 28 the PDM microphone clock and data lines get connected to SPI clock and MOSI. 29 Similar consideration may apply to other boards as well. 30 31References 32********** 33 34- X-NUCLEO-IKS02A1: https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html 35 36Building and Running 37******************** 38 39This sample runs with X-NUCLEO-IKS02A1 stacked on any board with a matching 40Arduino connector. For this example, we use a :ref:`nucleo_f411re_board` board. 41To build the sample you can use following command: 42 43.. zephyr-app-commands:: 44 :zephyr-app: samples/shields/x_nucleo_iks02a1/microphone/ 45 :board: nucleo_f411re 46 :goals: build 47 :compact: 48 49.. note:: 50 51 In case a different board is used, one of the things that must be verified before 52 building the sample is the I2S output clock frequency configuration. For example, 53 for nucleo_f411re board, we have the following file that configures the I2SPLL and 54 have a dependency on HSE/HSI: 55 :zephyr_file:`boards/shields/x_nucleo_iks02a1/boards/nucleo_f411re.defconfig` 56 57 The user is invited to to verify which osci is configured on the used host board 58 defconfig file and calculate the final I2SClk frequency, e.g. 59 :zephyr_file:`boards/arm/nucleo_f411re/nucleo_f411re.dts` 60 61 62Sample Output 63============= 64 65The example acquires one second of audio and prints out the PCM stream on COM port. 66The acquisition starts immediately after the reset button is pressed. 67 68The characteristics of the PCM audio are hardcoded in the example: 69 70- 16KHz sample rate 71- 16 bits per sample 72- 1 channel (mono) 73 74One second of acquisition at a 1 channel 16KHz sampling rate yields 16,000 16-bit samples. 75The microphone PDM requested clock should lead the MP34DT05 driver to select an 76oversampling/decimation factor to result in approximately a 2MHz bit clock. 77 78See PCM and PDM configuration in file :zephyr_file:`samples/shields/x_nucleo_iks02a1/microphone/src/main.c`. 79 80.. note:: It is possible to change the AUDIO_FREQ to 32000 acquiring only 500 ms. 81 82At the end of the acquisition the PCM data will be printed on the terminal 83emulator in either binary or ASCII format. The output is controlled by the 84:c:macro:`PCM_OUTPUT_IN_ASCII` macro, off by default, in 85:zephyr_file:`samples/shields/x_nucleo_iks02a1/microphone/src/main.c`. 86 87Binary PCM Output 88----------------- 89 90The Nucleo F411RE board presents itself to the host 91as a USB CDC class, and will use ``/dev/ttyACM0`` 92device for communication. The ``/dev/ttyACM0`` port 93must be configured in raw mode to avoid having 94special characters (such as :kbd:`CTRL-Z` or :kbd:`CTRL-D`) 95processed and 'cooked out'. 96 97.. code-block:: console 98 99 stty -F /dev/ttyACM0 115200 raw 100 cat /dev/ttyACM0 > /tmp/sound.raw 101 dos2unix -f /tmp/sound.raw 102 103.. note:: 104 105 The dos2unix command is used to recover the situation in which the character 0x0a is 106 interpreted as NL and an 0x0d (CR) is added. If you don't remove it the audio stream would 107 get corrupted. 108 109.. warning:: 110 111 The /tmp/sound.raw file final size should result exactly of 32000 byte, but sometimes may 112 happen that 1 or 2 spurious 0x00 bytes are put at the beginning. In this case the user 113 may get rid of them using the following linux command (change ``skip`` value according 114 to number of spurious bytes to be removed): 115 116 dd if=sound.raw of=sound_clean.raw bs=1 skip=1 117 118 119ASCII PCM Output 120---------------- 121 122It is also possible to recompile and to have PCM output in ASCII, which needs 123to be converted to binary later on. The output format is the following: 124 125.. code-block:: console 126 127 -- start 128 0xfbe0, 129 0xfbf0, 130 0xfc0c, 131 0xfc24, 132 0xfc3c, 133 0xfc4c, 134 0xfc68, 135 0xfc48, 136 137 [...] 138 139 0xfb98, 140 0xfb98, 141 0xfbb8, 142 0xfbac, 143 0xfbc4, 144 0xfbe8, 145 0xfbf4, 146 -- end 147 148Play PCM Audio 149-------------- 150 151Now that we have a binary PCM file (say sound.raw), you can use, 152for example, the audacity open source editor/player to load and play it. 153 154Use the 'Import->Raw Data' menu to load the sound.raw file as 155signed 16 bit PCM, Little Endian, mono format @16KHz: 156 157.. image:: img/audio_import.png 158 :width: 274px 159 :height: 307px 160 :align: center 161 :alt: audio_import 162 163After the file is imported you can analyze and play the 1sec audio file: 164 165.. image:: img/audio_file.png 166 :width: 1627px 167 :height: 505px 168 :align: center 169 :alt: audio_file 170