見出し画像

マイクロビットで連続した波形を分析する

今回は、前回の電圧を測るの続編です。
内容は
・握力計での電圧測定例の復習
・一測定分を配列に保存し分析する
・閾値を設定した分析
・連続した波形を分析する
以上の内容についてお送りします。

前回、アナログ出力のある握力計を想定し、握力の最大値を測定し結果を表示するプログラムを考えました。
この握力計は0から100kgの 測定値を 0から3.3ボルトに対応したアナログ出力するものとしました。

それでは前回のプログラムを見て行きましょう。
最初だけブロックの中に シリアル通信一行書き出しでスタートをコンソール出力します。
これは コンソールが開けるように小データボタンを表示させるために使用しています。
次に変数モードを999にします。このモード変数は 測定の状態を 保存する変数です。999は準備状況にあることを設定しています。
次にAボタンが押されると 測定が開始されるように このブロック内を設定しています。
最初に音を鳴らして、変数モードを1とします。これは測定が開始されたことを示します。
そして握力の最大値を 格納する変数maxに仮の最大値ゼロを入れます。
次に ボタンBですが このボタンを押すと測定が中止するように設定しています。このボタンが押されると 音を 発生させ 次に 変数モードを0として 測定を 停止させます。

次に測定 を監視するブロックですが、ずっとブロックの中に 条件判断 ブロックを入れています。
条件判断ブロックは 二つの「もしブロック」で構成しています。
一つは 変数modeが1であるか、つまり測定中であるかを判断するブロックで、もう一つは 測定が 停止されたかどうか判断するブロックです。
測定が開始された、つまりもうmode=1の場合、 関数{sokutei}を呼び出します。
測定停止のとき、つまり「Bボタンを押したとき」mode=0となるので
測定停止および 結果を表示する関数{stop_display}を ここで呼び出しています。


測定用関数{sokutei} の定義について説明します
この関数内は アナログ値を端子P0より読み取った後、数値をマップする関数で キログラムに変換しています。
そして変換された値と 現在の最大値を比較し 大きい方を新しい 最大値として設定しています。
そして 測定した値が格納された変数kgを コンソール出力 しています。

{stop_dispaly}関数はBボタンが押されたとき呼び出されます。
ここでは 変数maxの値を四捨五入し 改めて変数maxに代入します。
そして「 シリアル通信 変数名前と数値を書き出す」で コンソール出力します。また マイクロビットの LEDにも 変数maxの内容を 表示します。
最後に 変数modeを999として測定準備状態にもどします。

それでは一測定分を配列に保存し、分析する方法について考えてみましょう。今までは、データを逐次チェックし最大値を分析していましたが
ここでは一測定分のデータを配列に一旦記録し、測定した後に分析値として平均値と最大値を表示するプログラムを考えてみます。

プログラムの変更点について説明して行きます。
まず最初にAボタンが押されたとき の最後に変数kg_arrayを空の配列にする ブロックを入れます。この変数kg_arrayは 握力波形を保存する 配列として定義します。

次に関数測定の修正を行ないます。
「変数maxを....」0の部分は 削除を行ないます。
今回は、測定した後 最大値を求めるのでこの行はいりません。
追加行としては「 kg_arrayの最後に キログラムを追加する」のブロックを入れます。
これは測定された データを逐次 kg_array配列に格納するものです。

このプログラムでは、配列より最大値・平均値を求めるカスタムブロックを拡張機能より追加します。
このブロックの「ChatGPTを使用しMakeCodeのカスタムブロックを作成する」という動画で説明しています。
このカストンブロックは公開していますので 誰でも自分のプロジェクトに取り込みが使用可能です。
取り込み方法は、メークコードの「拡張機能」をクリックすると左下のような 画面が表示されます。
そこで 画面上部の URL欄に、この画面の 右上の URL(https://rock204.github.io/custom_block/)を書き込んでenterを押してください。すると下側に カスタムブロック と表示された タイルが出ますのでそれをクリックしてください。そうするとカスタムブロックが 自分のプログラムに取り込まれます。

こちらに示すのが 取り込まれたカスタムブロックです。
ここで使用できるブロックは
リストの最小値を計算する。 
リストの最大値を計算する。 
リストの標準偏差を計算する。
リストの平均値を計算する。
の四つのブロックです。
この「リスト」というのが配列に相当します。また「変数」は配列名を選択する部分になります。

{stop_display}関数の変更点について説明します。
今回は波形を取得した後、計算するのでカスタムブロックが使用できます。
最初の二行が kg_arrayに保存された データより 最大値maxと平均値 いいaverageを 取得します。
以降の部分は、求められた最大値と平均値をコンソールとLEDに表示するブロックが 配置されています。
そして最後にmodeを999に設定し測定の準備状態に変更しています。

次に閾値を設定した分析について説明します。
今までのプログラムではAボタンが押されて 次にBボタンが押されるまでデータを配列に取り込んでそれを分析していましたが、山が立ち上がらない部分や波形が平となった部分までデータに含まれているので、平均値を計算したとしても この部分のデータが入ってしまいます。
そこで閾値を設定し、その閾値を超えた場合にデータを取り込むようにすると純粋に山の部分だけを計算することができます。
以降の解説ではこの方法について説明します。

「最初だけ」ブロックの最後に変数ikichiを2にするブロックを追加します。
これにより、この値を上回ったデータより配列に取得します。
[sokutei]関数の中はアナログデータをマップする部分だけを残し他は削除します。またBボタンが押されたときは使用しないので削除します。

「ずっと」ブロック内の変更は、測定中で、かつ測定値(kg)が閾値を超えたときmodeを2とします。
右下の図では閾値以下の状態より閾値を超えたときmodeが2となります。

「ずっと」ブロックの後半は、②の閾値を超えた状態で、まだ閾値を下回っていない状態では測定値をkg_array配列に追加していきます。
これに対し①の閾値を超えた状態より再び閾値を下回った場合は1波形のデータが収集できたので結果の表示をおこなう「stop_display」関数を呼び出します。

「stop_display」関数の変更点は文字列を表示から数を表示までを削除しています。またmodeを1にすることによって再び測定開始
そして 波形を保存する配列 kg_arrayを初期化しています。
またボタンBの中に 変数モードを999とする を入れ測定を停止 機能を追加しています。

次に「連続した波形を分析する」方法について説明して行きます。
この図では ボタンAが押されたとき から ボタンBが押された時まで
連続して 波形を収集します。ボタンBが押されると、この場合4回分の波形が分析され結果を表示するというプログラムとなります。

一回ごとの最大と平均値を格納する 配列max_array、avr_array, 回数をカウントする変数counterを用意します。
変数初期化関数(hensu_shokika)では これらの値を初期化します。

ここではストップディスプレイ関数の変更点について見て行きます。
1行目は counterを一つ増やし、次に ①は波形分の最大値と平均値を計算しています。
②の部分は コンソールに結果を出力しています。
③では一波形が収集されるたびに それらの結果を 配列に格納しています。
そして④では測定を 再開するためモードを一としています。

「ボタンBが押されたとき」の前半部分です。
ここでは 「カウンターを ゼロからcounter-1に変える」 のループにおいて
一回ごとの回、最大値、平均値をコンソールに出力します。

後半部分においては全体の最大値と 平均値を計算しコンソール出力します。
以上でプログラムが完成です。


  • ※今回の「micro:bitで連続した波形を分析」では、前回の「電圧を測る」で作成した握力計の測定プログラムに機能を追加しその解説をおこないました。

  • 追加された分析機能としては

  • 1測定分を配列に保存し分析する。

  • 閾値を設定した分析

  • 連続した波形を分析する。

  • などがありますが最大値や平均値を算出するカスタムブロックを使用することによりプログラミングを簡略化することができました。


この記事が気に入ったらサポートをしてみませんか?