README.rst
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.overlay`
56
57 The user is invited 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/st/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