IoT向け小型センサ･ノード開発キット「STWIN.box 」を使ってセンサ･データ収集④ 超音波FFT

今回は、超音波帯域（~80KHz）の音声データを取り込み可能なMEMSマイクロフォンを使って、音声FFT表示を実施してみます。

+ 超音波FFT解析のユース･ケース: 予知保全

一般的に、機械装置が故障･不具合に至る過程において、その初期段階で異常音や異常振動が発生するケースは多々あります。異常音の中には超音波帯域を含むものもありますので、この帯域までチェックできると解析の幅が広がります。

![000_conditionMonitor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/6d49d5ee-060c-4e7c-94a8-9d4443cfef3c.png)



FP-SNS-DATALOG2のGUIで描画されるFFTグラフの演算は、STWIN.boxのマイコン（STM32U585AI）側で行います。NanoEdgeAIなども組み込めば、エッジでの高度な判断が可能になります。

STWIN.boxとFP-SNS-DATALOG2を初めて使う場合、まずはこちら記事を参考にお試しください。

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

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

Python scriptによるデータ変換方法はこちら（Python script ~ その2）:
<a href=https://qiita.com/ykawano/items/1d7de1cb5d7e69a5fa23>IoT向け小型センサ･ノード開発キット「STWIN.box 」を使ってセンサデータ収集③ python scriptを試す</a>


:::note info
インフォメーション
本記事で使用しているFP-SNS-DATALOG2 は、**Ver2.3以下が対象**になります。ver3.0以降はPython Script-SDK部分が分離独立されました（“HSDPython_SDK”フォルダ → <a href=https://www.st.com/ja/embedded-software/stdatalog-pysdk.html>STDATALOG-PYSDK</a>）。Script名やフォルダ構成などが若干変わっていますので注意ください。
:::

今回使用したPython Scriptは、以下表内の太字のScriptです。
（FP-SNS-DATALOG2 ~ Ver2.3）
<table>
<caption>Python Script</caption>
<thead>
    <tr>
        <th>Script</th><th>内容</th><th>Note</th>
    </tr>
</thead>

<tr>
    <td><strong>hsdatalog_plot.py</strong></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><strong>hsdatalog_data_export.py</strong></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><a href=https://qiita.com/ykawano/private/1d7de1cb5d7e69a5fa23>記事③</a>で紹介</td>
</tr>

<tr>
    <td>hsdatalog_to_unico.py</td>
    <td>Unico-GUI / MEMS Studioツールへインポート用</td>
    <td><a href=https://qiita.com/ykawano/private/1d7de1cb5d7e69a5fa23>記事③</a>で紹介</td>
</tr>

<tr>
    <td>hsdatalog_to_wav.py</td>
    <td>マイクデータをwavファイルへ変換</td>
    <td><a href=https://qiita.com/ykawano/private/1d7de1cb5d7e69a5fa23>記事③</a>で紹介</td>
</tr>

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

</table>


# 1. ハードウェアの準備

STWIN.box本体と、ファームウェア書き込み用のPC & ST-LINKを用意します。
基本的には記事①で準備したものでOKです。

【用意するもの】
- [STEVAL-STWINBX1](https://www.st.com/ja/evaluation-tools/steval-stwinbx1.html)：STWIN.box
- パソコン（本記事ではWindows PCを使用）
- [ST-LINK/V2](https://www.st.com/ja/development-tools/st-link-v2.html) または [STLINK-V3](https://www.st.com/ja/development-tools/stlink-v3minie.html) + 接続用USBケーブル（Mini / Micro / Type-C）
- キット本体用USB Type-Cケーブル


# 2. ファームウェアの準備
## 2-1. UltrasoundFFTプロジェクト
超音波FFT用ファームウェアも、記事①でダウンロードしたプロジェクトファイルの中に入っています。
Project → STWIN.box用フォルダ下には以下3つのProjectフォルダが用意されていますが、今回は **UltrasoundFFT** を使います。
+ DATALOG2（データロギング用）
+ UltrasoundFFT（超音波FFT用）← 今回使用するフォルダ
+ PDetect（近接検知用）

ファイル名: UltrasoundFFT_Release.bin

![210_FW_UltrasoundFFT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/5d0d112c-931b-442e-ab04-600ec42ec18c.png)




## 2-2. STWIN.boxにファームウェアを書き込む
記事①と同じ手順で書き込みます。ここではSTLINK-V3を使ってドラッグ&ドロップします。これだけでSTWIN.boxへのファームウェア書き込み完了です。

![220_Program_UltrasoundFFT_bin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/adfa8c00-e2f5-484b-81d6-5d80a9da8afb.png)


# 3. GUIの操作

パソコンにSTWIN.boxを接続した状態で進めます。

## 3-1．hsdatalog_gui.pyを実行
記事①と同じGUI用スクリプト（hsdatalog_gui.py）を実行します。STWIN.boxに書き込まれているファームウェアによって自動判別し、超音波FFTモードで起動します。

例:
```(base) D:\...\Utilities\HSDPython_SDK\examples>python hsdatalog_gui.py```

![310_GUI_open.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/3b38654f-af24-44a3-bd45-a7d01fd77571.png)



## 3-2. データロギング
**Start Log** ボタンクリックでログ開始します。超音波FFTと、時間軸データのグラフがリアルタイムで表示されます。もう一度クリックすると終了し、自動でPC内にデータ保存されます。ここでは音声については簡易確認のみで、超音波なしの状態で記録しました。一応、手をパチパチ鳴らしなが録音しています。
デフォルトではStart Logボタン下の**Save Files**がオンになっています。こちらをアンチェックするとデータ保存されません。

![320_GUI_StartLog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/c5ac8394-12f8-40e7-b60a-06a7f2d2f2d4.png)


保存されたデータ

DATALOG2の記事の時と同様に、日付＆時間名のフォルダが自動生成されて、その中に\*\*\*.datファイルが保存されます。
+ fft_dpu.dat: STM32マイコンにより計算された音声FFTデータ
+ imp23absu_mic.dat: マイク音声データ

![322_DATdata.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/88ac4b08-8c29-4392-aeb6-20faab9b5444.png)





## 3-3. データプロット

（こちら情報は参考程度になります。実戦的なデータの確認方法については次回記事⑤で紹介する予定です）

**offline plot settings**をオンにすると、最後に取得したデータについてpythonグラフで表示できます。**plot the last acquisition** ボタンクリックで別ウインドウが開き表示されます。

![330_GUI_plot_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/d1ce20d7-e7c6-468e-a41d-41c154abb595.png)


##### 時間軸データ

![332_GUI_plot_timedomain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/df024d3d-2cdb-5d94-28fc-eef7d35f06dd.png)

##### FFT

![334_GUI_plot_FFT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/78032848-c621-8b55-b83b-03e2a995b93e.png)

表示できたFFTは、色の濃淡で強度を表す声紋分析グラフのようになっていて、あまり一般的ではないようです。
また、このグラフはSTM32マイコンによる演算結果データ（fft_dpu.csv）は使っていません。Matplotlibライブラリの、<a href=https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.specgram.html>specgram</a>を使い、時間軸データのみを渡していますので
グラフ表示はpythonスクリプトからも直接実行できます。

コマンド: python hsdatalog_plot.py データフォルダ名 [OPTIONS]
例:
```(base) D:\...\Utilities\HSDPython_SDK\examples>python hsdatalog_plot.py 20250107_18_43_13 -s all```

<details><summary>hsdatalog_plot.py</summary>

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

Options:
  -s, --sensor_name TEXT          Component name (Sensor or Algorithm) - use
                                  "all" to extract all active Component data,
                                  otherwise select a specific Component by
                                  name
  -st, --start_time INTEGER       Start Time - Data plot will start from this
                                  time (seconds)
  -et, --end_time INTEGER         End Time - Data plot will end up in this
                                  time (seconds)
  -r, --raw_data                  Uses Raw data (not multiplied by
                                  sensitivity)
  -l, --labeled                   Plot data including information about
                                  annotations taken during acquisition (if
                                  any)
  -tl, --tag_labels TEXT          A list of tag labels strings to filter and
                                  include only the corresponding entries in
                                  the converted output
  -p, --subplots                  Multiple subplot for multi-dimensional
                                  sensors
  -fp, --fft_plots                Display frequency plots for inertial sensors
                                  and microphones
  -cdm, --custom_device_model <INTEGER INTEGER TEXT>...
                                  Upload a custom Device Template Model (DTDL)
  -v, --version                   hsdatalog_plot tool version number
  -d, --debug                     [DEBUG] Check for corrupted data and
                                  timestamps
  -h,  --help                     Show this message and exit.
  --help                          Show this message and exit.

-> Script execution examples:
   python hsdatalog_plot.py Acquisition_Folder_Path
   python hsdatalog_plot.py Acquisition_Folder_Path -s Sensor_Name
   python hsdatalog_plot.py Acquisition_Folder_Path -st 3 -et 6
   python hsdatalog_plot.py Acquisition_Folder_Path -r
   python hsdatalog_plot.py Acquisition_Folder_Path -l
   python hsdatalog_plot.py Acquisition_Folder_Path -tl tag1 -tl tag2
   python hsdatalog_plot.py Acquisition_Folder_Path -p
   python hsdatalog_plot.py Acquisition_Folder_Path -fp
   python hsdatalog_plot.py Acquisition_Folder_Path -cdm 1 2 custom_model.json
   python hsdatalog_plot.py Acquisition_Folder_Path -d
```
</details>


## 3-4. データ変換

過去記事でも解説しましたが、保存されたDATファイルは普通には開けないので、変換する必要があります。
変換用スクリプトは前回と同じくhsdatalog_data_export.pyを使います。特に指定しない場合は変換データ用のフォルダが自動作成されて、その中にcsv変換データが保存されます。

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

例:
```(base) D:\...\Utilities\HSDPython_SDK\examples>python hsdatalog_data_export.py 20250107_18_43_13 -s all```

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

```hsdatalog_data_export.py (help)
(base) D:\_MySTM32Cube3\STM32CubeFP_DATALOG2_V1.1.0\Utilities\HSDPython_SDK\examples>python hsdatalog_data_export.py -h
Usage: hsdatalog_data_export.py [OPTIONS] ACQ_FOLDER

Options:
  -o, --output_folder TEXT     Output folder (this will be created if it
                               doesn't exist)
  -f, --file_format [CSV|TSV]  Exported file format
  -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)
  -r, --raw_data               Uses Raw data (not multiplied by sensitivity)
  -l, --labeled                Includes annotations taken during acquisition
                               (if any) in the exported data
  -d, --debug                  [DEBUG] Check for corrupted data and timestamps
  -h, --help                   Show this message and exit.

-> Script execution examples:

-> HSDatalog1:
   python hsdatalog_data_export.py ..\..\STWIN_acquisition_examples\STWIN_00001
   python hsdatalog_data_export.py ..\..\STWIN_acquisition_examples\STWIN_00001 -s all
   python hsdatalog_data_export.py ..\..\STWIN_acquisition_examples\STWIN_00001 -s ISM330DHCX -f TSV -r
   python hsdatalog_data_export.py ..\..\STWIN_acquisition_examples\STWIN_00001 -o ..\..\STWIN_acquisition_examples\EXPORTED_DATA_FOLDER 


-> HSDatalog2:
   python hsdatalog_data_export.py ..\..\STWIN.box_acquisition_examples\20221017_13_04_39 -s all
   python hsdatalog_data_export.py ..\..\STWIN.box_acquisition_examples\20221017_13_04_39 -s ism330dhcx_gyro
   python hsdatalog_data_export.py ..\..\STWIN.box_acquisition_examples\20221017_13_04_39 -s ism330dhcx_gyro -r
   python hsdatalog_data_export.py ..\..\STWIN.box_acquisition_examples\20221017_13_04_39 -f TSV -s ism330dhcx_gyro
   python hsdatalog_data_export.py ..\..\STWIN.box_acquisition_examples\20221017_13_04_39 -f CSV -s ism330dhcx_gyro -l -o .\expDataByTags
```
</details>

![340_data_export.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/b8a86a74-bb96-49e8-963d-cf191abdaed0.png)




12秒程度のログデータでしたが、220万行を超えるデータのためExcelでは開けませんでした。ここでは<a href=https://jupyter.org/>Jupyter Notebook</a> & Pandasで確認しました。時間列とマイクデータ列が確認できます。

imp23absu_mic.csv

![342_data_export_miccsv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/64d00e42-7501-49c6-b849-3377b04d05ac.png)


FFTデータについては256列 X 5千行以上ありました。
1行が1ショットのFFTに相当します。

fft_dpu.csv

![342_data_export_micfftcsv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/02da3716-75e7-4932-914c-cbca9763cb63.png)




### 補足

・GUIツール（hsdatalog_gui.py）ではデータに対する操作内容は限定されますので（プロット表示のみ）、主にPythonスクリプトを使用する必要があります。
・サンプリング周波数（192KHz）は変更不可。本ファームウェアは192KHz固定で設計されているため、コード内を編集するとしても大幅な変更が必要になるのでおすすめはしません。
・窓関数はコード内編集により変更可能。
・FFT length（=256）は変更してもSTWIN.box側は動作しますが、PC側のGUIは256固定で設計されているため、FFTグラフは表示されなくなります。変更可能範囲としては4096以下（256, 512, 1024, 2048, 4096）という制約があります。