zephyr/samples/shields/x_nucleo_iks02a1/microphone
Gerard Marull-Paretas 79e6b0e0f6 includes: prefer <zephyr/kernel.h> over <zephyr/zephyr.h>
As of today <zephyr/zephyr.h> is 100% equivalent to <zephyr/kernel.h>.
This patch proposes to then include <zephyr/kernel.h> instead of
<zephyr/zephyr.h> since it is more clear that you are including the
Kernel APIs and (probably) nothing else. <zephyr/zephyr.h> sounds like a
catch-all header that may be confusing. Most applications need to
include a bunch of other things to compile, e.g. driver headers or
subsystem headers like BT, logging, etc.

The idea of a catch-all header in Zephyr is probably not feasible
anyway. Reason is that Zephyr is not a library, like it could be for
example `libpython`. Zephyr provides many utilities nowadays: a kernel,
drivers, subsystems, etc and things will likely grow. A catch-all header
would be massive, difficult to keep up-to-date. It is also likely that
an application will only build a small subset. Note that subsystem-level
headers may use a catch-all approach to make things easier, though.

NOTE: This patch is **NOT** removing the header, just removing its usage
in-tree. I'd advocate for its deprecation (add a #warning on it), but I
understand many people will have concerns.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-09-05 16:31:47 +02:00
..
img
src includes: prefer <zephyr/kernel.h> over <zephyr/zephyr.h> 2022-09-05 16:31:47 +02:00
CMakeLists.txt cmake: increase minimal required version to 3.20.0 2021-08-20 09:47:34 +02:00
prj.conf audio: remove defconfig/proj setting of audio drivers 2022-08-14 09:05:09 -05:00
README.rst samples/shields/x_nucleo_iks02a1: Review README file for microphone 2021-05-04 08:33:46 -05:00
sample.yaml samples: x_nucleo_iks02a1: fix test identifier 2020-05-07 14:23:45 -04:00

.. _x-nucleo-iks02a1-mic-sample:

X-NUCLEO-IKS02A1 shield: Acquire MEMS microphones data
######################################################

Overview
********
This sample enables the digital MEMS microphone on X-NUCLEO-IKS02A1
shields

This sample provides an example of how to acquire audio through
the digital MEMS microphones on X-NUCLEO-IKS02A1 shield.
The microphone generates a PDM stream which is acquired through I2S.
The PDM stream is then converted to PCM using the OpenPDM2PCM library
available in zephyrproject/modules/hal/st/audio/microphone.

Requirements
************

This sample communicates over I2C with the X-NUCLEO-IKS02A1 shield
stacked on a board with an Arduino connector.

.. note::

   Please note that, in order to make the shield working on top of this board,
   it is needed to have SB24 and SB29 solder bridges properly closed. In this way
   the PDM microphone clock and data lines get connected to SPI clock and MOSI.
   Similar consideration may apply to other boards as well.

References
**********

- X-NUCLEO-IKS02A1: https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html

Building and Running
********************

This sample runs with X-NUCLEO-IKS02A1 stacked on any board with a matching
Arduino connector. For this example, we use a :ref:`nucleo_f411re_board` board.
To build the sample you can use following command:

.. zephyr-app-commands::
   :zephyr-app: samples/shields/x_nucleo_iks02a1/microphone/
   :board: nucleo_f411re
   :goals: build
   :compact:

.. note::

   In case a different board is used, one of the things that must be verified before
   building the sample is the I2S output clock frequency configuration. For example,
   for nucleo_f411re board, we have the following file that configures the I2SPLL and
   have a dependency on HSE/HSI:
   :zephyr_file:`boards/shields/x_nucleo_iks02a1/boards/nucleo_f411re.defconfig`

   The user is invited to to verify which osci is configured on the used host board
   defconfig file and calculate the final I2SClk frequency, e.g.
   :zephyr_file:`boards/arm/nucleo_f411re/nucleo_f411re.dts`


Sample Output
=============

The example acquires one second of audio and prints out the PCM stream on COM port.
The acquisition starts immediately after the reset button is pressed.

The characteristics of the PCM audio are hardcoded in the example:

- 16KHz sample rate
- 16 bits per sample
- 1 channel (mono)

One second of acquisition at a 1 channel 16KHz sampling rate yields 16,000 16-bit samples.
The microphone PDM requested clock should lead the MP34DT05 driver to select an
oversampling/decimation factor to result in approximately a 2MHz bit clock.

See PCM and PDM configuration in file :zephyr_file:`samples/shields/x_nucleo_iks02a1/microphone/src/main.c`.

.. note:: It is possible to change the AUDIO_FREQ to 32000 acquiring only 500 ms.

At the end of the acquisition the PCM data will be printed on the terminal
emulator in either binary or ASCII format. The output is controlled by the
:c:macro:`PCM_OUTPUT_IN_ASCII` macro, off by default, in
:zephyr_file:`samples/shields/x_nucleo_iks02a1/microphone/src/main.c`.

Binary PCM Output
-----------------

The Nucleo F411RE board presents itself to the host
as a USB CDC class, and will use ``/dev/ttyACM0``
device for communication. The ``/dev/ttyACM0`` port
must be configured in raw mode to avoid having
special characters (such as :kbd:`CTRL-Z` or :kbd:`CTRL-D`)
processed and 'cooked out'.

.. code-block:: console

   stty -F /dev/ttyACM0 115200 raw
   cat /dev/ttyACM0 > /tmp/sound.raw
   dos2unix -f /tmp/sound.raw

.. note::

   The dos2unix command is used to recover the situation in which the character 0x0a is
   interpreted as NL and an 0x0d (CR) is added. If you don't remove it the audio stream would
   get corrupted.

.. warning::

   The /tmp/sound.raw file final size should result exactly of 32000 byte, but sometimes may
   happen that 1 or 2 spurious 0x00 bytes are put at the beginning. In this case the user
   may get rid of them using the following linux command (change ``skip`` value according
   to number of spurious bytes to be removed):

   dd if=sound.raw of=sound_clean.raw bs=1 skip=1


ASCII PCM Output
----------------

It is also possible to recompile and to have PCM output in ASCII, which needs
to be converted to binary later on. The output format is the following:

.. code-block:: console

    -- start
    0xfbe0,
    0xfbf0,
    0xfc0c,
    0xfc24,
    0xfc3c,
    0xfc4c,
    0xfc68,
    0xfc48,

    [...]

    0xfb98,
    0xfb98,
    0xfbb8,
    0xfbac,
    0xfbc4,
    0xfbe8,
    0xfbf4,
    -- end

Play PCM Audio
--------------

Now that we have a binary PCM file (say sound.raw), you can use,
for example, the audacity open source editor/player to load and play it.

Use the 'Import->Raw Data' menu to load the sound.raw file as
signed 16 bit PCM, Little Endian, mono format @16KHz:

.. image:: img/audio_import.png
     :width: 274px
     :height: 307px
     :align: center
     :alt: audio_import

After the file is imported you can analyze and play the 1sec audio file:

.. image:: img/audio_file.png
     :width: 1627px
     :height: 505px
     :align: center
     :alt: audio_file