IoT向け小型センサ･ノード開発キット「STWIN.box 」を使ってセンサデータ収集③ python scriptを試す

前回に続いて、IoT向け小型センサ･ノード開発キット<a href=https://www.st.com/ja/evaluation-tools/steval-stwinbx1.html>「STWIN.box」（STEVAL-STWINBX1）</a>とセンサ･データ収集用ファームウェア<a href=https://www.st.com/en/embedded-software/fp-sns-datalog1.html>「FP-SNS-DATALOG2」</a>を使用したpython scriptについて解説していきます。
今回は、以下の３つの操作を試してみます。

- センサデータを、AIツール側でインポートできるように成型する
- センサデータを、センサ評価専用ツール側でインポートできるように成型する
- マイクデータを、一般オーディオファイル（wav）に変換する


前回記事はこちら（Python script ~ その１）:
<a href=https://qiita.com/ykawano/items/fe09b2977ee42768246d>IoT向け小型センサ･ノード開発キット「STWIN.box 」を使ってセンサデータ収集② python scriptを試す</a>

セットアップ方法はこちら:
<a href=https://qiita.com/ykawano/items/ae56503f5ba890776c01>IoT向け小型センサ･ノード開発キット「STWIN.box 」を使ってセンサ･データ収集①　セットアップ & GUI操作</a>


<table>
<caption>Python Script</caption>
<thead>
    <tr>
        <th>Script</th><th>内容</th><th>Note</th>
    </tr>
</thead>

<tr>
    <td>hsdatalog_plot.py</td>
    <td>データプロット表示</td>
    <td><a href=https://qiita.com/ykawano/items/fe09b2977ee42768246d>記事②</a>で紹介</td>
</tr>

<tr>
    <td>hsdatalog_cli.py</td>
    <td>コマンド操作でのデータロギング</td>
    <td><a href=https://qiita.com/ykawano/items/fe09b2977ee42768246d>記事②</a>で紹介</td>
</tr>

<tr>
    <td>hsdatalog_data_export.py</td>
    <td>.datデータをCSVデータに変換</td>
    <td><a href=https://qiita.com/ykawano/items/fe09b2977ee42768246d>記事②</a>で紹介</td>
</tr>

<tr>
    <td>hsdatalog_dataframes.py</td>
    <td>pandas用データフレームに変換</td>
    <td><a href=https://qiita.com/ykawano/items/fe09b2977ee42768246d>記事②</a>で紹介</td>
</tr>

<tr>
    <td>hsdatalog_to_nanoedge.py</td>
    <td>NanoEdge AIツールへインポート用</td>
    <td>本記事で紹介</td>
</tr>

<tr>
    <td>hsdatalog_to_unico.py</td>
    <td>Unico-GUI / MEMS Studioツールへインポート用</td>
    <td>本記事で紹介</td>
</tr>

<tr>
    <td>hsdatalog_to_wav.py</td>
    <td>マイクデータをwavファイルへ変換</td>
    <td>本記事で紹介</td>
</tr>

<tr>
    <td>hsdatalog_gui.py</td>
    <td>GUI起動。リアルタイムプロット、データロギングをGUIで操作可能。</td>
    <td><a href=https://qiita.com/ykawano/items/ae56503f5ba890776c01>記事①</a>で紹介</td>
</tr>

</table>

参考資料: ユーザマニュアル<a href=https://www.st.com/content/ccc/resource/technical/document/user_manual/group2/5c/2c/49/42/31/90/43/b4/DM00927176/files/DM00927176.pdf/jcr:content/translations/en.DM00927176.pdf>UM3106</a>

## 1. ~ 4. （前回記事で紹介）
以下scriptについては<a href=https://qiita.com/ykawano/items/fe09b2977ee42768246d>前回記事</a>を参照ください。

<dl>
<dt>グラフプロット表示</dt>
<dd>hsdatalog_plot.py</dd>
<dt>コマンド操作ツール</dt>
<dd>hsdatalog_cli.py</dd>
<dt>データ変換</dt>
<dd>hsdatalog_data_export.py</dd>
<dt>データフレーム変換</dt>
<dd>hsdatalog_dataframes.py</dd>
</dl>

## 5. hsdatalog_to_nanoedge.py


<a href=https://www.st.com/ja/development-tools/nanoedgeaistudio.html>NanoEdgeAI studio</a>（STM32マイコン用の、機械学習用ライブラリ生成ツール）で、取得したデータを機械学習用データとしてインポートするため、データを並べ替えます（縦列 → 横列変換）。

![500_nanoedgeai_dataimport.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/3fa2795e-8833-ea8b-22bc-88b1d0e1d415.png)

コマンド: **python hsdatalog_to_nanoedge.py データフォルダ名 -sl xxx [OPTIONS]**

実行例: [20240228_18_55_32]フォルダ内のii2sdlpc.datを1024個のデータ組で変換。
```(base) D:\...\Utilities\HSDPython_SDK\examples>python hsdatalog_to_nanoedge.py 20240228_18_55_32 -s iis2dlpc_acc -sl 1024```

<details><summary>hsdatalog_to_nanoedge.pyのhelp</summary>

```hsdatalog_to_nanoedge.py (help)
(base) D:\_MySTM32Cube3\STM32CubeFP_DATALOG2_V2.3.0\Utilities\HSDPython_SDK\examples>python hsdatalog_to_nanoedge.py -h
Usage: hsdatalog_to_nanoedge.py [OPTIONS] ACQ_FOLDER

Options:
  -o, --output_folder TEXT        Output folder (this will be created if it
                                  doesn't exist)
  -s, --sensor_name TEXT          Sensor Name - use "all" to convert all
                                  active sensors data, otherwise select a
                                  specific sensor by name
  -sl, --signal_length INTEGER    The length of each segment when performing
                                  segmentation  [required]
  -si, --signal_increment INTEGER
                                  Parameter to control the overlap,
                                  signal_increment = None, is equal to no
                                  overlap, signal_increment = frameLength/2 is
                                  fifty percent overlap
  -st, --start_time INTEGER       Start Time - Data conversion will start from
                                  this time (seconds)
  -et, --end_time INTEGER         End Time - Data conversion will end up in
                                  this time (seconds)
  -r, --raw_data                  Uses Raw data (not multiplied by
                                  sensitivity)
  -t, --target_value FLOAT        Adds target value (mandatory for NEAI
                                  extrapolation datasets)
  -cdm, --custom_device_model <INTEGER INTEGER TEXT>...
                                  Upload a custom Device Template Model (DTDL)
  -v, --version                   hsdatalog_to_nanoedge Converter tool version
                                  number
  -d, --debug                     [DEBUG] Check for corrupted data and
                                  timestamps
  -h, --help                      Show this message and exit.

-> Script execution examples:
   python hsdatalog_to_nanoedge.py Acquisition_Folder_Path -s iis3dwb_acc -sl 1000 -si 500
   python hsdatalog_to_nanoedge.py Acquisition_Folder_Path -o Output_Folder_Path -s all -sl 32 -si 64 -r
```
</details>

-slスイッチで指定したデータ個数分を1セットとして横1行に配列し、以降セットごとに改行して順番に配置されます（縦並び → 横並び変換）。また、X,Y,Zのような3軸データを持つセンサの場合、X,Y,Zの順番で横に配列していきますので、横のデータ並び数（列数）は指定した数の3倍になります。
ここで指定する数値はNanoEdgeAIが判定を行う上での1バッファ･サイズになります。最適化のため、1セットのデータ数は$2^x$個である必要があります。（例: 256, 1024など。推奨範囲: 16 ~ 4096）

データ変換の様子:

![502_csv_origin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/27fb6090-5ede-46fb-8016-766841e9580c.png)


![504_arrow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/abc61d43-d3ee-f518-4fd3-9d17d5fa11c9.png)


![506_dataexport.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/3c4f6982-212f-49ac-a3d9-bb8815320ae4.png)



参考: 
<a href=https://wiki.st.com/stm32mcu/wiki/Category:NanoEdgeAI>wiki by ST > STM32MCU > NanoEdgeAI</a>

<a href=https://stm32ai.st.com/ja/nanoedge-ai/>NanoEdgeAI特設ページ</a>


## 6. hsdatalog_to_unico.py

#### MEMSセンサ用評価ツールでデータ解析

MEMSセンサ用評価ツール（ **Unico-GUI** や **MEMS-Studio** ）で、取得したデータをインポートするため、デーを成型します。
機能的にはhsdatalog_data_export.pyとほぼ同じで、csvフォーマットなどへデータ変換します。変換後のデータを見てみると両者に大きな違いはなく、こちらは時間データ列が削除されるようになっています。
なお、使っていると自然に気づきますが、MEMS-Studioの場合、この時間データ列が含まれていてもインポートできますので、hsdatalog_data_export.pyで変換したファイルをそのまま使っても大丈夫です。

+ <a href=https://www.st.com/ja/development-tools/unico-gui.html>Unico-GUI</a>:
+ <a href=https://www.st.com/ja/development-tools/mems-studio.html>MEMS-Studio</a>:

両ツールとも、STのすべてのMEMSセンサを対象とした、開発者向けGUIツールです。レジスタ設定およびデータ取得、データグラフ表示などが行えます。専用の評価用マザーボードおよび各MEMSセンサ単体のボードが必要です。MEMS-StudioはUnico-GUIの後継版で、新規に評価スタートする場合MEMS-Studioを推奨します。
（Unico-GUIはSTEVAL-MKI109V3以前のボードのみ対応で、新しいボードであるSTEVAL-MKI109Dには対応していません。またSTEVAL-MKI109V3は2025年時点で販売終了しています）

<table>
<caption>MEMSセンサ評価キット･ツール</caption>
<thead>
    <tr>
        <th>ソフトウェア･ツール</th><th>対応ボード</th><th>Note</th>
    </tr>
</thead>

<tr>
    <td><a href=https://www.st.com/ja/development-tools/unico-gui.html>Unico-GUI</a></td>
    <td><a href=https://www.st.com/ja/evaluation-tools/steval-mki109v3.html>STEVAL-MKI109V3</a></td>
    <td>MKI109V3は販売終了。<BR> 新規で評価スタートする場合、<BR>MEMS-Studioを推奨。</td>
</tr>
<tr>
    <td><a href=https://www.st.com/ja/development-tools/mems-studio.html>MEMS-Studio</a></td>
    <td><a href=https://www.st.com/ja/evaluation-tools/steval-mki109v3.html>STEVAL-MKI109V3</a> <BR> <a href=https://www.st.com/ja/evaluation-tools/steval-mki109d.html>STEVAL-MKI109D</a><BR>SensorTile.box.PROやSTWIN.box等で、AlgoBuilder（コード記述なしのアルゴリズム設計）による簡易FW動作も可能</td>
    <td>MKI109V3は販売終了。</td>
</tr>

</table>


実行例: [20230629_18_12_11]フォルダを指定。
```(base) D:\...\Utilities\HSDPython_SDK\examples>python hsdatalog_to_unico.py 20230629_18_12_11```



<details><summary>hsdatalog_to_unico.pyのhelp</summary>

```hsdatalog_to_unico.py (help)
(base) D:\_MySTM32Cube3\STM32CubeFP_DATALOG2_V2.3.0\Utilities\HSDPython_SDK\examples>python hsdatalog_to_unico.py -h
Usage: hsdatalog_to_unico.py [OPTIONS] ACQ_FOLDER

Options:
  -o, --output_folder TEXT        Output folder (this will be created if it
                                  doesn't exist)
  -s, --sensor_name TEXT          Sensor Name - use "all" to extract all
                                  active sensors data, otherwise select a
                                  specific sensor by name
  -st, --start_time INTEGER       Start Time - Data conversion will start from
                                  this time (seconds)
  -et, --end_time INTEGER         End Time - Data conversion will end up in
                                  this time (seconds)
  -t, --use_datalog_tags          Enable this flag to include information
                                  about annotations taken during acquisition
                                  (if any) in the exported data
  -f, --out_format [TXT|CSV|TSV]  Select exported data format
  -wu, --with_untagged            [NOTE: Valid only with -ag split_per_tags is
                                  selected] Select to export also untagged
                                  data sections in output files
  -wt, --with_timestamps          Enable this option to add timestamps column
                                  in the exported output files
  -r, --raw_data                  Uses Raw data (not multiplied by
                                  sensitivity)
  -cdm, --custom_device_model <INTEGER INTEGER TEXT>...
                                  Upload a custom Device Template Model (DTDL)
  -ag, --aggregation [single_file|split_per_tags]
                                  Data aggregation strategy, exported data
                                  format remains selectable by using -f
                                  parameter (default value: CSV)
  -cl, --columns_labels [default|mlc_tool]
                                  Select the naming convention to be used when
                                  creating column names in exported files
  -cs, --chunk_size INTEGER       Specify the size (number of samples) of each
                                  data chunk to be processed
  -v, --version                   HSDatalogToUnico Converter tool version
                                  number
  -d, --debug                     [DEBUG] Check for corrupted data and
                                  timestamps
  -h, --help                      Show this message and exit.

-> Script execution examples:
   python hsdatalog_to_unico.py Acquisition_Folder_Path -s all
   python hsdatalog_to_unico.py Acquisition_Folder_Path -o Output_Folder_Path -f CSV -s all
   python hsdatalog_to_unico.py Acquisition_Folder_Path -s SENSOR_NAME
   python hsdatalog_to_unico.py Acquisition_Folder_Path -st 3 -et 6 -wt -s SENSOR_NAME
   python hsdatalog_to_unico.py Acquisition_Folder_Path -t -s all
   python hsdatalog_to_unico.py Acquisition_Folder_Path -cdm 255 255 custom_model.json -s SENSOR_NAME
   python hsdatalog_to_unico.py Acquisition_Folder_Path -cs 1000 -s SENSOR_NAME
   python hsdatalog_to_unico.py Acquisition_Folder_Path -ag single_file -f CSV -s all
   python hsdatalog_to_unico.py Acquisition_Folder_Path -ag single_file -f TXT -s all
   python hsdatalog_to_unico.py Acquisition_Folder_Path -r -f CSV -s SENSOR_NAME
   python hsdatalog_to_unico.py Acquisition_Folder_Path -ag split_per_tags -wu -s all
   python hsdatalog_to_unico.py Acquisition_Folder_Path -cl mlc_tool -s all
   python hsdatalog_to_unico.py Acquisition_Folder_Path -ag split_per_tags -wu -cl mlc_tool -s all
   python hsdatalog_to_unico.py Acquisition_Folder_Path -d -s SENSOR_NAME
```

</details>

#### MEMS-Studioでデータ･インポート

FP-SNS-DATALOG2で取得した加速度センサ（IIS2DLPC）のデータをhsdatalog_to_unico.pyで変換後、MEMS-Studioでインポートしてみました。データ･インポートは解析ページのところで実行できます。

![600_memsstudio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/fde85092-b608-4f3b-bd29-c830c092df86.png)

左側の **Frequency Domain** をクリックするとFFT解析用ページが開きます。最初にODR値を入力してください。
デフォルトでは全区間対象のFFT結果が下のグラフに表示されますが、マウスで範囲を指定するとその区間のみのデータについてFFT表示できます。

![602_memsstudio_fft.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/743a204d-7c10-43fc-bbba-80b48a867402.png)


窓関数やFFT lengthなどは右側の設定項目から選択可能です。

![606_FFT_config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/47b1a525-467f-4fc8-9b4b-0bd6995e89f6.png)



現時点のFP-SNS-DATALOG2のGUIツールでは、過去に取得したファイルをloadして解析することなどはできないので、このようなツールがあると重宝します。


## 7. hsdatalog_to_wav.py

マイクデータをwavファイルへ変換します。
その他のscriptと同じように“フォルダ名 + -s all”で実行すると、マイク以外の全センサ･データもwavデータへ変換されてしまうので注意してください。“-s”スイッチでマイクファイルのみ指定した方がよいでしょう。あるいはフォルダだけ指定すれば、実行後にセンサの選択メニューが出てきますのでそこでマイクを指定しても良いです。

実行例: [20250107_16_25_41]フォルダ内imp23absu_mic
```(base) D:\...\Utilities\HSDPython_SDK\examples>python hsdatalog_to_wav 20250107_16_25_41 -s imp23absu_mic```

<details><summary>hsdatalog_to_wav.pyのhelp</summary>

```hsdatalog_to_wav.py (help)
(base) D:\_MySTM32Cube3\STM32CubeFP_DATALOG2_V2.3.0\Utilities\HSDPython_SDK\examples>python hsdatalog_to_wav.py -h
Usage: hsdatalog_to_wav.py [OPTIONS] ACQ_FOLDER

Options:
  -o, --output_folder TEXT        Output folder (this will be created if it
                                  doesn't exist)
  -s, --sensor_name TEXT          Sensor Name - use "all" to convert all
                                  active sensors data, otherwise select a
                                  specific sensor by name
  -st, --start_time INTEGER       Start Time - Data conversion will start from
                                  this time (seconds)
  -et, --end_time INTEGER         End Time - Data conversion will end up in
                                  this time (seconds)
  -spt, --split_per_tags          Enable this option to split the output into
                                  separate files for each tag
  -cdm, --custom_device_model <INTEGER INTEGER TEXT>...
                                  Upload a custom Device Template Model (DTDL)
  -cs, --chunk_size INTEGER       Specify the size (number of samples) of each
                                  data chunk to be processed
  -v, --version                   hsdatalog_to_wav Converter tool version
                                  number
  -h, --help                      Show this message and exit.

-> Script execution examples:
   python hsdatalog_to_wav.py Acquisition_Folder_Path
   python hsdatalog_to_wav.py Acquisition_Folder_Path -o Output_Folder_Path -s SENSOR_NAME -st START_TIME -et END_TIME
   python hsdatalog_to_wav.py Acquisition_Folder_Path -s all -spt
   python hsdatalog_to_wav.py Acquisition_Folder_Path -s SENSOR_NAME -cdm BOARD_ID FW_ID custom_model.json
   python hsdatalog_to_wav.py Acquisition_Folder_Path -s SENSOR_NAME -cs 500000
   python hsdatalog_to_wav.py Acquisition_Folder_Path -s SENSOR_NAME -st 3 -et 6
```
</details>

変換実行後のExportedフォルダ:
→ wavファイルが生成されます。

![700_wavfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/9ab7a245-d9d1-259c-4e0c-0fb45dd6a1f6.png)


変換後のwavファイルは、メディアプレーヤやAudacityなどで再生することができます。

![702_audacity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/454dbb27-ccb2-4996-7741-c70223412eb6.png)


wavファイルをバイナリエディタで確認すると、サンプリング周波数 = 192KHz、サンプルあたりビットサイズ = 16bitであることが確認できます。

![704_binary_riff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/0c00a7a2-bdfe-4c73-9cc8-ce140c476354.png)



補足:
RIFFフォーマットのデータ並びはリトルエンディアンであるため、小さい桁のバイトから順番に格納されます。