1. はじめに
前回の記事では、M5StickS3に内蔵されている加速度センサBMI270を利用して、簡易振動計を製作しました。この装置では、外付けの加速度センサを使用せず、M5StickS3本体だけで振動の測定とFFT解析を行うことができます。測定した加速度のRMS値や周波数スペクトル、主なピーク周波数を液晶画面に表示します。
前回は周波数の表示範囲を0~200 Hzとし、スマートフォンで発生させた110 Hz、150 Hz、195 Hzの3つの音による振動成分を検出しました。今回は、もう少し高い周波数まで測定できないかと考え、BMI270の設定を変更して、500 Hz付近まで測定範囲を広げてみました。
なお、本記事は前回のプログラムを変更する内容です。装置の基本構成やプログラム全体については、前回の記事を参照してください。
2. 測定範囲を広げるには
FFT解析で測定できる周波数の上限は、サンプリング周波数によって制限されます。サンプリング周波数を (f_s) とすると、ナイキスト周波数は次式で表されます。
$$
f_N=\frac{f_s}{2}
$$
前回はBMI270の加速度データ出力レート(ODR)を800 Hzに設定していました。実際のデータ出力間隔から推定したサンプリング周波数は約809.6 Hzであり、ナイキスト周波数は約405 Hzとなります。今回は、BMI270のODRを1600 Hzに変更することにしました。主な設定を次に示します。
| 項目 | 前回 | 今回 |
|---|---|---|
| BMI270のODR設定 | 800 Hz | 1600 Hz |
| FFTに使用するサンプリング周波数 | 809.6 Hz | 1619.2 Hz |
| FFTデータ数 | 1024点 | 1024点 |
| 周波数表示範囲 | 0~200 Hz | 0~500 Hz |
| FFTの周波数間隔 | 約0.791 Hz | 約1.581 Hz |
| データ取得時間 | 約1.26秒 | 約0.63秒 |
ここで注意したいのは、ODRの設定値と実際のサンプリング周波数が必ずしも一致しないことです。この点については、後ほど測定結果とともに説明します。また、ナイキスト周波数は理論上の上限です。実際に測定できる周波数範囲は、センサの内部フィルタや周波数応答にも影響されます。
3. プログラムの変更
今回は前回のプログラムを基本的にそのまま使用し、主に3か所を変更しました。
3.1 BMI270のODRの変更
configureBMI270()関数内で、BMI270の加速度設定レジスタに書き込む値を変更します。
変更前:
// Accelerometer ODR = 800 Hz
if (!writeReg(0x40, 0xAB))
return false;
変更後:
// Accelerometer ODR = 1600 Hz
if (!writeReg(0x40, 0xAC))
return false;
BMI270の加速度設定レジスタ0x40では、下位4ビットがODRの設定に使用されます。0x0Bが800 Hz、0x0Cが1600 Hzに対応します。
3.2 FFTのサンプリング周波数の変更
次に、プログラム冒頭のサンプリング周波数を変更します。
変更前:
constexpr double FS = 809.6;
今回の最終設定:
constexpr double FS = 1619.2;
このFSは、FFT解析で周波数を計算するために使用する値です。FSを書き換えても、BMI270の実際のサンプリング周波数が変わるわけではありません。 BMI270のODRを変更するには、前述のレジスタ設定を変更する必要があります。
なお、今回の1619.2 Hzは、前回800 Hz設定時にFIFOを用いて推定した809.6 Hzを2倍した値です。校正によって保証された値ではなく、使用する機器や条件によって確認が必要です。
3.3 FFTの表示範囲を変更する
周波数スペクトルの表示上限を200 Hzから500 Hzに変更します。
変更前:
constexpr double MAX_DISPLAY_HZ = 200.0;
変更後:
constexpr double MAX_DISPLAY_HZ = 500.0;
液晶画面の周波数目盛りも、0~500 Hzに合わせて変更します。例えば、中央の目盛りを250 Hz、右端を500 Hzとします。
d.print("250");
d.setCursor(x0 + plotW - 32, bottom + 3);
d.print("500Hz");
また、測定開始画面の表示も次のように変更します。
M5.Display.println("Range: 0-500 Hz");
このほか、プログラム中に200 Hzを直接指定している箇所があれば、必要に応じて修正します。FFTのデータ数は1024点のままとしました。
3.4 FIFOによるデータ取得
今回もBMI270のFIFO機能を使用し、Z軸の加速度データを1024点取得しています。ODRを1600 Hzに変更すると、前回より短時間でFIFOにデータが蓄積されます。そのため、FIFOからの読み出しが間に合わない場合には、データの欠落が発生する可能性があります。今回の実験では、シリアルモニタに毎回次のメッセージが表示され、1024点の取得処理が完了しました。
FIFO OK: 1024 samples
ただし、この表示だけでFIFOのオーバーフローやサンプルの欠落が完全に否定できるわけではありません。より厳密に確認する場合は、FIFOの状態監視などを追加する必要があります。
4. 110 Hz、250 Hz、490 Hzの振動測定
測定方法は前回と同様です。スマートフォンのアプリを使用して110 Hz、250 Hz、490 Hzの3つの音を同時に発生させ、スマートフォンの背面に置いたM5StickS3で振動を測定しました。M5StickS3は液晶画面を上向きに置き、画面に垂直なZ軸方向の加速度を測定しています。最初は、BMI270のODRを1600 Hz、FFTに使用するサンプリング周波数も1600 Hzとして測定しました。
4.1 FS = 1600 Hzでの測定結果
8回の測定結果を平均すると、次のようになりました。
| スマートフォンの設定周波数 | 測定周波数(平均) | 相対差 |
|---|---|---|
| 110 Hz | 108.698 Hz | −1.18% |
| 250 Hz | 247.088 Hz | −1.16% |
| 490 Hz | 484.245 Hz | −1.17% |
3つの周波数成分は検出できましたが、いずれも設定周波数より約1.17%低い値となりました。注目したのは、3つの周波数で相対差がほぼ一致していることです。このことから、FFTの計算に使用したサンプリング周波数と、実際のサンプリング周波数に差があるのではないかと考えました。
4.2 サンプリング周波数の変更
FFTで計算される周波数は、プログラムに設定したサンプリング周波数に比例します。仮にスマートフォンの設定周波数を基準とすると、実際のサンプリング周波数は次式から推定できます。
$$
f_{s,\mathrm{estimated}} = f_{s,\mathrm{setting}}\mathrm{Hz} \times
\frac{f_{\mathrm{source}}}{f_{\mathrm{measured}}}
$$
250 Hzの結果から計算すると
$$
1600\times\frac{250}{247.088}
\approx1618.9\ \mathrm{Hz}
$$
となります。
これは、前回800 Hz設定時にFIFOを用いて推定した809.6 Hzの2倍である1619.2 Hzとほぼ一致します。そこで、FFTに使用するサンプリング周波数を次のように変更しました。
constexpr double FS = 1619.2;
なお、ここでの逆算はスマートフォンの出力周波数が設定どおりであることを仮定しています。独立した校正ではありません。
4.3 FS = 1619.2 Hzでの測定結果
スマートフォンのアプリで3つの周波数の音を同時に発生させながら、スマートフォンの裏面の振動を5回測定しました。
| 測定回数 | 110 Hz成分 | 250 Hz成分 | 490 Hz成分 |
|---|---|---|---|
| 1 | 110.004 | 250.050 | 490.073 |
| 2 | 109.999 | 250.050 | 490.067 |
| 3 | 110.008 | 250.051 | 490.064 |
| 4 | 110.001 | 250.051 | 490.056 |
| 5 | 110.006 | 250.050 | 490.048 |
| 平均 | 110.004 | 250.050 | 490.062 |
単位:Hz
いずれの周波数成分も、設定周波数に近い値で検出されました。以下は、シリアルモニタの表示の一例です。
Sampling start
Before FIFO flush: CHIP_ID=0x24
FIFO OK: 1024 samples
RMS : 1.32421 m/s2
Peak : 250.050 Hz
FFT Peaks (strongest first):
1: 250.050 Hz (relative magnitude 100.0%)
2: 110.004 Hz (relative magnitude 36.5%)
3: 490.073 Hz (relative magnitude 29.3%)
4: 470.103 Hz (relative magnitude 9.6%)
5: 360.046 Hz (relative magnitude 8.5%)
FFT complete
今回の条件では、490 Hz付近の成分も5回とも安定して検出できました。
ただし、FFTの基本周波数間隔は約1.58 Hzです。表示された小数点以下の値は、FFTピーク付近の補間計算によるものであり、その桁まで測定精度が保証されているわけではありません。
5. 周波数によって振動の大きさが異なる
3つの周波数を同時に出力した場合、250 Hzのピークが最も大きく、490 Hzのピークは比較的小さくなりました。そこで、各周波数を単独で出力し、加速度RMSを測定しました。
測定結果を次に示します。
| 出力周波数 | 加速度RMS | 250 Hzに対する比率 |
|---|---|---|
| 110 Hz | 0.528 m/s² | 14.1% |
| 250 Hz | 3.735 m/s² | 100% |
| 490 Hz | 1.362 m/s² | 36.5% |
250 Hzでの振動は、110 Hzの約7.1倍、490 Hzの約2.7倍となりました。スマートフォンの音量設定が同じでも、筐体が同じ加速度で振動するわけではありません。
今回の結果から、スマートフォンの筐体が周波数によって異なる大きさで振動している可能性が考えられます。特に250 Hz付近では、スマートフォンの筐体や取付け系の共振などによって振動が大きくなっている可能性があります。ただし、今回の測定結果には、BMI270の周波数応答やM5StickS3の取付け状態の影響も含まれます。そのため、250 Hzで振動が大きく、490 Hzで小さくなる原因を特定することはできません。また、測定結果のRMS値には対象周波数以外の成分やノイズも含まれます。3周波数同時測定時のFFTピークの相対振幅と、そのまま比較できるものではありません。
6. 500 Hzまで正確に測定できるのか
今回の実験では、BMI270のODRを1600 Hzに変更することで、490 Hz付近の振動成分を検出できました。ただし、490 Hzのピーク周波数を検出できたことと、490 Hzの加速度振幅を正確に測定できることは別です。 実際の測定には、次のような要因が影響します。
- BMI270の内部フィルタや周波数応答
- M5StickS3本体の振動特性
- 測定対象への取付け方法
- スマートフォンのスピーカーや筐体の振動特性
- FIFOからのデータ取得状態
また、今回のスマートフォンは校正された振動発生装置ではありません。したがって、今回の結果は、500 Hz付近の周波数成分を簡易的に検出できたことを示すものであり、500 Hzまでの加速度測定精度を検証したものではありません。
7. おわりに
M5StickS3に内蔵されているBMI270のODRを800 Hzから1600 Hzに変更し、簡易振動計の周波数表示範囲を0~500 Hzに拡張しました。今回の実験では、110 Hz、250 Hz、490 Hzの3つの音による振動成分を同時に検出できました。また、FFTに使用するサンプリング周波数を公称値の1600 Hzとした場合には、測定周波数が約1.17%低く表示されましたが、1619.2 Hzに変更すると、設定周波数とほぼ一致する結果が得られました。このことから、FFT解析では、センサのODR設定だけでなく、実際のサンプリング周波数を把握することが重要であるとわかりました。
今回の装置は専用の振動計に代わるものではありませんが、マイコンを使った振動測定やFFT解析の仕組みを学ぶための教材として利用できると考えられます。今後は、さらに高い周波数まで測定できる加速度センサを使用することも検討したいと思います。
参考資料
- M5StickS3製品資料 https://docs.m5stack.com/ja/core/StickS3
- M5StickS3の内蔵加速度センサで簡易振動計を作る https://qiita.com/_Moony/items/c38c4c27a790e036f93f
